之前两次singnalr、 websocket实时推送相关:

tag: 浏览器--->nginx--> server

其中提到nginx默认不会为客户端转发UpgradeConnection标头, 因为为了让被代理的后端服务器知道客户端要升级协议,故要在nginx上显式转发标头:

location /realtime/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}

事情本该就就这么简单, 但devops总会有各种奇怪的姿势。

小动作引起的头脑风暴

但是运维在给nginx配置的时候,给/根路径配置了webcoket协议升级标头。

按照字面理解,导致所有的客户端转发请求都在要求切换到websocket协议,但是除了/chat路径, 服务器其他http路径并没有做websocket协议的逻辑,其他http请求是不是都该报错了。

是实际看,所有的请求(websocket、http)都没有报错,都按照指定预期返回。

刨一下

利用asp.netcore默认脚手架项目:

已知http://localhost:5000/WeatherForecast是http请求,返回一大坨json数据;

WeatherForecast添加断言日志:

模拟ops的错配效果,我们给这个请求添加websocket协议升级标头。

第一次:curl 'http://localhost:5000/WeatherForecast' -H 'Upgrade: websocket' -H 'Connection: Upgrade' --verbose,正常返回大坨json数据。

日志记录:

 该请求是不是webcocket请求:False,headers:[Accept, */*], [Connection, Upgrade], [Host, localhost:5000], [User-Agent, curl/7.79.1], [Upgrade, websocket]

以上说明,服务端并不认为是websocket请求, 这也印证了ops虽然错配,但对于常规的http请求没造成影响。

那服务端到底是怎么认定websocket请求?

服务端认定websocket请求的源码

依次判断;

  • HttpMethod: GET
  • Sec-WebSocket-Version标头==13
  • Connection标头==Upgrade
  • Upgrade标头==websocket
  • 有效的Sec-WebSocket-Key标头

这样我们就明白了,虽然websocket协议基于http,添加了httpConnectionUpgrade标头,但是浏览器实际会给我们带上Sec-WebSocket-KeySec-WebSocket-Version标头,以向服务器证明这是一个有效的websocket握手。

于是我们可以使用

curl 'http://localhost:5000/WeatherForecast' -H 'Upgrade: websocket' -H 'Connection: Upgrade' -H 'Sec-WebSocket-Version: 13' -H 'Sec-webSocket-Key: eeZn6lg/rOu8QbKwltqHDA==' --verbose 仿造客户端websocket请求。

日志记录:

该请求是不是webcocket请求:True,headers:[Accept, */*], [Connection, Upgrade], [Host, localhost:5000], [User-Agent, curl/7.79.1], [Upgrade, websocket], [Sec-WebSocket-Version, 13], [Sec-WebSocket-Key, eeZn6lg/rOu8QbKwltqHDA==]

对于这个websocket请求,服务端还是按照http代码逻辑返回200ok和JSON数据,从这个层面上看,http协议是兼容websocket的。

真正要让服务端按照websocket姿势, 要使用HttpContext.WebSockets.AcceptWebSocketAsync()告知客户端开始切换协议,并在原tcp上发起全双工通信。

前后对比, 困惑得解: 虽然nginx为http请求转发了ConnectionUpgrade标头, 但是服务器并不认可这是websocket升级协议,认为是携带了特殊标头的http请求,走原来的http业务处理逻辑是没有问题的。

总结

  1. 本文记录了nginx在转发websocket请求时要添加的配置
  2. websocket以http协议为蓝本,添加了特定的htp标头来要求切换协议;为了与常规http区分,浏览器自动增加了Sec-websocket-key等标头, 让服务端认为这是一个有效的websocket请求。

