diff --git a/cmd/proxy/proxy.go b/cmd/proxy/proxy.go index a1fb9cc..9dc0f6e 100644 --- a/cmd/proxy/proxy.go +++ b/cmd/proxy/proxy.go @@ -1,11 +1,11 @@ -// This is honestly terrible +// This is honestly terrible. It only exists to replace the AWS S3 website hosting feature missing in minio package main import ( - "io" "log" + "net" "net/http" - "net/url" + "net/http/httputil" "os" "strings" "time" @@ -16,7 +16,6 @@ import ( var endpoint string var endpointSecure bool var behindProxy bool -var client *http.Client func main() { // Read configuration @@ -24,23 +23,11 @@ func main() { endpointSecure = os.Getenv("MINIO_ENDPOINT_SECURE") == "true" behindProxy = os.Getenv("BEHIND_PROXY") == "true" - // Setup HTTP client - transport := &http.Transport{ - MaxIdleConns: 4, - MaxIdleConnsPerHost: 4, - IdleConnTimeout: 30 * time.Second, - DisableCompression: true, - } - client = &http.Client{ - Transport: transport, - Timeout: 5 * time.Second, - } - server := &http.Server{ Addr: ":80", ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second, - Handler: http.HandlerFunc(handle), + Handler: &httputil.ReverseProxy{Director: director}, } err := server.ListenAndServe() if err != nil { @@ -48,44 +35,38 @@ func main() { } } -func handle(w http.ResponseWriter, r *http.Request) { +func director(req *http.Request) { // Validate host - if _, ok := dns.IsDomainName(r.Host); !ok { - w.WriteHeader(http.StatusBadRequest) + host, port, err := net.SplitHostPort(req.Host) + if err != nil { + // Assumption: IsDomainName will handle other cases + host = req.Host + } + if _, ok := dns.IsDomainName(host); !ok { + req.URL.Scheme = "" return } // Rewrite URL - path := mapPath(r.URL.Path, r.Host) - url := &url.URL{ - Scheme: "http", - Host: endpoint, - Path: path, - } + req.URL.Scheme = "http" if endpointSecure { - url.Scheme = "https" + req.URL.Scheme = "https" + } + req.URL.Host = endpoint + req.URL.Path = mapPath(req.URL.Path, host) + + if !behindProxy { + // Clear existing unsafe headers + req.Header.Del("Forwarded") + req.Header.Del("X-Forwarded-For") + + // Unnecessary, but might as well + req.Header.Set("X-Forwarded-Proto", req.URL.Scheme) + req.Header.Set("X-Forwarded-Host", host) + req.Header.Set("X-Forwarded-Port", port) } - // Update Forwarded headers - header := safeCloneHeader(r.Header) - - // Create forwarded request - out := &http.Request{ - URL: url, - Header: header, - } - - log.Println(out.URL) - resp, err := client.Do(out) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - log.Println(err) - return - } - defer resp.Body.Close() - - w.WriteHeader(resp.StatusCode) - io.Copy(w, resp.Body) + log.Println(req.URL) } func mapPath(path, host string) string { @@ -94,36 +75,3 @@ func mapPath(path, host string) string { } return "/" + host + path } - -// Further validation is required for this function -func safeCloneHeader(h http.Header) http.Header { - clone := make(http.Header, 0) - for key, value := range h { - if !safeHeaderName(key) { - continue - } - for _, v := range value { - clone.Add(key, v) - } - } - return clone -} - -// Comparisons in this function MUST be in canonical form -func safeHeaderName(name string) bool { - if behindProxy { - if name == "X-Forwarded-For" { - return true - } - if name == "X-Forwarded-Host" { - return true - } - if name == "X-Forwarded-Proto" { - return true - } - if name == "Forwarded" { - return true - } - } - return false -} diff --git a/cmd/thumbnail/thumbnail.go b/cmd/thumbnail/thumbnail.go index 240614c..548a3cf 100644 --- a/cmd/thumbnail/thumbnail.go +++ b/cmd/thumbnail/thumbnail.go @@ -101,7 +101,6 @@ func update(w http.ResponseWriter, req *http.Request) { } wg.Wait() - // Check for errors for _, op := range resizes { if op.err != nil { @@ -124,7 +123,6 @@ func update(w http.ResponseWriter, req *http.Request) { } wg.Wait() - // Check for errors for _, op := range resizes { if op.err != nil {