【问题标题】:Proper use of HTTP status codes in a "validation" server在“验证”服务器中正确使用 HTTP 状态代码
【发布时间】:2010-09-26 15:09:20
【问题描述】:

在我的应用程序发送到第三方 SOA 服务器的数据中,有复杂的 XML。服务器所有者确实提供了 XML 模式 (.xsd),并且由于服务器拒绝无效的 XML 并发送无意义的消息,因此我需要在发送之前在本地验证它们。

我可以使用独立的 XML 模式验证器,但它们很慢,主要是因为解析模式文件需要时间。因此,我以 HTTP Server 的形式编写了自己的模式验证器(如果需要,用 Java),它缓存已解析的模式。

问题是:在验证过程中,很多事情都可能出错。除了意外异常和成功验证:

  • 服务器可能找不到指定的架构文件
  • 指定的文件可能不是有效的架构文件
  • XML 对架构文件无效

由于它是一个 HTTP 服务器,我想为客户端提供有意义的状态代码。对于上述所有情况,服务器是否应该以 400 错误(Bad request)回答?或者他们与 HTTP 无关,它应该用正文中的消息来回答 200?还有什么建议吗?

更新:主要应用程序是用Ruby编写的,它没有一个好的xml模式验证库,所以单独的验证服务器并没有过度设计。

【问题讨论】:

    标签: xml http validation xsd http-status-codes


    【解决方案1】:

    Status code 422 ("Unprocessable Entity") 听起来很接近:

    “422(Unprocessable Entity)状态码表示服务器理解请求实体的内容类型(因此415(Unsupported Media Type)状态码是不合适的),并且请求实体的语法是正确的(因此400 (Bad Request) 状态码不合适)但无法处理包含的指令。例如,如果 XML 请求正文包含格式正确(即语法正确)但语义错误的 XML 指令,则可能会发生此错误情况。 "

    【讨论】:

    • 请注意,422 是 WebDAV 特定的扩展。 400 状态码会更合适。
    • 它是WebDAV中定义的一个扩展,但仍然是一个通用的HTTP状态码。
    【解决方案2】:

    将验证过程中的错误情况映射到有意义的 HTTP 状态代码是一种完全有效的想法。

    我假设您使用 URI 将 XML 文件作为 POST 内容发送到您的验证服务器以确定特定的验证模式。

    所以这里有一些关于错误映射的建议:

    • 200:XML 内容有效
    • 400:XML 内容格式不正确,标头不一致,请求与 RFC 2616 语法不匹配
    • 401:在缓存中未找到架构,服务器需要凭据用于针对第 3 方 SOA 后端的身份验证才能获取架构文件
    • 404:未找到架构文件
    • 409:XML 内容对指定架构无效
    • 412:指定的文件不是有效的 XMl 架构
    • 500:验证服务器中的任何意外异常(NullPointerExceptions 等)
    • 502:在缓存中找不到架构,尝试从第 3 方 SOA 服务器请求它失败。
    • 503:验证服务器正在重新启动
    • 504:查看 502,原因为超时

    【讨论】:

    • 小心你如何使用像 401、409 和 412 这样的 http 状态——它们在 HTTP 协议中具有特殊的含义,而不是你可以决定在一些通用错误场景中使用的代码,因为你喜欢措辞听起来的方式 :) '422 unprocessable entity' 可能是您正在寻找的通用“虽然它在语法上对其媒体类型有效,但我们无法适应提交的请求实体的语义”@987654321 @
    【解决方案3】:

    假设您将 XML 文件发布到资源,例如:

    POST /验证器 内容类型:application/xml

    如果请求实体未能解析为其提交的媒体类型(即应用程序/xml),则 400 Bad Request 是正确的状态。

    如果它在语法上解析为它提交的媒体类型,但它没有针对某些所需的架构进行验证,或者具有使其提交到的资源无法处理的语义 - 那么 422 Unprocessable Entity 是最佳状态(尽管您可能应该在错误响应中附带一些更具体的错误信息;另请注意,它在技术上是在 HTTP 的扩展 WebDAV 中定义的,尽管它在 HTTP API 中被广泛使用,并且比任何其他 HTTP 错误状态都更合适当提交的实体出现语义错误时)。

    如果它是作为媒体类型提交的,这意味着 xml 之上的特定架构(例如 application/xhtml+xml),那么如果它无法针对该架构进行验证,您可以使用 400 Bad Request。但是,如果它的媒体类型是纯 XML,那么我认为架构不是媒体类型的一部分,尽管它有点灰色地带;如果 xml 文件指定了它的架构,您可能会将验证解释为 application/xml 语法要求的一部分。

    如果您通过 multipart/form 或 application/x-www-form-urlencoded 表单提交来提交 XML 文件,那么您必须使用 422 Unprocessable Entity 来解决 XML 文件的所有问题;仅当基本表单上传存在语法问题时,400 才适用。

    【讨论】:

      【解决方案4】:

      Amazon 可以用作如何将 http 状态代码映射到实际应用程序级别条件的模型: http://docs.amazonwebservices.com/AWSImportExport/latest/API/index.html?Errors.html(请参阅 Amazon S3 状态代码标题)

      【讨论】:

        【解决方案5】:

        来自 w3c: 400 = 由于语法错误,服务器无法理解请求。

        除非服务器实际上无法理解请求,否则我不会提供该服务。如果您只是获得无效的 xml,请提供 200 并解释为什么事情不起作用。

        问候 假的

        【讨论】:

          【解决方案6】:

          我会使用400 Bad request 并在正文中添加更具体的消息(可能在标题中带有辅助错误代码,例如X-Parse-Error: 10451 以便于处理)

          【讨论】:

            【解决方案7】:

            这听起来是个好主意,但 HTTP 状态代码并没有真正提供“操作失败”的情况。我将返回带有X-Validation-Result: true/false 标头的HTTP 200,必要时使用正文作为任何文本或“原因”。将 HTTP 4xx 保存为 HTTP 级错误,而不是应用程序级错误。

            不过,这是一种耻辱和双重标准。许多应用程序使用 HTTP 身份验证,它们能够从应用程序级别返回 HTTP 401 Not Authorized 或 403 Forbidden。拥有某种可以使用的全面的 HTTP 4xx Request Rejected 会很方便且明智。

            【讨论】:

            • 如果你 200 和一个额外的成功标头,你正在通过 HTTP 隧道协议,而不是正确使用 HTTP。不要那样做。
            猜你喜欢
            • 2018-09-24
            • 1970-01-01
            • 1970-01-01
            • 2020-04-05
            • 2012-12-13
            • 1970-01-01
            • 2014-12-20
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多