gpt4 book ai didi

go - 来自 golang : upload fails without properly setting ContentLength 文件的 HTTP PUT 请求正文

转载 作者:行者123 更新时间:2023-12-01 22:33:26 24 4
gpt4 key购买 nike

我正在尝试发布一个简单的 PUT请求上传文件。 http.NewRequest接受 body (作为 io.Reader )。但是通过 os.Filebody不起作用,而首先将其读入缓冲区可以解决问题:

file, _ := os.Open(filePath)

// request, _ := http.NewRequest("PUT", myURL, file)
// ^^^ why does this not work???

var buf bytes.Buffer
tee := io.TeeReader(file, &buf)
ioutil.ReadAll(tee)
request, _ := http.NewRequest("PUT", myURL, &buf) // this works fine

request.Header.Set("Content-Type", "application/octet-stream")
http.DefaultClient.Do(request)
编辑:问题不是设置 ContentLength header (即它被设置为默认值 0);这导致服务器不处理上传。使用缓冲区时,golang 确实将 header 设置为缓冲区长度,从而导致不同的行为。
ContentLength header 语义服务器依赖??浏览所以我的印象是标题是可选的,这显然不是这里的情况。

最佳答案

此源代码可能会有所帮助。

    // /usr/lib/go/src/net/http/request.go:872
if body != nil {
switch v := body.(type) {
case *bytes.Buffer:
req.ContentLength = int64(v.Len())
buf := v.Bytes()
req.GetBody = func() (io.ReadCloser, error) {
r := bytes.NewReader(buf)
return ioutil.NopCloser(r), nil
}
case *bytes.Reader:
req.ContentLength = int64(v.Len())
snapshot := *v
req.GetBody = func() (io.ReadCloser, error) {
r := snapshot
return ioutil.NopCloser(&r), nil
}
case *strings.Reader:
req.ContentLength = int64(v.Len())
snapshot := *v
req.GetBody = func() (io.ReadCloser, error) {
r := snapshot
return ioutil.NopCloser(&r), nil
}
default:
// This is where we'd set it to -1 (at least
// if body != NoBody) to mean unknown, but
// that broke people during the Go 1.8 testing
// period. People depend on it being 0 I
// guess. Maybe retry later. See Issue 18117.
}
// For client requests, Request.ContentLength of 0
// means either actually 0, or unknown. The only way
// to explicitly say that the ContentLength is zero is
// to set the Body to nil. But turns out too much code
// depends on NewRequest returning a non-nil Body,
// so we use a well-known ReadCloser variable instead
// and have the http package also treat that sentinel
// variable to mean explicitly zero.
if req.GetBody != nil && req.ContentLength == 0 {
req.Body = NoBody
req.GetBody = func() (io.ReadCloser, error) { return NoBody, nil }
}
}

关于go - 来自 golang : upload fails without properly setting ContentLength 文件的 HTTP PUT 请求正文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63821301/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com