2016-01-07 17:27:53 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
2016-01-13 12:22:03 +00:00
|
|
|
"io"
|
2016-01-07 17:27:53 +00:00
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
type DispatchFunction func([]string, []byte) (interface{}, error)
|
|
|
|
|
2016-01-13 00:22:01 +00:00
|
|
|
var apiRoutes = map[string]*(map[string]DispatchFunction){
|
2016-01-07 17:27:53 +00:00
|
|
|
"version": &ApiVersionRouting,
|
2016-01-20 18:56:08 +00:00
|
|
|
"ca": &ApiCARouting,
|
2016-01-25 02:09:22 +00:00
|
|
|
"events": &ApiEventsRouting,
|
2016-01-07 19:47:07 +00:00
|
|
|
"themes": &ApiThemesRouting,
|
2016-01-07 19:08:48 +00:00
|
|
|
"teams": &ApiTeamsRouting,
|
2016-01-07 17:27:53 +00:00
|
|
|
}
|
|
|
|
|
2016-01-13 00:22:01 +00:00
|
|
|
type apiRouting struct{}
|
|
|
|
|
|
|
|
func ApiHandler() http.Handler {
|
|
|
|
return apiRouting{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a apiRouting) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
2016-01-07 17:27:53 +00:00
|
|
|
log.Printf("Handling %s request from %s: %s [%s]\n", r.Method, r.RemoteAddr, r.URL.Path, r.UserAgent())
|
|
|
|
|
|
|
|
// Extract URL arguments
|
2016-01-13 00:22:01 +00:00
|
|
|
var sURL = strings.Split(r.URL.Path, "/")[1:]
|
|
|
|
if len(sURL) > 1 && sURL[len(sURL)-1] == "" {
|
2016-01-07 17:27:53 +00:00
|
|
|
// Remove trailing /
|
|
|
|
sURL = sURL[:len(sURL)-1]
|
|
|
|
}
|
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
|
|
|
|
|
|
var ret interface{}
|
|
|
|
var err error = nil
|
|
|
|
|
|
|
|
// Read the body
|
|
|
|
if r.ContentLength < 0 || r.ContentLength > 6553600 {
|
|
|
|
http.Error(w, fmt.Sprintf("{errmsg:\"Request too large or request size unknown\"}", err), http.StatusRequestEntityTooLarge)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
var body []byte
|
|
|
|
if r.ContentLength > 0 {
|
|
|
|
tmp := make([]byte, 1024)
|
|
|
|
for {
|
|
|
|
n, err := r.Body.Read(tmp)
|
|
|
|
for j := 0; j < n; j++ {
|
|
|
|
body = append(body, tmp[j])
|
|
|
|
}
|
|
|
|
if err != nil || n <= 0 {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Route request
|
2016-01-13 00:22:01 +00:00
|
|
|
if len(sURL) > 0 {
|
|
|
|
if h, ok := apiRoutes[sURL[0]]; ok {
|
2016-01-07 17:27:53 +00:00
|
|
|
if f, ok := (*h)[r.Method]; ok {
|
2016-01-13 00:22:01 +00:00
|
|
|
ret, err = f(sURL[1:], body)
|
2016-01-07 17:27:53 +00:00
|
|
|
} else {
|
2016-01-13 00:22:01 +00:00
|
|
|
err = errors.New(fmt.Sprintf("Invalid action (%s) provided for %s.", r.Method, sURL[0]))
|
2016-01-07 17:27:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
err = errors.New("No action provided.")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Format response
|
|
|
|
resStatus := http.StatusOK
|
|
|
|
if err != nil {
|
|
|
|
ret = map[string]string{"errmsg": err.Error()}
|
|
|
|
resStatus = http.StatusBadRequest
|
2016-01-18 17:25:32 +00:00
|
|
|
log.Println(r.RemoteAddr, resStatus, err.Error())
|
2016-01-07 17:27:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ret == nil {
|
|
|
|
ret = map[string]string{"errmsg": "Page not found"}
|
|
|
|
resStatus = http.StatusNotFound
|
|
|
|
}
|
|
|
|
|
2016-01-13 12:22:03 +00:00
|
|
|
if str, found := ret.(string); found {
|
|
|
|
w.WriteHeader(resStatus)
|
|
|
|
io.WriteString(w, str)
|
2016-01-20 18:54:27 +00:00
|
|
|
} else if bts, found := ret.([]byte); found {
|
|
|
|
w.WriteHeader(resStatus)
|
|
|
|
w.Write(bts)
|
2016-01-13 12:22:03 +00:00
|
|
|
} else if j, err := json.Marshal(ret); err != nil {
|
2016-01-18 17:25:32 +00:00
|
|
|
http.Error(w, fmt.Sprintf("{\"errmsg\":\"%q\"}", err), http.StatusInternalServerError)
|
2016-01-07 17:27:53 +00:00
|
|
|
} else {
|
|
|
|
w.WriteHeader(resStatus)
|
|
|
|
w.Write(j)
|
|
|
|
}
|
|
|
|
}
|