Chi: Reverse proxy not working

Created on 5 Mar 2017  路  3Comments  路  Source: go-chi/chi

Hi, thanks for this great project. I wrote a simple reverse proxy with Chi, intending to implement an api gateway. However, there's some issue with the reverse proxy.

The proxy will forward a request to a restful endpoint in remote server and the server is using Nginx. Since the endpoint takes a long time to return result (6-8 secs), sometimes golang complains timeout. However, when it does not timeout, it returns 404 and Nginx in remote server log 404 as well. I don't quite understand this behaviour. Anyone facing the same issue? Or my implementation is problematic?

The code is listed below.

func NewMultiHostReverseProxy(target_urls []string) *httputil.ReverseProxy {
    var urls []*url.URL
    for i := 0; i < len(target_urls); i++ {
        target, err := url.Parse(target_urls[i])
        if err != nil {
            fmt.Errorf("Error parsing url")
            return nil
        }
        urls = append(urls, target)
    }
    director := func(req *http.Request) {
        target := urls[rand.Int()%len(urls)]
        req.URL.Scheme = target.Scheme
        req.URL.Host = target.Host
        req.URL.Path = target.Path
        targetQuery := target.RawQuery
        if targetQuery == "" || req.URL.RawQuery == "" {
            req.URL.RawQuery = targetQuery + req.URL.RawQuery
        } else {
            req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
        }
        if _, ok := req.Header["User-Agent"]; !ok {
            // explicitly disable User-Agent so it's not set to default value
            req.Header.Set("User-Agent", "")
        }
    }
    return &httputil.ReverseProxy{Director: director}
}

Most helpful comment

ReverseProxy is just a handler. It works.

Try:

func ProxyHandler(w http.ResponseWriter, r *http.Request) {
    url, _ := url.Parse("http://example.com/path/")

    proxy := httputil.ReverseProxy{Director: func(r *http.Request) {
        r.URL.Scheme = url.Scheme
        r.URL.Host = url.Host
        r.URL.Path = url.Path + r.URL.Path
        r.Host = url.Host
    }}
    proxy.ServeHTTP(w, r)
}

All 3 comments

ReverseProxy is just a handler. It works.

Try:

func ProxyHandler(w http.ResponseWriter, r *http.Request) {
    url, _ := url.Parse("http://example.com/path/")

    proxy := httputil.ReverseProxy{Director: func(r *http.Request) {
        r.URL.Scheme = url.Scheme
        r.URL.Host = url.Host
        r.URL.Path = url.Path + r.URL.Path
        r.Host = url.Host
    }}
    proxy.ServeHTTP(w, r)
}

Thanks @VojtechVitek @zet4 . I think it should be the problem with nginx config, instead of golang code.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kevinconway picture kevinconway  路  8Comments

didip picture didip  路  7Comments

dannyvankooten picture dannyvankooten  路  5Comments

leighmcculloch picture leighmcculloch  路  8Comments

valsor picture valsor  路  5Comments