【问题标题】:Golang ServeHTTP make proxy error EOF on POST requestGolang ServeHTTP 在 POST 请求上生成代理错误 EOF
【发布时间】:2022-01-29 13:29:32
【问题描述】:

我正在使用 gin 和 ServeHTTP 开发代理服务器。实际上 GET 和 OPTIONS 请求效果很好。但是,当我尝试多个 POST 请求时,我会收到二分之一的 EOF 错误请求。 我已经测试在没有代理服务的情况下重复请求并且它的工作正常,所以我的代码中有一些东西不起作用。

编辑:

  1. 我用https://ptsv2.com/ 测试了POST 代理,所有请求响应都返回200 状态码。
// main.go

package main

import (
    "fmt"
    "../pkg/api"
)

func main() {
    fmt.Println("Starting server")
    api.InitServer()
}

// routes.go
package api

import (
    "github.com/gin-gonic/gin"
)

const serviceUrl = "http://localhost:8732"

func InitServer() {
    router := gin.Default()
    defineRoutes(router)
    router.Run()
}

func defineRoutes(router *gin.Engine) {
    router.GET("/ping", Ping)
    router.POST("/*any", Proxy(serviceUrl))
}
// controller.go

package api

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "net/http"
    "net/http/httputil"
    "net/url"
    "strconv"
    "github.com/gin-gonic/gin"
)

type transport struct {
    http.RoundTripper
}

func (t *transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
    resp, err = t.RoundTripper.RoundTrip(req)
    if err != nil {
        // EOF ERROR HERE
        return nil, err
    }
    b, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return nil, err
    }
    err = resp.Body.Close()
    if err != nil {
        return nil, err
    }
    b = bytes.Replace(b, []byte("server"), []byte("schmerver"), -1)
    body := ioutil.NopCloser(bytes.NewReader(b))

    response := resp
    response.Body = body


    response.ContentLength = int64(len(b))
    response.Header.Set("Content-Length", strconv.Itoa(len(b)))
    response.Header.Set("Access-Control-Allow-Origin", "*")

    return response, nil
}

func Proxy(targetUrl string) gin.HandlerFunc {
    fn := func(c *gin.Context) {
        remote, err := url.Parse(targetUrl)
        if err != nil {
            panic(err)
        }
        proxy := httputil.NewSingleHostReverseProxy(remote)

        proxy.Director = func(req *http.Request) {
            req.Header = c.Request.Header
            req.Host = remote.Host
            req.URL.Scheme = remote.Scheme
            req.URL.Host = remote.Host
            req.Close = true // True / False same result
        }
        proxy.Transport = &transport{http.DefaultTransport}
        proxy.ServeHTTP(c.Writer, c.Request)
    }
    return fn
}

【问题讨论】:

  • 我已经编辑了代码示例

标签: go go-gin go-http


【解决方案1】:

结论

您的代码没有错误。有用。可能你的网络设置有问题。

解释

我下载您的代码并使用本地后端服务器对其进行测试。它有效。

附录

后端服务器代码

package main

import (
    "fmt"

    "github.com/gin-gonic/gin"
)

func main() {
    fmt.Println("Starting server")
    router := gin.Default()
    router.POST("/*any", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "mes": "hello",
        })
    })
    router.Run(":8888")
}

【讨论】:

  • 感谢您的认可,我已经更换电脑并重建所有环境,它的工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-07
  • 1970-01-01
  • 2018-08-05
  • 2022-08-12
  • 2022-08-13
  • 2017-12-24
  • 1970-01-01
相关资源
最近更新 更多