如何仿造websocket请求?的更多相关文章

  1. HttpLitener处理http请求和Websocket请求

    HttpLitener处理http请求和Websocket请求的案例具体步骤如下 1.新建控制台项目TestClientWebsocket 2.选择项目右键添加类HttpAndWebsocket,代码 ...

  2. JAVA获得websocket请求路径前缀

    /** * 获得websocket请求路径前缀(线程安全 速度相对慢) * @param request * @return */ public static String getWebsocketU ...

  3. 火币网API文档——Websocket 请求与订阅示例

    1. 访问地址 Pro 站行情请求地址为:wss://api.huobipro.com/ws HADAX 站行情请求地址为:wss://api.hadax.com/ws 2. 数据压缩 WebSock ...

  4. WebSocket请求过程分析及实现Web聊天室

    WebSocket协议是基于TCP的一种新的协议.WebSocket最初在HTML5规范中被引用为TCP连接,作为基于TCP的套接字API的占位符.它实现了浏览器与服务器全双工(full-duplex ...

  5. 用python实现websocket请求遇到的问题及解决方法。

    想要实现python的ws库功能,实时获取对方服务器ws协议返回的数据,查了下百度,用如下流程: ws = create_connection("wss://ws.xxxxxxx.info/ ...

  6. Django配置websocket请求接口

    1.settings.py INSTALLED_APPS = [ '...', 'channels', '...', ] ASGI_APPLICATION = 'server.routing.appl ...

  7. HTTPS请求HTTP接口被浏览器阻塞,python实现websocket客户端,websocket服务器,跨域问题,dwebsocket,https,拦截,服务端

    HTTPS请求HTTP接口被浏览器阻塞,python实现websocket客户端,websocket服务器,跨域问题,dwebsocket,https,拦截,服务端 发表时间:2020-03-05 1 ...

  8. WebSocket - ( 一.概述 )

    说到 WebSocket,不得不提 HTML5,作为近年来Web技术领域最大的改进与变化,包含CSS3.离线与存储.多媒体.连接性( Connectivity )等一系列领域,而即将介绍的 WebSo ...

  9. 借助Nodejs探究WebSocket

    文章导读: 一.概述-what's WebSocket? 二.运行在浏览器中的WebSocket客户端+使用ws模块搭建的简单服务器 三.Node中的WebSocket 四.socket.io 五.扩 ...

随机推荐

  1. linux篇-tomcat:Cannot find /usr/local/tomcat1/bin/setclasspath.sh

    首先看下报错代码: Cannot find /usr/local/tomcat1/bin/setclasspath.sh This file is needed to run this program ...

  2. Git标签用法

    我们通常会在项目开发到一定阶段时给代码打上标签. 1.Git查看所有标签及其描述信息 git tag -l -n 2.Git创建标签 创建标签并添加描述信息 git tag -a v1.0.0 -m ...

  3. Spark——Standalone 环境安装及简单使用

    Standalone 环境安装 将 spark-3.0.0-bin-hadoop3.2.tgz 文件解压缩在指定位置(/opt/module) tar -zxvf spark-3.0.0-bin-ha ...

  4. 个人冲刺(七)——体温上报app(二阶段)

    冲刺任务:完成特殊情况功能 MoreActivity.java package com.example.helloworld; import android.content.Intent; impor ...

  5. systemctl设置程序开机启动、关闭、启用/禁用服务以vsftpd为例

    参考:https://blog.csdn.net/qq_29663071/article/details/80814081 systemctl是RHEL 7 的服务管理工具中主要的工具,它融合之前se ...

  6. SRE,了解一下?35+岁程序员新选择

    摘要:随着云业务的发展,今后会有越来越多的工程师深入到SRE领域. 本文分享自华为云社区<浅谈SRE角色认知>,作者: SRE确定性运维. 一.什么是SRE? SRE(Site Relia ...

  7. 2.C++标准库函数:getline函数 定界流输入截取函数 -windows编程

    引言:今天工作遇到了一个需要按行读取txt文件数据的需求,查询了一下getline()函数,发现这竟然是一个C++的标准库函数,而且设计的很好,特地做一下记录.getline本质是一个定界流输入截取函 ...

  8. React项目中 使用 CSS Module

    安装react-app-rewired 由于新的 react-app-rewired@2.x 版本的关系,还需要安装 customize-cra.但是我们这里不需要安装 react-app-rewir ...

  9. Vue回炉重造之搭建考试答卷系统

    本篇章主要讲述系统搭建逻辑,有疑问的可以加微信联系我.考试系统 资源 Vue.js Element UI 第三方数据接口 业务 答题过程中,防止用户中途退出或者其他不可抗力因素阻碍答题,在每次选择都要 ...

  10. SAP BPC 开发日记

    1.获取维度模型的方法1 DATA:i_appset_id TYPE uj_appset_id,     i_appl_id   TYPE uj_appl_id.i_appset_id = 'SINO ...