Io 在两个函数之间发送“Reader”
我正在尝试发出一个Io 在两个函数之间发送“Reader”,io,go,Io,Go,我正在尝试发出一个GET请求,然后在POST请求中将我获得的内容发送到另一个站点。以下代码可以正常工作: func deliver(sourceURL *url.URL, destinationURL *url.URL) { client := &http.Client{} sourceResponse, err := http.Get(sourceURL.String()) if err == nil { body, _ := ioutil.Re
GET
请求,然后在POST
请求中将我获得的内容发送到另一个站点。以下代码可以正常工作:
func deliver(sourceURL *url.URL, destinationURL *url.URL) {
client := &http.Client{}
sourceResponse, err := http.Get(sourceURL.String())
if err == nil {
body, _ := ioutil.ReadAll(sourceResponse.Body)
client.Post(destinationURL.String(), "text/html", strings.NewReader(string(body)))
}
}
但这会将整个响应读取到内存中—如何将响应流式传输到POST请求中?以下是我正在尝试的:
func deliver(sourceURL *url.URL, destinationURL *url.URL) {
client := &http.Client{}
sourceResponse, err := http.Get(sourceURL.String())
if err == nil {
client.Post(destinationURL.String(), "text/html", sourceResponse.Body)
}
}
我认为这会起作用,但它只发送一个空请求(没有正文)。为什么会这样?client.Post
函数是否实际尝试读取响应
下面是一个在运动场上的例子:
发送dataReader
而不是sourceResponse.Body
效果很好,但是直接发送sourceResponse.Body
不起作用
示例链接:
http://localhost:3000/fetch?dest=http://requestb.in/177ji621&src=http://www.google.com
http://requestb.in/177ji621?inspect
我做了一个小测试程序来尝试这个
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
)
var client = &http.Client{}
func httpd() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
log.Printf("%s Request from %s", r.Method, r.RemoteAddr)
if r.Method == "GET" {
fmt.Fprintf(w, "Here is a GET body")
return
}
body, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Fatalf("body read failed: %v", err)
}
log.Printf("Body received from %s: %q", r.Method, body)
})
log.Fatal(http.ListenAndServe(":8080", nil))
}
func deliver(sourceURL *url.URL, destinationURL *url.URL) {
sourceResponse, err := http.Get(sourceURL.String())
if err != nil {
log.Fatalf("post failed: %v", err)
}
postResponse, err := client.Post(destinationURL.String(), "text/html", sourceResponse.Body)
if err != nil {
log.Fatalf("post failed: %v", err)
}
postResponse.Body.Close()
sourceResponse.Body.Close()
}
func main() {
go httpd()
src, err := url.Parse("http://127.0.0.1:8080/")
if err != nil {
log.Fatalf("src parse failed: %v", err)
}
dst, err := url.Parse("http://127.0.0.1:8080/")
if err != nil {
log.Fatalf("dst parse failed: %v", err)
}
deliver(src, dst)
}
它运行良好,产生了这样的输出
2014/10/04 08:40:26 GET Request from 127.0.0.1:48910
2014/10/04 08:40:26 POST Request from 127.0.0.1:48911
2014/10/04 08:40:26 Body received from POST: "Here is a GET body"
因此,代码的问题很可能会被你没有检查的错误暴露出来——最有可能的错误是文章中的错误
还请注意,如果可以,您希望重用http.Client
,以便获得连接池
查看问题更新后更新 我用
http://requestb.in/
并且它不显示主体。然而,我确实看到了这种传输编码:chunked
,所以我怀疑requestb.in
不支持chunked传输编码
如果为请求提供整个正文,则go将设置
内容长度
标题,但go使用。尽管分块传输编码是HTTP/1.1规范的非可选部分,但仍有相当多的服务器不支持它。不知道为什么它不适合我。尝试检查所有错误,但没有问题。我可以确认请求正在发送,但正文仍然是空的。如果您需要更多帮助,请发布一个演示问题的工作示例。我在问题中添加了一个Go Playder示例-看起来我可以清晰地再现。某种意义上,我猜这可能就是问题所在。但我在围棋测试中也遇到了同样的问题。如果你仍然好奇,代码就在这里:在fetch.go
和fetch\u test.go
中。