package main import ( "encoding/json" "errors" "fmt" "io/ioutil" "log" "net/http" _ "git.euclide.org/euclide/openvpn-mgt/statik" "github.com/rakyll/statik/fs" ) type jsonInput struct { Action string `json:"action"` Params jsonInputParams `json:"params"` } type jsonInputParams struct { Server string `json:"server"` Session int `json:"session"` } type HttpServer struct { Port string ovpn *OpenVpnMgt } func parseJsonQuery(r *http.Request) (*jsonInput, error) { var in jsonInput body, err := ioutil.ReadAll(r.Body) if err != nil { return nil, err } if err = json.Unmarshal(body, &in); err != nil { return nil, err } return &in, nil } func (h *HttpServer) handler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-type", "application/javascript") fmt.Fprintf(w, "\n") } func (h *HttpServer) ajaxHandler(w http.ResponseWriter, r *http.Request) { var err error var jsonStr []byte w.Header().Set("Content-type", "application/json") // add CORS headers w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin")) w.Header().Set("Access-Control-Allow-Methods", "POST") w.Header().Set("Access-Control-Allow-Credentials", "true") w.Header().Set("Access-Control-Allow-Headers", "content-type, accept, origin, user-agent, Accept-Encoding") // stop here if the method is OPTIONS, to allow CORS to work if r.Method == "OPTIONS" { return } // stop here if the method is OPTIONS, to allow CORS to work if r.Method != "POST" { http.Error(w, "post only", 405) return } req, err := parseJsonQuery(r) if err != nil { log.Println(err) http.Error(w, "Invalid request", 500) return } h.ovpn.Debug(req) switch req.Action { case "get-remotes": jsonStr, err = json.Marshal(h.ovpn) case "set-remote": err = h.ovpn.SetRemote(req.Params.Server, req.Params.Session) jsonStr = []byte("{\"status\": \"ok\"}") case "get-sessions": jsonStr, err = json.Marshal(h.ovpn) case "version": err, version := h.ovpn.Version() if err != nil { break } jsonStr, err = json.Marshal(version) case "stats": case "restart": err = h.ovpn.Restart(req.Params.Session) jsonStr = []byte("{\"status\": \"ok\"}") case "kill": err = h.ovpn.Kill(req.Params.Session) jsonStr = []byte("{\"status\": \"ok\"}") default: err = errors.New("Invalid request") } if err != nil { http.Error(w, fmt.Sprintf("Error : %s", err), 500) return } fmt.Fprintf(w, "%s", jsonStr) return } func NewHTTPServer(port string, s *OpenVpnMgt) { h := &HttpServer{ Port: port, ovpn: s, } statikFS, err := fs.New() if err != nil { log.Fatal(err) } http.HandleFunc("/ajax", h.ajaxHandler) http.Handle("/", http.FileServer(statikFS)) log.Fatal(http.ListenAndServe(port, nil)) }