mirror of
https://github.com/openfaas/faas.git
synced 2025-06-22 06:43:23 +00:00
Make 'URLPathTransformer' interface and implementation to do the function prefix trimming instead of baking it in. Also add a configuration option, 'pass_url_path_to_functions' to control whether the full path is passed to the functions or not.
Signed-off-by: Thomas E Lackey <telackey@bozemanpass.com>
This commit is contained in:
committed by
Alex Ellis
parent
7870b87c38
commit
decf9addb3
@ -29,12 +29,17 @@ type BaseURLResolver interface {
|
||||
Resolve(r *http.Request) string
|
||||
}
|
||||
|
||||
// RequestURLPathTransformer Transform the incoming URL path for upstream requests
|
||||
type URLPathTransformer interface {
|
||||
Transform(r *http.Request) string
|
||||
}
|
||||
|
||||
// MakeForwardingProxyHandler create a handler which forwards HTTP requests
|
||||
func MakeForwardingProxyHandler(proxy *types.HTTPClientReverseProxy, notifiers []HTTPNotifier, baseURLResolver BaseURLResolver) http.HandlerFunc {
|
||||
func MakeForwardingProxyHandler(proxy *types.HTTPClientReverseProxy, notifiers []HTTPNotifier, baseURLResolver BaseURLResolver, urlPathTransformer URLPathTransformer) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
baseURL := baseURLResolver.Resolve(r)
|
||||
|
||||
requestURL := r.URL.Path
|
||||
requestURL := urlPathTransformer.Transform(r)
|
||||
|
||||
start := time.Now()
|
||||
|
||||
@ -51,23 +56,7 @@ func MakeForwardingProxyHandler(proxy *types.HTTPClientReverseProxy, notifiers [
|
||||
}
|
||||
|
||||
func buildUpstreamRequest(r *http.Request, baseURL string, requestURL string) *http.Request {
|
||||
url := baseURL
|
||||
|
||||
if requestURL != "" {
|
||||
// When forwarding to a function, since the `/function/xyz` portion
|
||||
// of a path like `/function/xyz/rest/of/path` is only used or needed
|
||||
// by the Gateway, we want to trim it down to `/rest/of/path` for the
|
||||
// upstream request. In the following regex, in the case of a match
|
||||
// the requestURL will be at `0`, the function name at `1` and the
|
||||
// rest of the path (the part we are interested in) at `2`.
|
||||
matcher := functionMatcher.Copy()
|
||||
parts := matcher.FindStringSubmatch(requestURL)
|
||||
if 3 == len(parts) {
|
||||
url += parts[2]
|
||||
} else {
|
||||
url += requestURL
|
||||
}
|
||||
}
|
||||
url := baseURL + requestURL
|
||||
|
||||
if len(r.URL.RawQuery) > 0 {
|
||||
url = fmt.Sprintf("%s?%s", url, r.URL.RawQuery)
|
||||
@ -211,3 +200,46 @@ func (f FunctionAsHostBaseURLResolver) Resolve(r *http.Request) string {
|
||||
|
||||
return fmt.Sprintf("http://%s%s:%d", svcName, suffix, watchdogPort)
|
||||
}
|
||||
|
||||
// TransparentURLPathTransformer passes the requested URL path through untouched.
|
||||
type TransparentURLPathTransformer struct {
|
||||
}
|
||||
|
||||
// Transform returns the URL path unchanged.
|
||||
func (f TransparentURLPathTransformer) Transform(r *http.Request) string {
|
||||
return r.URL.Path
|
||||
}
|
||||
|
||||
// PathTruncatingURLPathTransformer always truncated the path to "/".
|
||||
type PathTruncatingURLPathTransformer struct {
|
||||
}
|
||||
|
||||
// Transform always return a path of "/".
|
||||
func (f PathTruncatingURLPathTransformer) Transform(r *http.Request) string {
|
||||
return "/"
|
||||
}
|
||||
|
||||
// FunctionPrefixTrimmingURLPathTransformer removes the "/function/servicename/" prefix from the URL path.
|
||||
type FunctionPrefixTrimmingURLPathTransformer struct {
|
||||
}
|
||||
|
||||
// Transform removes the "/function/servicename/" prefix from the URL path.
|
||||
func (f FunctionPrefixTrimmingURLPathTransformer) Transform(r *http.Request) string {
|
||||
ret := r.URL.Path
|
||||
|
||||
if ret != "" {
|
||||
// When forwarding to a function, since the `/function/xyz` portion
|
||||
// of a path like `/function/xyz/rest/of/path` is only used or needed
|
||||
// by the Gateway, we want to trim it down to `/rest/of/path` for the
|
||||
// upstream request. In the following regex, in the case of a match
|
||||
// the r.URL.Path will be at `0`, the function name at `1` and the
|
||||
// rest of the path (the part we are interested in) at `2`.
|
||||
matcher := functionMatcher.Copy()
|
||||
parts := matcher.FindStringSubmatch(ret)
|
||||
if 3 == len(parts) {
|
||||
ret = parts[2]
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
@ -164,7 +164,10 @@ func Test_buildUpstreamRequest_Body_Method_Query_Path(t *testing.T) {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
upstream := buildUpstreamRequest(request, "http://xyz:8080", request.URL.Path)
|
||||
transformer := FunctionPrefixTrimmingURLPathTransformer{}
|
||||
transformedPath := transformer.Transform(request)
|
||||
|
||||
upstream := buildUpstreamRequest(request, "http://xyz:8080", transformedPath)
|
||||
|
||||
if request.Method != upstream.Method {
|
||||
t.Errorf("Method - want: %s, got: %s", request.Method, upstream.Method)
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
// MakeQueuedProxy accepts work onto a queue
|
||||
func MakeQueuedProxy(metrics metrics.MetricOptions, wildcard bool, canQueueRequests queue.CanQueueRequests) http.HandlerFunc {
|
||||
func MakeQueuedProxy(metrics metrics.MetricOptions, wildcard bool, canQueueRequests queue.CanQueueRequests, pathTransformer URLPathTransformer) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
|
||||
@ -49,6 +49,7 @@ func MakeQueuedProxy(metrics metrics.MetricOptions, wildcard bool, canQueueReque
|
||||
Body: body,
|
||||
Method: r.Method,
|
||||
QueryString: r.URL.RawQuery,
|
||||
Path: pathTransformer.Transform(r),
|
||||
Header: r.Header,
|
||||
Host: r.Host,
|
||||
CallbackURL: callbackURL,
|
||||
|
Reference in New Issue
Block a user