在 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)
}
这是架构:
客户端发送一个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)
}