2017-02-26 13 views
1

私はGolangで単純な逆プロキシを書いています。コードは以下の通りである:Nollyxの背後にあるアプリケーションにGolangリバースプロキシ

func NewMultiHostProxy(target_urls []string) gin.HandlerFunc { 
    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) 
    } 
    return func(c *gin.Context) { 
     director := func(req *http.Request) { 
      target := urls[rand.Int()%len(urls)] 
      r := c.Request 
      req = r 
      req.URL.Scheme = target.Scheme 
      req.URL.Host = target.Host 
      req.URL.Path = target.Path 
      req.Header.Set("X-GoProxy", "GoProxy") 
      if target.RawQuery == "" || req.URL.RawQuery == "" { 
       req.URL.RawQuery = target.RawQuery + req.URL.RawQuery 
      } else { 
       req.URL.RawQuery = target.RawQuery + "&" + req.URL.RawQuery 
      } 
      log.Print(req.URL) 
     } 
     proxy := &httputil.ReverseProxy{Director: director} 
     proxy.ServeHTTP(c.Writer, c.Request) 
    } 
} 

私はプロキシにnginxの後ろのREST APIへの要求を1つしようとしています、nginxのはいつも私が直接REST APIにアクセスする場合、それは正確に結果を返します。しかし、404を返します。ここに私のNginxの設定です:

server { 
    listen  80; 
    server_name myservername; 

    location /api { 
     proxy_pass http://127.0.0.1:5000; 
     proxy_set_header X-Real-IP $remote_addr; 
     proxy_set_header Host $host; 
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    } 
} 

私はこの問題をデバッグする方法を知っていますか?それはNginxの設定によって引き起こされますか? https://golang.org/pkg/net/http/httputil/#ReverseProxyから

答えて

2

&httputil.ReverseProxy{Director: director}

にリバースプロキシを構築するために使用される機能がある

// Director must be a function which modifies 
    // the request into a new request to be sent 
    // using Transport. Its response is then copied 
    // back to the original client unmodified. 
    // Director must not access the provided Request 
    // after returning. 
    Director func(*http.Request) 

しかし、あなたのdirectorは決してhttp.Requestreqポイントに変更しません。ポインタをreq = rに再割り当てします。無関係なhttp.Requestが代わりに変更されます。

+0

こんにちは@cshu、返信いただきありがとうございます。私は再割り当てコードを削除しましたが、404エラーは継続します。 Nginxログには、アクセスのためのレコードがあるので、プロキシ要求はターゲットに到達できますが、nginxログには404が表示されます。 –

0

問題はリクエスト本体にあります。 Ginがどのようにパラメータを取得するかを調べると、それが開いて読んで閉じていることがわかります。したがって、要求を転送すると、要求本体は空になります。

0

私はこの同じ問題に直面しました。私はホストを設定することでそれを解決しました。 nginxは、ホスト(server_name)を使用して、ポート80上のどのサーバを提供するかを決定します。

req.Host = target.Host 
// or 
req.Host = "" 

URLホストがちょうど側の注意点としてreq.URL.Host = target.Host https://golang.org/pkg/net/http/#Request

// For client requests Host optionally overrides the Host 
    // header to send. If empty, the Request.Write method uses 
    // the value of URL.Host. Host may contain an international 
    // domain name. 
    Host string 

を設定して、あなたはジンハンドラの外のプロキシを作成し、proxy.ServeHTTP(c.Writer, c.Request)を呼び出すことができますので、それは空の文字列に設定することができますジンハンドラーで最終的な結果は次のようになります。

func NewMultiHostProxy(target_urls []string) gin.HandlerFunc { 
    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 
     req.Host = "" 
     req.Header.Set("X-GoProxy", "GoProxy") 
     if target.RawQuery == "" || req.URL.RawQuery == "" { 
      req.URL.RawQuery = target.RawQuery + req.URL.RawQuery 
     } else { 
      req.URL.RawQuery = target.RawQuery + "&" + req.URL.RawQuery 
     } 
     log.Print(req.URL) 
    } 
    proxy := &httputil.ReverseProxy{Director: director} 
    return func(c *gin.Context) { 
     proxy.ServeHTTP(c.Writer, c.Request) 
    } 
} 
関連する問題