我需要读取用户提供的 URL 的响应
我不希望他们通过大文件的链接使我的服务器超载。
我想最多读取 N 个字节,如果还有更多字节要读取,则返回错误。
我可以读取 N 个字节,但是我如何检测该文件不完整(假设远程文件正好是 N 个字节长的极端情况)?
net/http除了彼得的回答之外,软件包中还有一个现成的解决方案http.MaxBytesReader()::
func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser
Run Code Online (Sandbox Code Playgroud)
MaxBytesReader 与 io.LimitReader 类似,但旨在限制传入请求正文的大小。与 io.LimitReader 相比,MaxBytesReader 的结果是 ReadCloser,对于超出限制的 Read 返回非 EOF 错误,并在调用其 Close 方法时关闭底层读取器。
最初它是为了限制传入请求主体的大小而“设计”的,但它也可以用于限制传入响应主体。为此,只需传递nil参数即可ResponseWriter。
使用它的示例:
{
body := ioutil.NopCloser(bytes.NewBuffer([]byte{0, 1, 2, 3, 4}))
r := http.MaxBytesReader(nil, body, 4)
buf, err := ioutil.ReadAll(r)
fmt.Println("When body is large:", buf, err)
}
{
body := ioutil.NopCloser(bytes.NewBuffer([]byte{0, 1, 2, 3, 4}))
r := http.MaxBytesReader(nil, body, 5)
buf, err := ioutil.ReadAll(r)
fmt.Println("When body is exact (OK):", buf, err)
}
{
body := ioutil.NopCloser(bytes.NewBuffer([]byte{0, 1, 2, 3, 4}))
r := http.MaxBytesReader(nil, body, 6)
buf, err := ioutil.ReadAll(r)
fmt.Println("When body is small (OK):", buf, err)
}
Run Code Online (Sandbox Code Playgroud)
输出(在Go Playground上尝试):
When body is large: [0 1 2 3] http: request body too large
When body is exact (OK): [0 1 2 3 4] <nil>
When body is small (OK): [0 1 2 3 4] <nil>
Run Code Online (Sandbox Code Playgroud)