如何从HTTP响应中读取附件
问题描述:
我试图从URL下载一些csv数据。原始响应看起来是这样的如何从HTTP响应中读取附件
HTTP/1.1 200 OK
Server: Europa-4
X-Varnish: 33948791
Vary: Accept-Encoding, X-UA-Device
X-Cache: MISS
Cache-Control: no-cache, no-cache, no-store, proxy-revalidate, must-revalidate, max-age=0
Content-Type: application/octet-stream
P3p: CP="CAO PSA OUR"
Date: Fri, 01 Sep 2017 19:53:27 GMT
X-Server: web03
Expires: Fri, 01 Sep 2017 19:53:26 GMT
X-XSS-Protection: 1; mode=block
Transfer-Encoding: chunked
Accept-Ranges: bytes
X-Content-Type-Options: nosniff
Content-Disposition: attachment; filename="GooglePLAv1US.txt"
Via: 1.1 varnish-v4
Connection: keep-alive
Last-Modified: Fri, 01 Sep 2017 19:53:27 +0000
X-Frame-Options: sameorigin
X-UA-Device: desktop
Age: 0
X-Modified-Url: /amfeed/main/get/file/GooglePLAv1US/?___store=ca_en
id title description google_product_category .....
20649074 ......
20652632 ......
.
.
.
现在我知道这是不是一个真正的多方响应,但它具有Content-Disposition: attachment; filename="GooglePLAv1US.txt"
头,它说,它需要被视为一个下载浏览器。
当我尝试读取响应的主体时,它会抛出错误unexpected EOF
。我如何读取这些数据,这不是真的在任何一个部分?
代码
http.DefaultClient.Timeout = time.Second * 30
resp, err := http.Get(ht.Creds.AccessData.URL)
if err != nil {
return nil, err
}
defer resp.Body.Close()
d, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrap(err, "Error reading HTTP response body")
}
这会产生错误
Error reading HTTP response body: unexpected EOF
答
给一个尝试net/textproto,这里是一个小例子:
package main
import (
"bufio"
"fmt"
"io"
"net/http"
"net/http/httptest"
"net/textproto"
"os"
)
func main() {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "%s\n%s\n%s\n%s\n",
"col1,col2,col3",
"1,2,3",
"a,b,c",
"x,y,x",
)
}))
defer ts.Close()
client := &http.Client{}
res, err := client.Get(ts.URL)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
defer res.Body.Close()
reader := bufio.NewReader(res.Body)
tp := textproto.NewReader(reader)
for {
if line, err := tp.ReadLine(); err != nil {
if err == io.EOF {
// if file is emtpy
return
}
return
} else {
fmt.Printf("%s\n\n", line)
}
}
}
https://play.golang.org/p/fee4B5mh35
这是基于你原来的问题就“CSV”又如:
package main
import (
"bufio"
"fmt"
"net/http"
"os"
)
func main() {
client := &http.Client{}
res, err := client.Get("http://samplecsvs.s3.amazonaws.com/Sacramentorealestatetransactions.csv")
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
defer res.Body.Close()
scanner := bufio.NewScanner(res.Body)
scanner.Split(bufio.ScanBytes)
for scanner.Scan() {
c := scanner.Text()
switch c {
case "\r":
fmt.Println()
default:
fmt.Printf("%s", c)
}
}
}
在这种情况下,注意scanner.Split(bufio.ScanBytes)
,希望这可以给你更多的想法。
它在response.Body中,假设你使用Go(基于问题标签),但是你没有显示任何代码,所以没有太多的人可以提供帮助。 – Adrian
@Adrian提交了我正在使用的代码,谢谢! – Danish