如何在Go中实现HTTP转发代理

如何在Go中实现HTTP转发代理,http,go,Http,Go,我想为您实现一个HTTP请求和响应系统 client ------> A ----------> B --------> (request) HTTPserver client <------ A <---------- B <-------- (response) HTTPserver 客户端使用任何HTTP方法POST、PUT等将HTTP请求发送到 然后A读取请求主体并对其进行加密,然后将其转发给B 3B然后解密读取HTTP请求正文的数据 然后,将接收到

我想为您实现一个HTTP请求和响应系统

client ------> A ----------> B --------> (request) HTTPserver
client <------ A <---------- B <-------- (response) HTTPserver
客户端使用任何HTTP方法POST、PUT等将HTTP请求发送到 然后A读取请求主体并对其进行加密,然后将其转发给B 3B然后解密读取HTTP请求正文的数据 然后,将接收到的解密主体作为有效负载,准备一个HTTP请求并发送到HTTP服务器。 5然后HTTP服务器响应B。 B然后加密来自HTTP服务器的响应,然后转发给A。 A还对B的响应进行解密,然后将响应发送回客户端。 根据前面的建议,我已经实现了以下内容

ProxyA:

const (
  ServerB = "<address of B>"
  Port = "<proxy A port>"
)

func main() {
  // start server
  http.HandleFunc("/", proxyPass)
  log.Fatal(http.ListenAndServe(":" + Port, nil))
}

func proxyPass(res http.ResponseWriter, req  *http.Request) {
 
 // read request body from client
bodybytes, _ := ioutil.ReadAll(req.Body)

defer req.Body.Close()

// encrypt req.Body
object, _ := enc.Encrypt(bodybytes)

// serialize object
serialized, _ := object.CompactSerialize()

// prepare forwarding message
msg := message{reformatedData: serialized}

// encode message 
msgbytes, _ := json.Marshal(&msg)

req.ContentLength = int64(len(msgbytes))
req.Body = ioutil.NopCloser(bytes.NewBuffer(msgbytes))


// How do I read the response data from proxy server B and then send
// response to the client
....
 
  url, _ := url.Parse(ServerB)
  proxy := httputil.NewSingleHostReverseProxy(url)
  proxy.ServeHTTP(res, req)
}
我的问题是

如何将代理B中proxyServHTTP res的respmsgbytes写回代理A

如何从代理服务器B读取响应数据,然后发送 对客户的回应

有什么帮助吗?我留下了错误检查来缩短代码。

您可以使用 你可以做如下的事情。 对于代理A:

const (
  ServerB = "<address of B>"
  Port = "<proxy A port>"
)

func main() {
  // start server
  http.HandleFunc("/", proxyPass)
  log.Fatal(http.ListenAndServe(":" + Port, nil))
}

func proxyPass(res http.ResponseWriter, req  *http.Request) {
  // Encrypt Request here
  // ...

  url, _ := url.Parse(ServerB)
  proxy := httputil.NewSingleHostReverseProxy(url)
  proxy.ServeHTTP(res, req)
} 
这可以在两个代理上完成

编辑: 可以使用更新代理响应。 您可以这样使用它:

func proxyPass(res http.ResponseWriter, req *http.Request) {
    ....
    
    proxy := httputil.NewSingleHostReverseProxy(url)
    
    proxy.ModifyResponse = func(response *http.Response) error {
        // Read and update the response here

        // The response here is response from server (proxy B if this is at proxy A)
        // It is a pointer, so can be modified to update in place
        // It will not be called if Proxy B is unreachable
    }

    proxy.ServeHTTP(res, req)
}
你可以用 你可以做如下的事情。 对于代理A:

const (
  ServerB = "<address of B>"
  Port = "<proxy A port>"
)

func main() {
  // start server
  http.HandleFunc("/", proxyPass)
  log.Fatal(http.ListenAndServe(":" + Port, nil))
}

func proxyPass(res http.ResponseWriter, req  *http.Request) {
  // Encrypt Request here
  // ...

  url, _ := url.Parse(ServerB)
  proxy := httputil.NewSingleHostReverseProxy(url)
  proxy.ServeHTTP(res, req)
} 
这可以在两个代理上完成

编辑: 可以使用更新代理响应。 您可以这样使用它:

func proxyPass(res http.ResponseWriter, req *http.Request) {
    ....
    
    proxy := httputil.NewSingleHostReverseProxy(url)
    
    proxy.ModifyResponse = func(response *http.Response) error {
        // Read and update the response here

        // The response here is response from server (proxy B if this is at proxy A)
        // It is a pointer, so can be modified to update in place
        // It will not be called if Proxy B is unreachable
    }

    proxy.ServeHTTP(res, req)
}

您可能会发现stdlib httputil.ReverseProxy有用您可能会发现stdlib httputil.ReverseProxy有用我收到错误:httputil:ReverseProxy在正文复制期间读取错误:读取tcp 127.0.0.1:52484->127.0.0.1:2020:读取:由对等方重置连接您正在尝试连接什么?该错误是由对等方重置的连接。这意味着出于某种原因,客户端似乎发送了RST,或者说是我的错,使用了http.ListenAndServeTLS而不是http.ListenAndServe。但是,在请求加密后,我如何将其发送到代理B?您必须使用请求正文并更新请求本身。我会直接更新当前请求。收到错误:httputil:ReverseProxy在正文复制期间读取错误:读取tcp 127.0.0.1:52484->127.0.0.1:2020:读取:peerhow重置连接您正在尝试连接吗?该错误是由对等方重置的连接。这意味着出于某种原因,客户端似乎发送了RST,或者说是我的错,使用了http.ListenAndServeTLS而不是http.ListenAndServe。但是,在请求加密后,我如何将其发送到代理B?您必须使用请求正文并更新请求本身。我会直接更新当前的请求。
func proxyPass(res http.ResponseWriter, req *http.Request) {
    ....
    
    proxy := httputil.NewSingleHostReverseProxy(url)
    
    proxy.ModifyResponse = func(response *http.Response) error {
        // Read and update the response here

        // The response here is response from server (proxy B if this is at proxy A)
        // It is a pointer, so can be modified to update in place
        // It will not be called if Proxy B is unreachable
    }

    proxy.ServeHTTP(res, req)
}