【问题标题】:HTTP/1.1 426 Upgrade Required需要 HTTP/1.1 426 升级
【发布时间】:2017-07-08 13:07:00
【问题描述】:

当尝试连接到本地主机(使用终端)时,我得到了这个答案:

HTTP/1.1 426 需要升级
服务器:WebSocket++/0.3.0-alpha4

我该如何回应升级?

【问题讨论】:

  • 请求到底是什么?响应是否带有响应正文?
  • 您好 Julian,我正在尝试连接到 localhost 以运行应用程序。我使用命令行 "netstat -atp tcp | grep -i "listen" 来确定我应该使用哪个端口号,并且终端返回了几个本地主机监听。我使用 curl -v localhost:[NUMBER] 并且我尝试返回的第一个本地主机号消息:

标签: http websocket terminal server upgrade


【解决方案1】:

您显然是连接到 WebSocket 服务器,而不是普通的 HTTP 服务器

服务器:WebSocket++/0.3.0-alpha4

WebSocket protocol 以基于 HTTP 的请求/响应握手开始,客户端请求服务器允许将通信升级为全双工 WebSocket 消息传递。

426 响应意味着初始握手未请求正确的 WebSocket 升级。每RFC 6455 Section 4.1 Client Requirements:

一旦与服务器建立连接(包括通过代理或通过 TLS 加密隧道的连接),客户端必须向服务器发送打开握手。握手包括一个 HTTP 升级请求,以及一个必需和可选的头字段列表。这次握手的要求如下。

  1. 握手必须是 [RFC2616] 指定的有效 HTTP 请求。

  2. 请求的方法必须是 GET,并且 HTTP 版本必须至少为 1.1。

For example, if the WebSocket URI is "ws://example.com/chat", the first line sent should be "GET /chat HTTP/1.1".
  1. 请求的“Request-URI”部分必须匹配第 3 节中定义的 /resource name/(相对 URI),或者是绝对的 http/https URI,在解析时具有 /resource name/,/ host/ 和 /port/ 匹配对应的 ws/wss URI。

  2. 请求必须包含一个 |Host|头字段,其值包含 /host/ 加上可选的 ":" 后跟 /port/(不使用默认端口时)。

  3. 请求必须包含 |Upgrade|其值必须包含“websocket”关键字的标头字段。

  4. 请求必须包含一个 |Connection|其值必须包含“升级”令牌的标头字段。

  5. 请求必须包含一个名为 |Sec-WebSocket-Key| 的头域。这个头域的值必须是一个随机数,由一个随机选择的 16 字节值组成,该值已经过 base64 编码(参见 [RFC4648] 的第 4 节)。必须为每个连接随机选择随机数。

NOTE: As an example, if the randomly selected value was the sequence of bytes 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10, the value of the header field would be "AQIDBAUGBwgJCgsMDQ4PEC=="
  1. 请求必须包含一个标题字段,其名称为 |Origin| [RFC6454] 如果请求来自浏览器客户端。如果连接来自非浏览器客户端,如果该客户端的语义与此处描述的浏览器客户端用例相匹配,则请求可以包含此标头字段。此标头字段的值是建立连接的代码正在运行的上下文的 ASCII 序列化。有关如何构造此标头字段值的详细信息,请参阅 [RFC6454]。
As an example, if code downloaded from www.example.com attempts to establish a connection to ww2.example.com, the value of the header field would be "http://www.example.com".
  1. 请求必须包含一个名为 |Sec-WebSocket-Version| 的标头字段。此标头字段的值必须为 13。
NOTE: Although draft versions of this document (-09, -10, -11, and -12) were posted (they were mostly comprised of editorial changes and clarifications and not changes to the wire protocol), values 9, 10, 11, and 12 were not used as valid values for Sec-WebSocket-Version.  These values were reserved in the IANA registry but were not and will not be used.
  1. 请求可以包含一个名为 |Sec-WebSocket-Protocol| 的头域。如果存在,此值指示客户端希望发言的一个或多个逗号分隔的子协议,按偏好排序。组成该值的元素必须是非空字符串,其字符范围为 U+0021 到 U+007E,不包括 [RFC2616] 中定义的分隔符,并且必须都是唯一字符串。该头域的值的 ABNF 是 1#token,其中结构和规则的定义在 [RFC2616] 中给出。

  2. 请求可以包含一个名为 |Sec-WebSocket-Extensions| 的头域。如果存在,此值指示客户端希望发言的协议级扩展。这个头域的解释和格式在第 9.1 节中描述。​​

  3. 请求可以包含任何其他头字段,例如,cookie [RFC6265] 和/或身份验证相关的头字段,例如 |Authorization|标头字段 [RFC2616],根据定义它们的文档进行处理。

一旦发送了客户端的打开握手,客户端必须等待服务器的响应,然后再发送任何进一步的数据。

客户端必须按如下方式验证服务器的响应:

  1. 如果从服务器接收到的状态码不是 101,客户端会按照 HTTP [RFC2616] 程序处理响应。特别是,如果客户端收到 401 状态码,它可能会执行身份验证;服务器可能会使用 3xx 状态码重定向客户端(但客户端不需要跟随它们)等。否则,请执行以下操作。

  2. 如果响应缺少 |Upgrade|标头字段或 |Upgrade|标头字段包含的值不是与值“websocket”匹配的不区分大小写的 ASCII 值,客户端必须WebSocket 连接失败

  3. 如果响应缺少 |Connection|头域或|Connection|标头字段不包含与值“Upgrade”匹配的不区分大小写的 ASCII 标记,客户端必须WebSocket 连接失败

  4. 如果响应缺少 |Sec-WebSocket-Accept|标头字段或 |Sec-WebSocket-Accept|包含 |Sec-WebSocket-Key| 连接的 base64 编码 SHA-1 以外的值(作为字符串,未经过 base64 解码)与字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”但忽略任何前导和尾随空格,客户端必须WebSocket 连接失败

  5. 如果响应包含 |Sec-WebSocket-Extensions|标头字段,并且此标头字段指示使用了客户端握手中不存在的扩展(服务器已指示客户端未请求的扩展),客户端必须WebSocket 连接失败。 (第 9.1 节讨论了对该头字段的解析以确定请求哪些扩展。)

  6. 如果响应包含 |Sec-WebSocket-Protocol|标头字段,并且此标头字段指示使用了客户端握手中不存在的子协议(服务器已指示客户端未请求的子协议),客户端必须WebSocket 连接失败

如果服务器的响应不符合本节和第 4.2.2 节中定义的服务器握手要求,则客户端必须WebSocket 连接失败

请注意,根据 [RFC2616],所有头域名称在 HTTP 请求和 HTTP 响应都不区分大小写。

如果服务器的响应按照上述规定进行验证,则表示WebSocket 连接已建立,并且 WebSocket 连接处于 OPEN 状态。

【讨论】:

    猜你喜欢
    • 2021-10-24
    • 1970-01-01
    • 2019-07-29
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-21
    • 1970-01-01
    相关资源
    最近更新 更多