|
@@ -15,7 +15,6 @@
|
|
|
package vhost
|
|
|
|
|
|
import (
|
|
|
- "bytes"
|
|
|
"context"
|
|
|
"encoding/base64"
|
|
|
"errors"
|
|
@@ -64,9 +63,9 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) *
|
|
|
req := r.Out
|
|
|
req.URL.Scheme = "http"
|
|
|
reqRouteInfo := req.Context().Value(RouteInfoKey).(*RequestRouteInfo)
|
|
|
- oldHost, _ := httppkg.CanonicalHost(reqRouteInfo.Host)
|
|
|
+ originalHost, _ := httppkg.CanonicalHost(reqRouteInfo.Host)
|
|
|
|
|
|
- rc := rp.GetRouteConfig(oldHost, reqRouteInfo.URL, reqRouteInfo.HTTPUser)
|
|
|
+ rc := req.Context().Value(RouteConfigKey).(*RouteConfig)
|
|
|
if rc != nil {
|
|
|
if rc.RewriteHost != "" {
|
|
|
req.Host = rc.RewriteHost
|
|
@@ -78,7 +77,7 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) *
|
|
|
endpoint, _ = rc.ChooseEndpointFn()
|
|
|
reqRouteInfo.Endpoint = endpoint
|
|
|
log.Tracef("choose endpoint name [%s] for http request host [%s] path [%s] httpuser [%s]",
|
|
|
- endpoint, oldHost, reqRouteInfo.URL, reqRouteInfo.HTTPUser)
|
|
|
+ endpoint, originalHost, reqRouteInfo.URL, reqRouteInfo.HTTPUser)
|
|
|
}
|
|
|
// Set {domain}.{location}.{routeByHTTPUser}.{endpoint} as URL host here to let http transport reuse connections.
|
|
|
req.URL.Host = rc.Domain + "." +
|
|
@@ -93,6 +92,15 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) *
|
|
|
req.URL.Host = req.Host
|
|
|
}
|
|
|
},
|
|
|
+ ModifyResponse: func(r *http.Response) error {
|
|
|
+ rc := r.Request.Context().Value(RouteConfigKey).(*RouteConfig)
|
|
|
+ if rc != nil {
|
|
|
+ for k, v := range rc.ResponseHeaders {
|
|
|
+ r.Header.Set(k, v)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ },
|
|
|
// Create a connection to one proxy routed by route policy.
|
|
|
Transport: &http.Transport{
|
|
|
ResponseHeaderTimeout: rp.responseHeaderTimeout,
|
|
@@ -116,10 +124,16 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) *
|
|
|
return nil, nil
|
|
|
},
|
|
|
},
|
|
|
- BufferPool: newWrapPool(),
|
|
|
- ErrorLog: stdlog.New(newWrapLogger(), "", 0),
|
|
|
+ BufferPool: pool.NewBuffer(32 * 1024),
|
|
|
+ ErrorLog: stdlog.New(log.NewWriteLogger(log.WarnLevel, 2), "", 0),
|
|
|
ErrorHandler: func(rw http.ResponseWriter, req *http.Request, err error) {
|
|
|
- log.Warnf("do http proxy request [host: %s] error: %v", req.Host, err)
|
|
|
+ log.Logf(log.WarnLevel, 1, "do http proxy request [host: %s] error: %v", req.Host, err)
|
|
|
+ if err != nil {
|
|
|
+ if e, ok := err.(net.Error); ok && e.Timeout() {
|
|
|
+ rw.WriteHeader(http.StatusGatewayTimeout)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
rw.WriteHeader(http.StatusNotFound)
|
|
|
_, _ = rw.Write(getNotFoundPageContent())
|
|
|
},
|
|
@@ -152,14 +166,6 @@ func (rp *HTTPReverseProxy) GetRouteConfig(domain, location, routeByHTTPUser str
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (rp *HTTPReverseProxy) GetHeaders(domain, location, routeByHTTPUser string) (headers map[string]string) {
|
|
|
- vr, ok := rp.getVhost(domain, location, routeByHTTPUser)
|
|
|
- if ok {
|
|
|
- headers = vr.payload.(*RouteConfig).Headers
|
|
|
- }
|
|
|
- return
|
|
|
-}
|
|
|
-
|
|
|
// CreateConnection create a new connection by route config
|
|
|
func (rp *HTTPReverseProxy) CreateConnection(reqRouteInfo *RequestRouteInfo, byEndpoint bool) (net.Conn, error) {
|
|
|
host, _ := httppkg.CanonicalHost(reqRouteInfo.Host)
|
|
@@ -300,8 +306,13 @@ func (rp *HTTPReverseProxy) injectRequestInfoToCtx(req *http.Request) *http.Requ
|
|
|
RemoteAddr: req.RemoteAddr,
|
|
|
URLHost: req.URL.Host,
|
|
|
}
|
|
|
+
|
|
|
+ originalHost, _ := httppkg.CanonicalHost(reqRouteInfo.Host)
|
|
|
+ rc := rp.GetRouteConfig(originalHost, reqRouteInfo.URL, reqRouteInfo.HTTPUser)
|
|
|
+
|
|
|
newctx := req.Context()
|
|
|
newctx = context.WithValue(newctx, RouteInfoKey, reqRouteInfo)
|
|
|
+ newctx = context.WithValue(newctx, RouteConfigKey, rc)
|
|
|
return req.Clone(newctx)
|
|
|
}
|
|
|
|
|
@@ -322,20 +333,3 @@ func (rp *HTTPReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request)
|
|
|
rp.proxy.ServeHTTP(rw, newreq)
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-type wrapPool struct{}
|
|
|
-
|
|
|
-func newWrapPool() *wrapPool { return &wrapPool{} }
|
|
|
-
|
|
|
-func (p *wrapPool) Get() []byte { return pool.GetBuf(32 * 1024) }
|
|
|
-
|
|
|
-func (p *wrapPool) Put(buf []byte) { pool.PutBuf(buf) }
|
|
|
-
|
|
|
-type wrapLogger struct{}
|
|
|
-
|
|
|
-func newWrapLogger() *wrapLogger { return &wrapLogger{} }
|
|
|
-
|
|
|
-func (l *wrapLogger) Write(p []byte) (n int, err error) {
|
|
|
- log.Warnf("%s", string(bytes.TrimRight(p, "\n")))
|
|
|
- return len(p), nil
|
|
|
-}
|