在 golang 中将管道读取写入 http 响应

Write pipe reading into http response in golang

这是架构:

客户端发送一个POST请求到服务器A

服务器 A 对此进行处理并向服务器 B 发送 GET

服务器 B 通过 A 向客户端发送响应


我虽然最好的想法是制作一个管道来读取 GET 的响应,然后写入 POST 的响应,但我遇到了很多类型的问题。

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/test/{hash}", testHandler)

    log.Fatal(http.ListenAndServe(":9095", r))
}

func handleErr(err error) {
    if err != nil {
        log.Fatalf("%s\n", err)
    }
}


func testHandler(w http.ResponseWriter, r *http.Request){

    fmt.Println("FIRST REQUEST RECEIVED")
    vars := mux.Vars(r)
    hash := vars["hash"]
    read, write := io.Pipe()

    // writing without a reader will deadlock so write in a goroutine
    go func() {
        write, _ = http.Get("http://localhost:9090/test/" + hash)
        defer write.Close()
    }()

    w.Write(read)
}

当我 运行 这样做时,出现以下错误:

./ReverseProxy.go:61: 不能在 w.Write

的参数中使用读取(类型 *io.PipeReader)作为类型 []byte

有没有办法将 io.PipeReader 格式正确地插入到 http 响应中? 还是我的做法完全错误?

您实际上并不是在写入它,而是在替换管道的写入。

大致如下:

func testHandler(w http.ResponseWriter, r *http.Request) {

    fmt.Println("FIRST REQUEST RECEIVED")

    vars := mux.Vars(r)
    hash := vars["hash"]

    read, write := io.Pipe()

    // writing without a reader will deadlock so write in a goroutine
    go func() {
        defer write.Close()
        resp, err := http.Get("http://localhost:9090/test/" + hash)
        if err != nil {
            return
        }
        defer resp.Body.Close()
        io.Copy(write, resp.Body)

    }()

    io.Copy(w, read)

}

不过,我同意@JimB 的观点,对于这种情况,甚至不需要管道,像这样的东西应该更有效:

func testHandler(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    hash := vars["hash"]

    resp, err := http.Get("http://localhost:9090/test/" + hash)
    if err != nil {
        // handle error
        return
    }
    defer resp.Body.Close()

    io.Copy(w, resp.Body)
}