bbappyuanyuan
8/3/2018 - 8:57 AM

Go net/http

package main

import (
	"flag"
	"fmt"
	"html/template"
	"net/http"
	"net/http/httputil"
	"net/url"
	"path"
	"strconv"
)

var (
	flagInfluxDBServer = flag.String("influxdb-server", "influxdb-dpflow:8086", "Address of InfluxDB server")
	flagPort           = flag.Int("port", 3000, "Port of web server")
	flagWebappFolder   = flag.String("webapp-folder", "/var/dpflow-monitor-server", "Web app folder")
)

func main() {
	flag.Parse()

	proxy := &httputil.ReverseProxy{Director: director}

	http.Handle("/resources/", http.FileServer(http.Dir(*flagWebappFolder)))

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		t, err := template.ParseFiles(path.Join(*flagWebappFolder, "main.html"))
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		t.Execute(w, nil)
	})

	http.HandleFunc("/query", func(w http.ResponseWriter, r *http.Request) {
		if _, ok := r.URL.Query()["sql"]; !ok {
			http.Error(w, "missing parameter 'sql'", http.StatusInternalServerError)
			return
		}
		proxy.ServeHTTP(w, r)
	})
	fmt.Println("Listening port " + strconv.Itoa(*flagPort))
	panic(http.ListenAndServe(":"+strconv.Itoa(*flagPort), nil))
}

func director(r *http.Request) {
	sql, _ := r.URL.Query()["sql"]
	r.URL.Scheme = "http"
	r.URL.Host = *flagInfluxDBServer
	r.URL.Path = "/query"
	r.URL.RawQuery = "db=dpflow&q=" + url.QueryEscape(sql[0])
}
go func() {
	fileHandler := http.StripPrefix(*flagSSDBase, http.FileServer(http.Dir(*flagSSDBase)))
	http.HandleFunc("/volumes/", func(w http.ResponseWriter, r *http.Request) {
		log.Info("Receive HTTP request " + r.URL.Path)
		vid, err := strconv.ParseUint(strings.TrimPrefix(r.URL.Path, "/volumes/"), 10, 64)
		if err != nil {
			http.Error(w, "Unavailable volume", http.StatusInternalServerError)
			return
		}
		volumeTask, exist := manager.LookupTable[vid]
		if !exist {
			log.WithField("volume", vid).Error("Unavailable volume")
			http.Error(w, "Unavailable volume", http.StatusInternalServerError)
			return
		}
		r.URL.Path = volumeTask.Provider.GetPath()
		log.WithField("volume", vid).Info("Upload " + r.URL.Path)
		fileHandler.ServeHTTP(w, r)
	})
	log.Info("Serving HTTP on port 16380")
	log.Error(http.ListenAndServe(":16380", nil))
}()