Improve URL Builders
Handles an issue where mux.Route does not set the desired scheme when building a url and always uses `http`. Now uses X-Forwarded-Proto when creating a URLBuilder from a request. Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
This commit is contained in:
parent
c41141fbd3
commit
f801b9a7bd
2 changed files with 141 additions and 50 deletions
|
@ -43,9 +43,30 @@ func NewURLBuilderFromString(root string) (*URLBuilder, error) {
|
|||
// NewURLBuilderFromRequest uses information from an *http.Request to
|
||||
// construct the root url.
|
||||
func NewURLBuilderFromRequest(r *http.Request) *URLBuilder {
|
||||
var scheme string
|
||||
|
||||
forwardedProto := r.Header.Get("X-Forwarded-Proto")
|
||||
|
||||
switch {
|
||||
case len(forwardedProto) > 0:
|
||||
scheme = forwardedProto
|
||||
case r.TLS != nil:
|
||||
scheme = "https"
|
||||
case len(r.URL.Scheme) > 0:
|
||||
scheme = r.URL.Scheme
|
||||
default:
|
||||
scheme = "http"
|
||||
}
|
||||
|
||||
host := r.Host
|
||||
forwardedHost := r.Header.Get("X-Forwarded-Host")
|
||||
if len(forwardedHost) > 0 {
|
||||
host = forwardedHost
|
||||
}
|
||||
|
||||
u := &url.URL{
|
||||
Scheme: r.URL.Scheme,
|
||||
Host: r.Host,
|
||||
Scheme: scheme,
|
||||
Host: host,
|
||||
}
|
||||
|
||||
return NewURLBuilder(u)
|
||||
|
@ -129,13 +150,28 @@ func (ub *URLBuilder) BuildBlobUploadChunkURL(name, uuid string, values ...url.V
|
|||
|
||||
// clondedRoute returns a clone of the named route from the router. Routes
|
||||
// must be cloned to avoid modifying them during url generation.
|
||||
func (ub *URLBuilder) cloneRoute(name string) *mux.Route {
|
||||
func (ub *URLBuilder) cloneRoute(name string) clonedRoute {
|
||||
route := new(mux.Route)
|
||||
*route = *ub.router.GetRoute(name) // clone the route
|
||||
root := new(url.URL)
|
||||
|
||||
return route.
|
||||
Schemes(ub.root.Scheme).
|
||||
Host(ub.root.Host)
|
||||
*route = *ub.router.GetRoute(name) // clone the route
|
||||
*root = *ub.root
|
||||
|
||||
return clonedRoute{Route: route, root: root}
|
||||
}
|
||||
|
||||
type clonedRoute struct {
|
||||
*mux.Route
|
||||
root *url.URL
|
||||
}
|
||||
|
||||
func (cr clonedRoute) URL(pairs ...string) (*url.URL, error) {
|
||||
routeURL, err := cr.Route.URL(pairs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cr.root.ResolveReference(routeURL), nil
|
||||
}
|
||||
|
||||
// appendValuesURL appends the parameters to the url.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue