Golang反向代理返回“未找到”或“禁止”错误

3

我正在尝试创建一个反向代理,将所有请求重定向到目标URL,例如google.com或任何其他API。不幸的是,所有目标都返回错误,如页面未找到或禁止访问的错误。

func main() {
 r := gin.Default()

 eanAPI := api.NewEanAPI()

 routers.InitRedirectRoutes(r, eanAPI)
 port := os.Getenv("PORT")
 if len(port) == 0 {
  port = "8000"
 }
 r.Run(":" + port)
}

// InitRedirectRoutes initialize routes redirection.
func InitRedirectRoutes(r *gin.Engine, eanAPI api.EanAPI) {
 r.POST("/*action", eanAPI.ReverseProxy)
 r.GET("/*action", eanAPI.ReverseProxy)
}


type EanAPI interface {
 ReverseProxy(ctx *gin.Context)
}

type eanAPI struct {
 baseURL string
}

func NewEanAPI() EanAPI {
 return &eanAPI{}
}

func (api *eanAPI) ReverseProxy(ctx *gin.Context) {
    // proxy
    forwardToHost := "http://httpbin.org/"
    // I tried with "https://jsonplaceholder.typicode.com/" 
    "http://google.com"

 reverseProxy := proxy.NewProxy(forwardToHost)
 reverseProxy.Handle(ctx.Writer, ctx.Request, url.Parse(forwardToHost))
}

type Prox struct {
 target *url.URL
 proxy  *httputil.ReverseProxy
}

func NewProxy(target string) *Prox {
 url, _ := url.Parse(target)
 fmt.Println("url", url)
 return &Prox{target: url, proxy: httputil.NewSingleHostReverseProxy(url)}
}

func (p *Prox) Handle(w http.ResponseWriter, r *http.Request, origin *url.URL) {
 w.Header().Set("Content-Type", "application/json; charset=utf-8")
 w.Header().Set("X-Forwarded-Host", r.Host)
 w.Header().Set("X-Origin-Host", origin.Host)
 r.URL.Scheme = origin.Scheme
 r.URL.Host = origin.Host

 p.proxy.ServeHTTP(w, r)
}

我花了很多天时间尝试设置适当的标头,但目前为止什么都没有起作用。我认为标头没有被正确设置,但我不知道如何从客户端复制标头并添加到代理中。

我使用代理而不是重定向,因为我必须对请求和响应的主体进行一些处理!

提前感谢您!


2
你为什么不使用httputil.ReverseProxy来完成这个任务,而要重新发明轮子呢? - Jonathan Hall
1
eanapi.ReverseProxy 可能没有实现你所认为的功能。在我看来,它生成了形如 /somethingaction 的 get/post 请求发送给远端服务器,但这些 URL 在远端服务器上并不存在。 - user4466350
@Flimzy,我尝试过使用ReverseProxy,但出现了相同的错误! - Nizar AYARI
@mh-cbon,我尝试使用'/',但是出现了相同的错误。 - Nizar AYARI
你可以看一下go-micro包,它基于mdns和服务发现进行操作。 - zenwraight
1个回答

2
我不确定这是否有帮助,但是您可以使用https://golang.org/pkg/net/http/httputil/#ReverseProxy中的Director函数来调试和更改请求路径,检查传入的请求。还要确保不仅更改req.URL.Host,而且还要更改req.Host,因为这个将被apache/nginx虚拟主机设置所获取。不要放弃,记得享受!最初的回答。

我之前有这个代码: req.URL.Host = origin.Host 但是缺少了这一行代码: req.Host = origin.Host - Mantas Karanauskas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接