Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如何将HTTP响应写入标准输出?_Go - Fatal编程技术网

Go 如何将HTTP响应写入标准输出?

Go 如何将HTTP响应写入标准输出?,go,Go,我正试图将从GET请求收到的原始HTTP响应写入stdout。我原以为httputil.DumpResponse可以满足我的要求,但它似乎包含了“更大”响应的神秘字节计数 例如: HTTP/1.1 200 OK Transfer-Encoding: chunked Content-Type: text/plain; charset=utf-8 Date: Mon, 16 Oct 2017 15:07:53 GMT 1f43 THE ACTUAL BODY CONTENT WHICH IS 80

我正试图将从GET请求收到的原始HTTP响应写入stdout。我原以为
httputil.DumpResponse
可以满足我的要求,但它似乎包含了“更大”响应的神秘字节计数

例如:

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: text/plain; charset=utf-8
Date: Mon, 16 Oct 2017 15:07:53 GMT

1f43
THE ACTUAL BODY CONTENT WHICH IS 8003 BYTES
0
1f43
似乎是响应主体的长度。Go的
http.response
谈到了拖车,所以
0
可能是拖车的大小

我的代码是:

    var resp *http.Response
    var err error

    if *isPost {
        resp, err = http.Post(url, "application/x-www-form-urlencoded", strings.NewReader(*data))
    } else {
        resp, err = http.Get(url)
    }

    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    dump, err := httputil.DumpResponse(resp, true)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("%s", dump)
我已经阅读了
DumpResponse
TransferWriter
的代码,但是我不知道
1f43
0
来自哪里

如果我用curl发出相同的请求,我不会在响应中得到
1f43
0


这是编写原始HTTP响应的最佳方法吗?如果是这样,我如何修复它以避免这些字节计数?

您可以使用接口

Get调用返回一个指向响应类型的指针,该响应类型包含一个Body,如果检查Body接口,可以看到Body实现了io.ReadCloser,它同时实现了Reader和Closer接口

通过理解这些接口,您可以使用例如:io.Copy

func Copy(dst Writer, src Reader) (written int64, err error) {...}
作为第二个参数,您可以传递响应体,它实现读取器

作为第一个参数Writer,您既可以实现自己的自定义类型,也可以创建一个func来实现Writer接口,或者也可以使用内置的os.Stdout,后者已经实现了Writer接口

package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
)

func main() {

    resp, err := http.Get("http://google.com")

    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(1)
    }

    io.Copy(os.Stdout, resp.Body)
}

你可以使用接口

Get调用返回一个指向响应类型的指针,该响应类型包含一个Body,如果检查Body接口,可以看到Body实现了io.ReadCloser,它同时实现了Reader和Closer接口

通过理解这些接口,您可以使用例如:io.Copy

func Copy(dst Writer, src Reader) (written int64, err error) {...}
作为第二个参数,您可以传递响应体,它实现读取器

作为第一个参数Writer,您既可以实现自己的自定义类型,也可以创建一个func来实现Writer接口,或者也可以使用内置的os.Stdout,后者已经实现了Writer接口

package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
)

func main() {

    resp, err := http.Get("http://google.com")

    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(1)
    }

    io.Copy(os.Stdout, resp.Body)
}

这就是“传输编码:分块”的原因。分块响应实际上(实际上必须)具有这些“1f43”长度。所以:不要做出分块的回答,例如通过设置内容长度(参见)。啊哈,好的。有了这些信息,我找到了发生这种情况的地方:在
net/http/internal/chunked
Write()函数中;我正在发送请求,并试图打印我得到的取消注册的响应。好吧,然后将其分块,因为这就是响应。或者阅读全文,用内容长度替换传输编码,并在转储响应之前重新提供正文。有意义,谢谢。如果你想回答这个问题,我很乐意接受。这就是“传输编码:分块”的原因。分块响应实际上(实际上必须)具有这些“1f43”长度。所以:不要做出分块的回答,例如通过设置内容长度(参见)。啊哈,好的。有了这些信息,我找到了发生这种情况的地方:在
net/http/internal/chunked
Write()函数中;我正在发送请求,并试图打印我得到的取消注册的响应。好吧,然后将其分块,因为这就是响应。或者阅读全文,用内容长度替换传输编码,并在转储响应之前重新提供正文。有意义,谢谢。如果你想回答这个问题,我很乐意接受。谢谢。我只是意识到我从来没有说过我也想要响应的标题(这就是为什么我使用
dumpResponse()
)–但是你的答案回答了我的问题。我看不到一个内置的方法来写标题,所以我自己写出来,例如
fmt.Print(resp.Proto+“”+resp.Status+“\r\n”)
。谢谢。我只是意识到我从来没有说过我也想要响应的标题(这就是为什么我使用
dumpResponse()
)–但是你的答案回答了我的问题。我看不到一个内置的方法来写标题,所以我自己写出来,例如
fmt.Print(resp.Proto+“”+resp.Status+“\r\n”)