webserver的http实现

1、用了状态机,为什么要用状态机?
在逻辑处理模块中,响应的http请求采用主从状态机完成,
传统的控制流程都是按照顺序执行的,状态机能够处理任意顺序的事件,并能提供有意义的响应--即使这些事件发生的顺序和预计的不同。
项目中使用主从状态机的模式进行解析, 从状态机负责读取报文的一行,主状态机负责对该行数据进行解析,主状态机内部调用从状态机,从状态机驱动主状态机。
每解析一部分都会将整个请求的check_state状态改变,状态机也就是根据这个状态来进行不同部分的解析跳转的。
2、状态机的转移图画一下
1、主状态机的三种状态,标志解析位置
    REQUESTLINE,解析请求行
    HEADER,解析请求头
    BODY,解析消息体,仅用于解析POST请求
2、从状态机的状态,标识解析一行的读取状态
    ParseRequestLine,完整读取一行,该条件涉及解析请求行和请求头部
    ParseHeader,报文语法有误
   ParseBody,读取的行不完整
3、处理结果
NO_REQUEST:请求不完整,需要继续读取请求报文数据
GET_REQUEST 获得了完整的HTTP请求
BAD_REQUEST HTTP请求报文有语法错误
INTERNAL_ERROR 服务器内部错误
3、状态机的缺点是什么?
状态机的缺点就是 性能比较低 ,一般一个状态做一个事情,性能比较差,在追求高性能的场景下一般不用,高性能场景一般使用 流水线设计。
4、get和post的区别
get主要用来获取数据,而post是提交或修改数据;
get有长度限制(2048字节)而post没有;
get的参数是显式的,get的参数会附加在url之 中,以 “ ? “分割url和传输数据,多个参数用 “&”连接;而post是隐式的,post是放在请求体中;
get请求会保存在浏览器历史记录中,也可以保存在web服务器日志中;
get在浏览器回退时是无害的,而post会再次提交请求;
get请求只能进行url编码,而post支持多种编码方式;
get请求的参数数据类型只接受ASCII字符,而post没有限制。
5、http请求怎么拆包?
HTTP请求内容:请求行,请求头,空行,请求体
一个有报文的请求到服务器时,请求头里都会有content_length,这个指定了报文的大小。报文如果很大的时候,会通过一部分一部分的发送请求,直到结束。当这个过程中,出现多个请求,第一个请求会带有请求头信息,前面一个请求的发送的报文如果没有满时,会把后面一个请求的内容填上,这个操作就叫 粘包 。这样粘包后, 它会通过content_length字段的大小,来做拆包。
在post发送大数据量时会分段发,接收端一次接收的只是部分post, 源代码读到len=-1直接开始处理了 ,但实际上还有数据没发过来,在process内判断buffer收到的len和header中的content-length是否匹配,如果不匹配直接返回false,下一个post包发过来接着用buffer收,最后收完了再开始request处理。
6、HTTP的整体流程
浏览器发出http连接请求,主线程创建http对象接收请求同时将所有数据存到对应的buffer,将该对象插入任务队列,工作线程从任务队列中取出一个任务进行处理。
工作线程取出任务后,调用process_read函数,通过主从状态机对请求报文进行解析。
解析完成后,跳转do_request函数生成响应报文,通过process_write写入buffer,返回给浏览器端。
注意:在生成的响应报文中并没有返回消息的具体内容,文件也并不在缓冲区,因此传输的时候采取分块写的方式,一块传输buff里面的内容,另一块传输内存映射的文件指针。
7、报文解析的整体流程
1、利用search从缓冲区读取响应的报文片段。
2、建立请求报文的有限状态机,请求报文中一般包含post和get。该有限状态机的作用原理在于每次读取缓冲区中的一行进行匹配,直到状态变为finish。
REQUEST_LINE——ParseRequestLine_(line)
HEADERS——ParseHeader_(line)
BODY——ParseBody_(line)
调用ParsePost();,因为只有post中有请求体
1. 解析 POST 请求 :检查请求方法和  Content-Type  是否符合条件。
2. 解析表单数据 :从 URL 编码的请求体中提取用户提交的数据。
cpp /*URL 编码 是一种用于将数据编码为有效 URL 字符串的方式,其中特殊字符(如空格、&、= 等)会被替换为特定的字符序列: *空格编码为 %20 *特殊字符(如 &, =)不会直接出现在值中,而需要进行编码 *其他特殊字符也会有类似的编码方式,如 %3A 表示冒号 :
3. 路径判断 :检查路径是否是需要处理的特定页面(如登录或注册页面)。
4. 登录或注册逻辑 :根据路径进行用户验证,判断是登录还是注册,并根据结果决定跳转的页面。
8、报文响应的流程(httpresponse):
httprequest是对读取缓冲区中的可读数据进行解析,
httpresponse是对缓冲区中的可写数据进行写入。
响应报文的四个部分:
9、buffer缓冲区总结:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/949112.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Uniapp Android 本地离线打包(详细流程)

一、简介 App 离线 SDK 暂时不支持 Kotlin,未来不清楚。 uniapp 提供了 云打包 与 本地打包 两种方案,云打包 需要排队且还有次数限制,本地打包 则就没有这些限制,而且会 本地打包 对开发 原生插件 有很大的帮助。 细节&#x…

记录一次电脑被入侵用来挖矿的过程(Trojan、Miner、Hack、turminoob)

文章目录 0、总结1、背景2、端倪3、有个微软的系统更新,就想着更新看看(能否冲掉问题)4、更新没成功,自动重启电脑5、风险文件(好家伙命名还挺规范,一看名字就知道出问题了)6、开机有一些注册表…

使用大语言模型的生物嵌入,后续应该会有很多类似文章出来!

生信碱移 语言模型嵌入 小编先前分享了使用ChatGPT基因嵌入做平替的顶刊文章GenePT,只需要在原本的领域工作上插入这类的GPT嵌入,就能够实现降维打击。 ▲ 对于GenePT或者嵌入感兴趣的铁子,可以点击查看上面这篇推文。 今天冲浪的时候又看…

如何在没有 iCloud 的情况下将联系人从 iPhone 传输到 iPhone

概括 近期iOS 13.5的更新以及苹果公司发布的iPhone SE在众多iOS用户中引起了不小的轰动。此外,不少变化,如暴露通知 API、Face ID 增强功能以​​及其他在 COVID-19 期间与公共卫生相关的新功能,吸引了 iPhone 用户尝试新 iPhone 并更新到最…

GitLab集成Runner详细版--及注意事项汇总【最佳实践】

一、背景 看到网上很多用户提出的runner问题其实实际都不是问题,不过是因为对runner的一些细节不清楚导致了误解。本文不系统性的介绍GitLab-Runner,因为这类文章写得好的特别多,本文只汇总一些常几的问题/注意事项。旨在让新手少弯路。 二、…

【从零开始入门unity游戏开发之——C#篇40】C#特性(Attributes)和自定义特性

文章目录 前言一、特性(Attributes)基本概念二、自定义特性1、自定义特性代码示例:2、应用自定义特性:3、解释3.1 **AttributeUsage 特性**3.2 特性的命名3.3 **构造函数**:3.4 **属性**: 4、使用反射获取特…

k8s基础(2)—Kubernetes-Namespace

一、Namespace概述 名字空间 在 Kubernetes 中,名字空间(Namespace) 提供一种机制,将同一集群中的资源划分为相互隔离的组。 同一名字空间内的资源名称要唯一,但跨名字空间时没有这个要求。 名字空间作用域仅针对带有…

iOS 逆向学习 - iOS Security Features:硬件与软件多重防护体系

iOS 逆向学习 - iOS Security Features:硬件与软件多重防护体系 iOS 安全特性全面解析:构筑多层次防御体系一、iOS 的硬件安全特性1. Secure Enclave(安全隔区)2. Hardware Root of Trust(硬件信任根)3. De…

计算机网络——数据链路层-流量控制和可靠传输

一、流量控制 流量控制是指由接收方及时控制发送方发送数据的速率,使接收方来得及接受。 • 停止等待流量控制 • 滑动窗口流量控制 1、停止—等待流量控制 停止-等待流量控制的基本原理是发送方每发出一帧后,就要等待接收方的应答信号&#xff…

Zookeeper是如何保证事务的顺序一致性的?

大家好,我是锋哥。今天分享关于【Zookeeper是如何保证事务的顺序一致性的?】面试题。希望对大家有帮助; Zookeeper是如何保证事务的顺序一致性的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Zookeeper 通过多个机制来保证事务的顺序一…

实际开发中,常见pdf|word|excel等文件的预览和下载

实际开发中,常见pdf|word|excel等文件的预览和下载 背景相关类型数据之间的转换1、File转Blob2、File转ArrayBuffer3、Blob转ArrayBuffer4、Blob转File5、ArrayBuffer转Blob6、ArrayBuffer转File 根据Blob/File类型生成可预览的Base64地址基于Blob类型的各种文件的下载各种类型…

Qt使用CMake编译项目时报错:#undefined reference to `vtable for MainView‘

博主将.h文件和.cpp文件放到了不同的文件目录下面,如下图所示: 于是构建项目的时候就报错了#undefined reference to vtable for MainView,这个是由于src/view目录下的CMake无法自动moc头文件导致的,需要手动moc include/view目录…

会员制电商创新:开源 AI 智能名片与 2+1 链动模式的协同赋能

摘要:本文聚焦于电商领域会员制的关键作用,深入探讨在传统交易模式向数字化转型过程中,如何借助开源 AI 智能名片以及 21 链动模式商城小程序,实现对会员数据的精准挖掘与高效利用,进而提升企业的营销效能与客户洞察能…

第27周:文献阅读及机器学习

目录 摘要 Abstract 一、文献阅读 发现问题 研究方法 CNN-LSTM DT SVR 创新点 案例分析 数据准备 模型性能 预测模型的实现 仿真实验及分析 二、LSTM 1、基本结构 2、具体步骤 3、举例说明 4、原理理解 总结 摘要 本周阅读文献《Short-term water qua…

【机器遗忘之UNSIR算法】2023年IEEE Trans期刊论文:Fast yet effective machine unlearning

1 介绍 年份:2023 期刊:IEEE Transactions on Neural Networks and Learning Systems 引用量:170 Tarun A K, Chundawat V S, Mandal M, et al. Fast yet effective machine unlearning[J]. IEEE Transactions on Neural Networks and Le…

Linux-----进程处理(waitpid,进程树,孤儿进程)

目录 waitpid等待 进程树 孤儿进程 waitpid等待 Linux中父进程除了可以启动子进程,还要负责回收子进程的状态。如果子进程结束后父进程没有正常回收,那么子进程就会变成一个僵尸进程——即程序执行完成,但是进程没有完全结束,其…

Docker- Unable to find image “hello-world“locally

Docker- Unable to find image “hello-world“locally 文章目录 Docker- Unable to find image “hello-world“locally问题描述一. 切换镜像1. 编辑镜像源2. 切换镜像内容 二、 检查设置1、 重启dockers2、 检查配置是否生效3. Docker镜像源检查4. Dokcer执行测试 三、自定义…

Android配件应用默认启动与USB权限申请区别

使用效果: USB配件授权演示 选择USB配件默认打开应用 申请USB配件使用权限

vue2框架配置路由设计打印单

业务效果: 查询出列表后&#xff0c;点击申请单按钮&#xff0c;弹出申请表格&#xff0c;可进行打印 后端实现 控制器、服务层等省略&#xff0c;关联查出数据提供接口给前端即可 <!--获取详细信息(用于申请单打印)--><select id"selectXxxxDetail" par…