【问题标题】:Why couldn't Go read a request properly?为什么 Go 不能正确读取请求?
【发布时间】:2015-07-12 08:27:07
【问题描述】:

我的 API 需要解析传入的请求。第一步,需要通过ioutil包的Go的ReadAll()函数读取数据。为什么会出现错误?

official documentation 没有给出提示,因为没有描述此类错误的原因。

func ParseRequest(w http.ResponseWriter, r *http.Request) {
    body, err := ioutil.ReadAll(r.Body)

    if err != nil {
        // handle the error
    }
}

【问题讨论】:

  • 为什么正文不能读取?它不是有效的 JSON 吗?服务器代码是否包含错误?
  • 这样的事情不太可能发生,但如果没有原因,Go 的标准库不会提供错误作为潜在的返回值,正如您在 official docs 中看到的那样。

标签: go http-status-codes standard-library


【解决方案1】:

ioutil.ReadAll 失败的原因有很多。它能够读取任何io.Reader,而不仅仅是 HTTP 请求正文。而Request.Body 只是一个io.ReadCloser。对我来说,生成一个与网络套接字以外的东西相关联的东西是完全合法的(我一直对 http 做这些事情来构建代理和隧道协议)。

很明显,许多io.Reader 事件可能会出现错误(例如,您可能无法访问文件,或者磁盘可能在读取过程中被卸载)。特定于 HTTP,您可能会遇到类似的网络故障错误。如果网络套接字在读取请求正文的中途收到一个 RST 数据包,您会发生什么?

不过,最终你应该明白的一点是你必须处理错误,因为Reader 接口会产生错误。不要假设该接口是如何实现的。

【讨论】:

  • 感谢您的解释。发送客户端会导致任何错误吗?我问是因为我想实现一个 API 并想返回一个 http 状态码。
  • 我不确定你的意思。状态码不是错误;它只是一个整数。如果你问是否可以设置状态码,那就是ResponseWriter.WriteHeader()
  • 如果ReadAll返回错误,我想返回一个http状态码。但是正确的状态码是什么?由客户端引起的内部服务器错误 (500) 或错误请求 (400)。
  • 感谢您的帮助。这就是我终于想知道的:)
  • 另一个故障点可能是当您的r.Body 被包装时,例如,数据解压缩器 - 如果流不是有效的(例如)gzip,它会失败。为此,最好发送 400。
【解决方案2】:

如果客户端确实发送了无效的 JSON,那是客户端的错误:400 Bad Request

如果 JSON 有效但服务器代码包含错误,则为服务器故障:500 Internal Server error

【讨论】:

  • 在验证 JSON 之前,我需要使请求可读之后将发送 404 状态。我不认为 Go 标准库会包含这样的错误,所以它不太可能是服务器的错误。去的包裹。这个问题,为什么函数会返回错误,仍然悬而未决。
  • 我说的不是 404,而是 400。顺便说一句:您的问题是关于 REST 和 API 还是关于 Go 实现?
  • 为什么会在Go中包含这样的错误以及可能导致它的原因,将回答有关状态码的问题。所以它会专注于 Go 的实现。我在验证过程中出现了 400 错误。我的错。
  • 那么请编辑您的问题以使其更清楚。
  • 我更新了问题并删除了其余的api部分。
猜你喜欢
  • 2019-12-16
  • 1970-01-01
  • 2023-02-09
  • 1970-01-01
  • 1970-01-01
  • 2020-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多