我尝试发出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
函数是否真的尝试读取响应?
这是Go游乐场的一个例子:http://play.golang.org/p/_EO80aj6wr
发送dataReader
代替sourceResponse.Body
效果很好,但直接发送sourceResponse.Body
并不起作用。
示例链接:
http://localhost:3000/fetch?dest=http://requestb.in/177ji621&src=http://www.google.com
http://requestb.in/177ji621?inspect
答案 0 :(得分:2)
我做了一个小测试程序试试这个
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/
尝试了我的测试程序,它没有显示身体。但是我确实看到了Transfer-Encoding: chunked
,所以我怀疑requestb.in
不支持分块传输编码。
如果您将整个正文提供给请求,那么请设置Content-Length
标题,但是if you provide a stream然后使用chunked transfer encoding。尽管分块传输编码是HTTP / 1.1规范的非可选部分,但仍有不少服务器不能正确支持它。