根据 WebSocket RFC ( RFC6455#section-4.2.1 ):
如果服务器在读取握手时发现客户端未发送与以下描述匹配的握手 [...],则服务器必须停止处理客户端的握手并返回带有适当错误代码的 HTTP 响应(例如400 错误请求)。
- 一个 HTTP/1.1 或更高版本的 GET 请求,包括一个“Request-URI”[RFC2616],应该解释为第 3 节中定义的 /resource name/(或包含 /resource name/ 的绝对 HTTP/HTTPS URI)。
[ETC...]
当客户端的握手消息改为指定HTTP/1.0
(或者可能是更低的版本号?)时,我不确定在HTTP/1.1 400 \r\n\r\n
给定其定义(RFC7231#section-6.5.1)的情况下响应是否合适:
400 (Bad Request) 状态码表示服务器不能或不会处理请求,因为某些东西被认为是客户端错误(例如,格式错误的请求语法、无效的请求消息帧或欺骗性请求路由)。
我想HTTP版本号是否太低是否被认为是客户端错误取决于如何解释客户端握手消息:
任何一个...
- 客户端握手消息是一个普通的 HTTP1.1 消息(如果它包含一组特定的 HTTP 标头,可能会导致未来升级到 WebSocket)。
...或者...
- 客户端握手消息实际上不是 HTTP1.1 消息,而是实际上是 WebSocket 标准的一部分并且只是伪装成 HTTP1.1 消息的消息。
如果是后者,状态码 400 是有意义的,因为客户端明显违反了 WebSocket 标准。
如果是前者,则状态码 400 没有意义,因为该消息作为 HTTP 消息是有效的;并且状态码 505 可能更可取:(RFC7231#section-6.6.6)
505(不支持 HTTP 版本)状态码表示服务器不支持或拒绝支持请求消息中使用的 HTTP 主要版本。服务器表示它无法或不愿意使用与客户端相同的主要版本完成请求,如 [RFC7230] 的第 2.6 节所述,除了此错误消息。服务器应该为 505 响应生成一个表示,描述为什么不支持该版本以及该服务器支持哪些其他协议。
再说一次,我不喜欢返回 5XX 类状态代码的想法,因为它或多或少表明服务器因抛出错误而出错......
编辑:正如我在下面的评论中提到的,大部分歧义可能源于我根本不检查客户端是否打算升级到 WebSocket。