Cleanup logging, give not allowed to GET on gateway functions

This commit is contained in:
Alex Ellis 2017-04-05 22:34:45 +01:00
parent 469fc690da
commit 3aec97441e
3 changed files with 51 additions and 41 deletions

View File

@ -23,7 +23,7 @@ import (
) )
// MakeProxy creates a proxy for HTTP web requests which can be routed to a function. // MakeProxy creates a proxy for HTTP web requests which can be routed to a function.
func MakeProxy(metrics metrics.MetricOptions, wildcard bool, c *client.Client, logger *logrus.Logger) http.HandlerFunc { func MakeProxy(metrics metrics.MetricOptions, wildcard bool, client *client.Client, logger *logrus.Logger) http.HandlerFunc {
proxyClient := http.Client{ proxyClient := http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment, Proxy: http.ProxyFromEnvironment,
@ -39,27 +39,35 @@ func MakeProxy(metrics metrics.MetricOptions, wildcard bool, c *client.Client, l
} }
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
if r.Method == "POST" { if r.Method == "POST" {
logger.Infoln(r.Header) logger.Infoln(r.Header)
header := r.Header["X-Function"]
logger.Infoln(header)
if wildcard == true { xfunctionHeader := r.Header["X-Function"]
if len(xfunctionHeader) > 0 {
logger.Infoln(xfunctionHeader)
}
// getServiceName
var serviceName string
if wildcard {
vars := mux.Vars(r) vars := mux.Vars(r)
name := vars["name"] name := vars["name"]
fmt.Println("invoke by name") serviceName = name
lookupInvoke(w, r, metrics, name, c, logger, &proxyClient) } else if len(xfunctionHeader) > 0 {
defer r.Body.Close() serviceName = xfunctionHeader[0]
}
} else if len(header) > 0 { if len(serviceName) > 0 {
lookupInvoke(w, r, metrics, header[0], c, logger, &proxyClient) lookupInvoke(w, r, metrics, serviceName, client, logger, &proxyClient)
defer r.Body.Close()
} else { } else {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("Provide a named /function URL or an x-function header.")) w.Write([]byte("Provide an x-function header or valid route /function/function_name."))
defer r.Body.Close()
} }
} else {
w.WriteHeader(http.StatusMethodNotAllowed)
} }
} }
} }
@ -82,12 +90,12 @@ func lookupInvoke(w http.ResponseWriter, r *http.Request, metrics metrics.Metric
if err != nil || exists == false { if err != nil || exists == false {
if err != nil { if err != nil {
logger.Fatalln(err) logger.Infof("Could not resolve service: %s error: %s.", name, err)
} }
writeHead(name, metrics, http.StatusInternalServerError, w)
w.Write([]byte("Error resolving service.")) // TODO: Should record the 404/not found error in Prometheus.
defer r.Body.Close() writeHead(name, metrics, http.StatusNotFound, w)
return w.Write([]byte(fmt.Sprintf("Cannot find service: %s.", name)))
} }
if exists { if exists {
@ -106,19 +114,6 @@ func lookupSwarmService(serviceName string, c *client.Client) (bool, error) {
return len(services) > 0, err return len(services) > 0, err
} }
func copyHeaders(destination *http.Header, source *http.Header) {
for k, vv := range *source {
vvClone := make([]string, len(vv))
copy(vvClone, vv)
(*destination)[k] = vvClone
}
}
func randomInt(min, max int) int {
rand.Seed(time.Now().Unix())
return rand.Intn(max-min) + min
}
func invokeService(w http.ResponseWriter, r *http.Request, metrics metrics.MetricOptions, service string, requestBody []byte, logger *logrus.Logger, proxyClient *http.Client) { func invokeService(w http.ResponseWriter, r *http.Request, metrics metrics.MetricOptions, service string, requestBody []byte, logger *logrus.Logger, proxyClient *http.Client) {
stamp := strconv.FormatInt(time.Now().Unix(), 10) stamp := strconv.FormatInt(time.Now().Unix(), 10)
@ -129,6 +124,7 @@ func invokeService(w http.ResponseWriter, r *http.Request, metrics metrics.Metri
metrics.GatewayFunctionsHistogram.WithLabelValues(service).Observe(seconds) metrics.GatewayFunctionsHistogram.WithLabelValues(service).Observe(seconds)
}(time.Now()) }(time.Now())
//TODO: inject setting rather than looking up each time.
var dnsrr bool var dnsrr bool
if os.Getenv("dnsrr") == "true" { if os.Getenv("dnsrr") == "true" {
dnsrr = true dnsrr = true
@ -185,3 +181,16 @@ func invokeService(w http.ResponseWriter, r *http.Request, metrics metrics.Metri
writeHead(service, metrics, http.StatusOK, w) writeHead(service, metrics, http.StatusOK, w)
w.Write(responseBody) w.Write(responseBody)
} }
func copyHeaders(destination *http.Header, source *http.Header) {
for k, vv := range *source {
vvClone := make([]string, len(vv))
copy(vvClone, vv)
(*destination)[k] = vvClone
}
}
func randomInt(min, max int) int {
rand.Seed(time.Now().Unix())
return rand.Intn(max-min) + min
}

View File

@ -10,6 +10,7 @@ import (
faasHandlers "github.com/alexellis/faas/gateway/handlers" faasHandlers "github.com/alexellis/faas/gateway/handlers"
"github.com/alexellis/faas/gateway/metrics" "github.com/alexellis/faas/gateway/metrics"
"github.com/docker/docker/client" "github.com/docker/docker/client"
"github.com/gorilla/mux" "github.com/gorilla/mux"
) )

View File

@ -44,19 +44,19 @@ func fireRequestWithHeaders(url string, method string, reqBody string, headers m
return string(body), res.StatusCode, readErr return string(body), res.StatusCode, readErr
} }
// TODO: Review this - should give StatusMethodNotAllowed, gives 200 OK
func TestGet_Rejected(t *testing.T) { func TestGet_Rejected(t *testing.T) {
// var reqBody string var reqBody string
// _, code, err := fireRequest("http://localhost:8080/function/func_echoit", http.MethodGet, reqBody) _, code, err := fireRequest("http://localhost:8080/function/func_echoit", http.MethodGet, reqBody)
want := http.StatusMethodNotAllowed
if code != want {
t.Logf("Failed got: %d, wanted: %d", code, want)
t.Fail()
}
// if code != http.StatusMethodNotAllowed { if err != nil {
// t.Logf("Failed got: %d", code) t.Log(err)
// } t.Fail()
}
// if err != nil {
// t.Log(err)
// t.Fail()
// }
} }
func TestEchoIt_Post_Route_Handler_ForwardsClientHeaders(t *testing.T) { func TestEchoIt_Post_Route_Handler_ForwardsClientHeaders(t *testing.T) {