Files
gluetun/internal/httpproxy/http.go
2020-11-21 01:26:02 +00:00

72 lines
1.7 KiB
Go

package httpproxy
import (
"fmt"
"io"
"net"
"net/http"
"strings"
)
func (h *handler) handleHTTP(responseWriter http.ResponseWriter, request *http.Request) {
switch request.URL.Scheme {
case "http", "https":
default:
h.logger.Warn("Unsupported scheme %q", request.URL.Scheme)
http.Error(responseWriter, "unsupported scheme", http.StatusBadRequest)
return
}
request = request.WithContext(h.ctx)
request.RequestURI = ""
for _, key := range hopHeaders {
request.Header.Del(key)
}
if !h.stealth {
setForwardedHeaders(request)
}
response, err := h.client.Do(request)
if err != nil {
http.Error(responseWriter, "server error", http.StatusInternalServerError)
h.logger.Warn("cannot request %s for client %q: %s",
request.URL, request.RemoteAddr, err)
return
}
defer response.Body.Close()
if h.verbose {
h.logger.Info("%s %s %s %s", request.RemoteAddr, response.Status, request.Method, request.URL)
}
for _, key := range hopHeaders {
response.Header.Del(key)
}
targetHeaderPtr := responseWriter.Header()
for key, values := range response.Header {
for _, value := range values {
targetHeaderPtr.Add(key, value)
}
}
responseWriter.WriteHeader(response.StatusCode)
if _, err := io.Copy(responseWriter, response.Body); err != nil {
h.logger.Error("%s %s: body copy error: %s", request.RemoteAddr, request.URL, err)
}
}
func setForwardedHeaders(request *http.Request) {
clientIP, _, err := net.SplitHostPort(request.RemoteAddr)
if err != nil {
return
}
// keep existing proxy headers
if prior, ok := request.Header["X-Forwarded-For"]; ok {
clientIP = fmt.Sprintf("%s,%s", strings.Join(prior, ", "), clientIP)
}
request.Header.Set("X-Forwarded-For", clientIP)
}