wnanbei / direwolf

Package direwolf is a convenient and easy to use http client written in Golang.
https://wnanbei.github.io/direwolf/
MIT License
43 stars 3 forks source link

read Response.Body failed unexpected EOF #1

Closed tablecell closed 5 years ago

tablecell commented 5 years ago
package main

import (
    "fmt"
    dw "github.com/wnanbei/direwolf"
)

func main() {
    url := "https://blog.csdn.net/u013451157/article/details/78719374"
    headers := dw.NewHeaders(
        "User-Agent", "direwolf",
    )
    resp, err := dw.Get(url, headers)
    if  nil !=  err{
        fmt.Println(err)
        return
    }
    //fmt.Println(resp.Text())

    fmt.Println(string(resp.Content()))
}
wnanbei commented 5 years ago

因为 Golang net/http 库的设定,如果在请求头里只指定了 "Accept-Encoding": "gzip" 的话,那么返回的 Body 是不会自动 gzip 解压的,需要手动解压。

解压前把 resp.Contont() 获得的 []byte 转换成 io.Reader 就可以用官方的 compress/gzip 解压了。

package main

import (
    "bytes"
    "compress/gzip"
    "fmt"
    "io/ioutil"

    dw "github.com/wnanbei/direwolf"
)

func main() {
    url := "http://httpbin.org/gzip"
    headers := dw.NewHeaders(
        "User-Agent", "direwolf",
        "Accept-Encoding", "gzip",
    )
    resp, err := dw.Get(url, headers)
    if err != nil {
        fmt.Println(err)
        return
    }

    gr, err := gzip.NewReader(bytes.NewReader(resp.Content()))
    if err != nil {
        fmt.Println(err)
        return
    }
    defer gr.Close()
    data, err := ioutil.ReadAll(gr)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(data))
}
tablecell commented 5 years ago

url = "https://blog.csdn.net/yang731227/article/details/89338745&"用这个url 测试----- 原始邮件 -----发件人:wnanbeinotifications@github.com发送时间:2019-11-08 11:14:08收件人:wnanbei/direwolfdirewolf@noreply.github.com抄送:tablecelltablecell@sohu.com;Authorauthor@noreply.github.com主 题:Re: [wnanbei/direwolf] read Response.Body failed  unexpected EOF (#1)因为 Golang net/http 库的设定,如果在请求头里只指定了 "Accept-Encoding": "gzip" 的话,那么返回的 Body 是不会自动 gzip 解压的,需要手动解压。解压前把 resp.Contont() 获得的 []byte 转换成 io.Reader 就可以用官方的 compress/gzip 解压了。package mainimport ( "bytes" "compress/gzip" "fmt" "io/ioutil" dw "github.com/wnanbei/direwolf")func main() { url := "http://httpbin.org/gzip" headers := dw.NewHeaders( "User-Agent", "direwolf", "Accept-Encoding", "gzip", ) resp, err := dw.Get(url, headers) if err != nil { fmt.Println(err) return } gr, err := gzip.NewReader(bytes.NewReader(resp.Content())) if err != nil { fmt.Println(err) return } defer gr.Close() data, err := ioutil.ReadAll(gr) if err != nil { fmt.Println(err) return } fmt.Println(string(data))}—You are receiving this because you authored the thread.Reply to this email directly, view it on GitHub, or unsubscribe.

wnanbei commented 5 years ago

@tablecell 我查了下,造成这个原因是因为,这个网页返回的标头中没有 content-length 这个字段,所以在使用 ioutil.ReadAll() 读取内容的时候,会由于不知道何时结尾,并抛 unexpected EOF 这个异常。

其实内容是已经都读到了的,你可以先加上 Accept-Encoding", "gzip 发起请求,然后在 data, err := ioutil.ReadAll(gr) 这个步骤忽略异常即可。

稍后我会更新一下,在构建 Response 时忽略这个异常。

wnanbei commented 5 years ago

@tablecell 在版本 0.5.4 中,已经忽略读取 Response.Body 遇到 Unexpected EOF 这个异常,数据可以正常读取。但如果需要自行手动解压 gzip 数据的话,依然可能会遇到这个问题,需要手动忽略这个 io.ErrUnexpectedEOF 异常。

如无疑问,就关闭这个 Issues 了。