1
0
Fork 0
mirror of https://github.com/alice-lg/birdwatcher.git synced 2025-03-09 00:00:05 +01:00
birdwatcher/endpoints/endpoint.go

112 lines
2.4 KiB
Go
Raw Permalink Normal View History

2016-11-11 14:14:38 +01:00
package endpoints
import (
2016-11-30 15:19:01 +01:00
"fmt"
"log"
"reflect"
2016-11-30 15:19:01 +01:00
"strings"
2017-02-24 11:42:46 +01:00
"compress/gzip"
2016-11-11 14:14:38 +01:00
"encoding/json"
"net/http"
"github.com/alice-lg/birdwatcher/bird"
2016-11-11 14:14:38 +01:00
"github.com/julienschmidt/httprouter"
)
type endpoint func(*http.Request, httprouter.Params, bool) (bird.Parsed, bool)
2016-11-30 15:19:01 +01:00
var Conf ServerConfig
func CheckAccess(req *http.Request) error {
if len(Conf.AllowFrom) == 0 {
return nil // AllowFrom ALL
}
// Extract IP
tokens := strings.Split(req.RemoteAddr, ":")
ip := strings.Join(tokens[:len(tokens)-1], ":")
ip = strings.Replace(ip, "[", "", -1)
ip = strings.Replace(ip, "]", "", -1)
// Check Access
for _, allowed := range Conf.AllowFrom {
if ip == allowed {
return nil
}
}
// Log this request
log.Println("Rejecting access from:", ip)
return fmt.Errorf("%s is not allowed to access this service.", ip)
}
func CheckUseCache(req *http.Request) bool {
qs := req.URL.Query()
if Conf.AllowUncached &&
len(qs["uncached"]) == 1 && qs["uncached"][0] == "true" {
return false
}
return true
}
func Endpoint(wrapped endpoint) httprouter.Handle {
2016-11-11 14:26:07 +01:00
return func(w http.ResponseWriter,
r *http.Request,
ps httprouter.Params) {
2016-11-30 15:19:01 +01:00
// Access Control
if err := CheckAccess(r); err != nil {
http.Error(w, err.Error(), http.StatusForbidden)
return
}
2016-11-11 14:26:07 +01:00
res := make(map[string]interface{})
useCache := CheckUseCache(r)
ret, from_cache := wrapped(r, ps, useCache)
if reflect.DeepEqual(ret, bird.NilParse) {
2016-12-13 11:05:44 +01:00
w.WriteHeader(http.StatusTooManyRequests)
return
}
if reflect.DeepEqual(ret, bird.BirdError) {
w.WriteHeader(http.StatusInternalServerError)
w.Header().Set("Content-Type", "application/json")
js, _ := json.Marshal(ret)
w.Write(js)
return
}
res["api"] = GetApiInfo(&ret, from_cache)
2016-11-11 14:14:38 +01:00
2016-11-11 14:26:07 +01:00
for k, v := range ret {
res[k] = v
}
2016-11-11 14:14:38 +01:00
2016-11-11 14:26:07 +01:00
w.Header().Set("Content-Type", "application/json")
2017-03-13 11:30:53 +01:00
// Check if compression is supported
if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
// Compress response
2017-02-24 11:42:46 +01:00
w.Header().Set("Content-Encoding", "gzip")
gz := gzip.NewWriter(w)
defer gz.Close()
json := json.NewEncoder(gz)
json.Encode(res)
2017-03-13 11:30:53 +01:00
} else {
json := json.NewEncoder(w)
json.Encode(res) // Fall back to uncompressed response
2017-02-24 11:42:46 +01:00
}
2016-11-11 14:26:07 +01:00
}
2016-11-11 14:14:38 +01:00
}
2017-02-15 12:20:55 +01:00
func Version(version string) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte(version))
}
}