2017-04-01 04:19:50 +00:00
|
|
|
package server
|
2017-03-13 16:43:28 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"net/http"
|
2017-03-13 21:46:11 +00:00
|
|
|
"runtime"
|
|
|
|
"strconv"
|
2017-03-13 16:43:28 +00:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/gorilla/mux"
|
2017-03-22 21:43:36 +00:00
|
|
|
|
|
|
|
"git.daplie.com/Daplie/go-rvpn-server/rvpn/envelope"
|
2017-03-13 16:43:28 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2017-03-26 22:33:40 +00:00
|
|
|
endPointPrefix = "/api/com.daplie.tunnel/"
|
2017-03-13 16:43:28 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var connectionTable *Table
|
2017-03-23 23:10:49 +00:00
|
|
|
var serverStatus *Status
|
2017-03-20 00:04:47 +00:00
|
|
|
var serverStatusAPI *Status
|
2017-03-13 16:43:28 +00:00
|
|
|
|
|
|
|
//handleAdminClient -
|
|
|
|
// - expecting an existing oneConnListener with a qualified wss client connected.
|
|
|
|
// - auth will happen again since we were just peeking at the token.
|
|
|
|
func handleAdminClient(ctx context.Context, oneConn *oneConnListener) {
|
2017-03-23 23:10:49 +00:00
|
|
|
serverStatus = ctx.Value(ctxServerStatus).(*Status)
|
2017-03-20 00:04:47 +00:00
|
|
|
|
|
|
|
connectionTable = serverStatus.ConnectionTable
|
|
|
|
serverStatusAPI = serverStatus
|
2017-03-13 16:43:28 +00:00
|
|
|
router := mux.NewRouter().StrictSlash(true)
|
|
|
|
|
2017-03-15 00:26:01 +00:00
|
|
|
router.PathPrefix("/admin/").Handler(http.StripPrefix("/admin/", http.FileServer(http.Dir("html/admin"))))
|
|
|
|
|
2017-03-13 16:43:28 +00:00
|
|
|
router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
loginfo.Println("HandleFunc /")
|
2017-03-23 23:10:49 +00:00
|
|
|
|
|
|
|
serverStatus.AdminStats.IncRequests()
|
|
|
|
|
2017-03-13 16:43:28 +00:00
|
|
|
switch url := r.URL.Path; url {
|
|
|
|
case "/":
|
|
|
|
// check to see if we are using the administrative Host
|
|
|
|
if strings.Contains(r.Host, "rvpn.daplie.invalid") {
|
|
|
|
http.Redirect(w, r, "/admin", 301)
|
2017-03-23 23:10:49 +00:00
|
|
|
serverStatus.AdminStats.IncResponses()
|
|
|
|
|
2017-03-13 16:43:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
http.Error(w, "Not Found", 404)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2017-03-14 01:22:44 +00:00
|
|
|
router.HandleFunc(endPointPrefix+"domains", getDomainsEndpoint).Methods("GET")
|
|
|
|
router.HandleFunc(endPointPrefix+"domain/", getDomainEndpoint).Methods("GET")
|
|
|
|
router.HandleFunc(endPointPrefix+"domain/{domain-name}", getDomainEndpoint).Methods("GET")
|
2017-03-13 21:46:11 +00:00
|
|
|
router.HandleFunc(endPointPrefix+"servers", getServersEndpoint).Methods("GET")
|
|
|
|
router.HandleFunc(endPointPrefix+"server/", getServerEndpoint).Methods("GET")
|
|
|
|
router.HandleFunc(endPointPrefix+"server/{server-id}", getServerEndpoint).Methods("GET")
|
2017-03-20 00:04:47 +00:00
|
|
|
router.HandleFunc(endPointPrefix+"status/", getStatusEndpoint).Methods("GET")
|
2017-03-13 16:43:28 +00:00
|
|
|
|
|
|
|
s := &http.Server{
|
|
|
|
Addr: ":80",
|
|
|
|
Handler: router,
|
|
|
|
}
|
|
|
|
|
|
|
|
err := s.Serve(oneConn)
|
|
|
|
if err != nil {
|
|
|
|
loginfo.Println("Serve error: ", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
select {
|
|
|
|
case <-ctx.Done():
|
|
|
|
loginfo.Println("Cancel signal hit")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-20 00:04:47 +00:00
|
|
|
func getStatusEndpoint(w http.ResponseWriter, r *http.Request) {
|
|
|
|
pc, _, _, _ := runtime.Caller(0)
|
|
|
|
loginfo.Println(runtime.FuncForPC(pc).Name())
|
|
|
|
|
2017-03-23 23:10:49 +00:00
|
|
|
serverStatus.AdminStats.IncRequests()
|
|
|
|
|
2017-03-20 00:04:47 +00:00
|
|
|
statusContainer := NewStatusAPI(serverStatusAPI)
|
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
|
|
|
|
|
|
|
env := envelope.NewEnvelope("domains/GET")
|
|
|
|
env.Result = statusContainer
|
|
|
|
env.GenerateWriter(w)
|
2017-03-23 23:10:49 +00:00
|
|
|
serverStatus.AdminStats.IncResponses()
|
2017-03-20 00:04:47 +00:00
|
|
|
}
|
|
|
|
|
2017-03-14 01:22:44 +00:00
|
|
|
func getDomainsEndpoint(w http.ResponseWriter, r *http.Request) {
|
|
|
|
pc, _, _, _ := runtime.Caller(0)
|
|
|
|
loginfo.Println(runtime.FuncForPC(pc).Name())
|
|
|
|
|
2017-03-23 23:10:49 +00:00
|
|
|
serverStatus.AdminStats.IncRequests()
|
|
|
|
|
2017-03-26 01:33:09 +00:00
|
|
|
domainsContainer := NewDomainsAPI(connectionTable.domains)
|
2017-03-14 01:22:44 +00:00
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
|
|
|
|
|
|
|
env := envelope.NewEnvelope("domains/GET")
|
|
|
|
env.Result = domainsContainer
|
|
|
|
env.GenerateWriter(w)
|
2017-03-23 23:10:49 +00:00
|
|
|
serverStatus.AdminStats.IncResponses()
|
2017-03-14 01:22:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func getDomainEndpoint(w http.ResponseWriter, r *http.Request) {
|
|
|
|
pc, _, _, _ := runtime.Caller(0)
|
|
|
|
loginfo.Println(runtime.FuncForPC(pc).Name())
|
|
|
|
|
2017-03-23 23:10:49 +00:00
|
|
|
serverStatus.AdminStats.IncRequests()
|
|
|
|
|
2017-03-14 01:22:44 +00:00
|
|
|
env := envelope.NewEnvelope("domain/GET")
|
|
|
|
|
|
|
|
params := mux.Vars(r)
|
|
|
|
if id, ok := params["domain-name"]; !ok {
|
|
|
|
env.Error = "domain-name is missing"
|
|
|
|
env.ErrorURI = r.RequestURI
|
|
|
|
env.ErrorDescription = "domain API requires a domain-name"
|
|
|
|
} else {
|
|
|
|
domainName := id
|
2017-03-25 20:01:57 +00:00
|
|
|
if domainLB, ok := connectionTable.domains[domainName]; !ok {
|
2017-03-14 01:22:44 +00:00
|
|
|
env.Error = "domain-name was not found"
|
|
|
|
env.ErrorURI = r.RequestURI
|
|
|
|
env.ErrorDescription = "domain-name not found"
|
|
|
|
} else {
|
2017-03-26 01:33:09 +00:00
|
|
|
var domainAPIContainer []*ServerDomainAPI
|
2017-03-25 20:01:57 +00:00
|
|
|
conns := domainLB.Connections()
|
|
|
|
for pos := range conns {
|
|
|
|
conn := conns[pos]
|
2017-03-26 01:33:09 +00:00
|
|
|
domainAPI := NewServerDomainAPI(conn, conn.DomainTrack[domainName])
|
2017-03-25 20:01:57 +00:00
|
|
|
domainAPIContainer = append(domainAPIContainer, domainAPI)
|
|
|
|
}
|
|
|
|
env.Result = domainAPIContainer
|
2017-03-14 01:22:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
|
|
|
env.GenerateWriter(w)
|
2017-03-23 23:10:49 +00:00
|
|
|
serverStatus.AdminStats.IncResponses()
|
2017-03-14 01:22:44 +00:00
|
|
|
}
|
|
|
|
|
2017-03-13 21:46:11 +00:00
|
|
|
func getServersEndpoint(w http.ResponseWriter, r *http.Request) {
|
|
|
|
pc, _, _, _ := runtime.Caller(0)
|
|
|
|
loginfo.Println(runtime.FuncForPC(pc).Name())
|
|
|
|
|
2017-03-23 23:10:49 +00:00
|
|
|
serverStatus.AdminStats.IncRequests()
|
|
|
|
|
2017-03-13 16:43:28 +00:00
|
|
|
serverContainer := NewServerAPIContainer()
|
|
|
|
|
|
|
|
for c := range connectionTable.Connections() {
|
2017-03-13 21:46:11 +00:00
|
|
|
serverAPI := NewServersAPI(c)
|
2017-03-13 16:43:28 +00:00
|
|
|
serverContainer.Servers = append(serverContainer.Servers, serverAPI)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
|
|
|
|
2017-03-13 21:46:11 +00:00
|
|
|
env := envelope.NewEnvelope("servers/GET")
|
|
|
|
env.Result = serverContainer
|
|
|
|
env.GenerateWriter(w)
|
2017-03-23 23:10:49 +00:00
|
|
|
serverStatus.AdminStats.IncResponses()
|
2017-03-13 21:46:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func getServerEndpoint(w http.ResponseWriter, r *http.Request) {
|
|
|
|
pc, _, _, _ := runtime.Caller(0)
|
|
|
|
loginfo.Println(runtime.FuncForPC(pc).Name())
|
|
|
|
|
2017-03-23 23:10:49 +00:00
|
|
|
serverStatus.AdminStats.IncRequests()
|
|
|
|
|
2017-03-13 21:46:11 +00:00
|
|
|
env := envelope.NewEnvelope("server/GET")
|
|
|
|
|
|
|
|
params := mux.Vars(r)
|
|
|
|
if id, ok := params["server-id"]; !ok {
|
|
|
|
env.Error = "server-id is missing"
|
|
|
|
env.ErrorURI = r.RequestURI
|
|
|
|
env.ErrorDescription = "server API requires a server-id"
|
|
|
|
} else {
|
|
|
|
serverID, err := strconv.Atoi(id)
|
|
|
|
if err != nil {
|
|
|
|
env.Error = "server-id is not an integer"
|
|
|
|
env.ErrorURI = r.RequestURI
|
|
|
|
env.ErrorDescription = "server API requires a server-id"
|
|
|
|
|
|
|
|
} else {
|
|
|
|
conn, err := connectionTable.GetConnection(int64(serverID))
|
|
|
|
if err != nil {
|
|
|
|
env.Error = "server-id was not found"
|
|
|
|
env.ErrorURI = r.RequestURI
|
|
|
|
env.ErrorDescription = "missing server-id, make sure desired service-id is in servers"
|
|
|
|
} else {
|
|
|
|
loginfo.Println("test")
|
|
|
|
serverAPI := NewServerAPI(conn)
|
|
|
|
env.Result = serverAPI
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
|
|
|
env.GenerateWriter(w)
|
2017-03-23 23:10:49 +00:00
|
|
|
serverStatus.AdminStats.IncResponses()
|
2017-03-13 16:43:28 +00:00
|
|
|
}
|