HTTP协议讲解

前瞻:


认识URL
  


1.ip+port
2.平时上网,就是进程间通信
3.上网行为,1.获取资源 2.上传数据 相当于I/O
4.http协议采用tcp协议
网页 图片 音乐其实都是资源

Http请求
  
  
http request
  


Method:Get/Post
资源/路径:网页 图片 视频资源的路径
版本:http/1.0 短连接  http/1.1(主流) 长连接 基于一条连接发送许多请求

http如何读到完整的报文
a.一直读直到读到空行 分离报文和有效载荷
b.Content-Length:XXX——表示正文部分的长度  读到Content则正文有数据
如何对http进行反序列化   根据/r/n

http response
  

状态码:200 表示成功
         404 代表资源无法找到
  

请求行的内容
method url http_version    
在使用 std::stringstream 进行输入操作时,默认情况下是以空格作为分隔符的
此时可以将他们提取出来

 

`std::stringstream` s1;s1>>_method>>_url>>_http_version


资源url路径
要访问资源所在的路径

如何理解web根目录 /
可以将url中/提取出来,再识别成./wwwroot + firstpage 这样/访问就是访问首页
Content-Type:表示正文类型
  
a.你要求的所有资源都有资源类型
b.http response给浏览器响应的时候,会自动去识别资源类型去读取资源
所以我们没对资源进行访问时,都要有suffix后缀提供给浏览器识别读取


例如:
HTTP 请求或响应的 Content-Type 通常用于指定传输的数据类型。常见的 Content-Type 值:
text/html:HTML 文档

JPG 图像文件的 Content-Type 是:
image/jpeg
我们将suffix转换成shuffix后缀再交给responsecontent    
  
工具:Fiddler

请求方法GET/POST
上网行为
我们获取资源
我们向服务器传参 登陆 注册 搜索 POST+ 利用html的表单

GET:既可以获取资源也可以上传参数
POST:上传

request and response

#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
using namespace std;
const string httpSep = "\r\n";
const string firstpagepath="firstpage.html";
const string workroot="./wwwroot";
const string spaceseq=" ";
class Request
{
public:Request() : _blank_line(httpSep),_path(workroot){}bool GetLine(string &response, string *line){int pos = response.find(httpSep);if (pos == string::npos)return false;*line = response.substr(0, pos);response.erase(0, pos + httpSep.size());return true;}void Deserialize(string &response){string line;if (!GetLine(response, &line))return;_statu_line = line;while (true){string line;bool ok = GetLine(response, &line);if (ok && !response.empty()) //_vec_line{_vec_header.push_back(line);continue;}else if (ok && response.empty()){_req_content = line;break;}else{break;}}}void Parse_statu_line(){std::stringstream s1(_statu_line);s1>>_method>>_url>>_http_version;if(_url=="/"){_path+=_url+firstpagepath;}else{_path+=_url;}}void Parse_suffix_type(){int pos=_path.find('.');if(pos==string::npos) {_suffix=".html";}_suffix=_path.substr(pos);}std::string GetFileContentHelper(const std::string &path){//文本// std::ifstream in(path, std::ios::binary);// if (!in.is_open())//     return "";// std::string content;// std::string line;// while(std::getline(in, line)) // BUG// {//     content += line;// }// in.close();// return content;std::ifstream in(path, std::ios::binary);if (!in.is_open())return "";in.seekg(0, in.end);int filesize = in.tellg();in.seekg(0, in.beg);std::string content;content.resize(filesize);in.read((char *)content.c_str(), filesize);// std::vector<char> content(filesize);// in.read(content.data(), filesize);in.close();return content;}void Parse(){Parse_statu_line();Parse_suffix_type();}void RequestDebug(){cout << "_statu_line:" << _statu_line << endl;for (auto &e : _vec_header){cout << "---->" << e << endl;}cout << "_blank_line" << _blank_line << endl;cout << "_req_content:" << _req_content;}~Request() {}string& Path(){return _path;}string& Suffix(){return _suffix;}
private:string _statu_line;vector<string> _vec_header;string _blank_line;string _req_content;string _method;string _url;string _http_version;string _path;string _suffix;
};
class Response{//"Http/1.0 200 ok\r\n";public:Response():_http_version("Http/1.0"){}bool SetCode(int code){_code=to_string(code);}string ret_code(){return _code;}bool SetCodeDesc(const string  codedesc){if(codedesc.empty()) return false;_code_desc=codedesc;return true;}void make_statu_line(){_statu_line=_http_version+spaceseq+_code+spaceseq+_code_desc+"\r\n";}void head_push(string line){_head_vector.push_back(line);}void Set_content(string content){_rescontent=content;}string serialize(){string retmesaage("");retmesaage+=_statu_line;for(auto & e: _head_vector){retmesaage+=e;}retmesaage+=_rescontent;return retmesaage;}private:string _statu_line;vector<string> _head_vector;string _rescontent;string _http_version;string _code;string _code_desc;};

main.cc

#include"TcpServer.hpp"
#include"HttpProtocol.hpp"
using namespace  std;
using namespace NET_work;
void Usage(std::string proc)
{std::cout << "Usage : \n\t" << proc << "local_port\n"<< std::endl;
}
string _to_httptype(string type)
{if (type == ".html" || type== ".html")return "text/html";else if (type == ".png")return "image/png";else if (type == ".jpg")return "image/jpeg";else{return "text/html";}
}
string GetCodeDesc(int _code)
{switch (_code){case 200: return "OK";case 404: return "Not Found";case 307:return "Temporary Redirect";default:break;}
}
string Http_Handel(string & requestmessage)
{Request req;req.Deserialize(requestmessage);req.Parse();req.RequestDebug();string responsemessage;string content=req.GetFileContentHelper(req.Path());Response res;int code=200;if(content.empty()){code=404;content=req.GetFileContentHelper("./wwwroot/404.html");}//code=307;res.SetCode(code);res.SetCodeDesc(GetCodeDesc(code));res.make_statu_line();res.Set_content(content);string httphead="Content-Length: " + std::to_string(content.size()) + "\r\n";res.head_push(httphead);httphead="Content_type: "+_to_httptype(req.Suffix())+"\r\n";res.head_push(httphead);if(res.ret_code()==to_string(307)){string httphead307;httphead307="Location:http://www.qq.com"+string("\r\n");res.head_push(httphead307);}httphead="Set-Cookie: "+string("username=bossface")+"\r\n";res.head_push(httphead);httphead="Set-Cookie: "+string("password=123465")+"\r\n";res.head_push(httphead);httphead="\r\n";res.head_push(httphead);//content;responsemessage=res.serialize();return responsemessage;}   
int main(int argc, char *argv[])
{// 遗留问题,客户端只发了一次数据就退出了?if (argc != 2){Usage(argv[0]);cerr << "Usage error" << endl;exit(0);}uint16_t port = stoi(argv[1]);TcpServer *server = new TcpServer(port,Http_Handel);server->Loop();
}

表单


  
FROM表单不写方法默认是GET方法

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>我的网站</title>
</head><body><h4>This is my first paragraph.</h4><!-- <a href="https://www.qq.com/">点我</a> --><a href="http://8.137.19.140:8888/dira/dirb/x.html">跳转到登录</a><form action="/dira/dirb/x.html" method="post">First name:<br><input type="text" name="myname" value="aaaa"><br>Last name:<br><input type="password" name="mypasswd" value=""><br><br><input type="submit" value="登录"></form><!-- <img src="/image/1.png" alt="cat"> -->
</body></html>

GET vs POST

GET利用url传参 POST利用正文传参

GET有字节数限制 POST没有字节数限制

GET私密性更差一点,但是GET/POST方法都不安全

我们要对数据进行加密和解密

HTTP的状态码
  

HTTP状态码对照表,HTML常用字符查询表,html特殊字符对照表_TendCode
例如200 success 404 failed 403 Forbiden 禁止访问 

设计一个404
可以直接创建一个404.html 当获取内容为空时 code设置为404 改为获取404.html文件中的内容
  


  
设计一个307 重定向功能
结合location
在响应报头里添加 Location: www.qq.com
重定向可以进行页面的跳转
301永久重定向和307临时重定向有什么区别?https://tendcode.com/tool/html-special-characters/
  

搜索网页,搜索的关键字会与无数个URL网络链接相关联(例如baidu),网站过期了,我们可以用301,去让用户获取新的链接,之后用户所有的访问都会去新的永久重定向的地址,旧地址就不使用了
  

cookie和session
http
1.无连接
2.无状态

网站为什么要一直认识我?
网站根据用户身份,要区分用户的权限。
那当点击网站内任意一链接时,为什么网站又不去一直让我登陆?
因为server无状态,所以无法一直识别用户,此时server会传入传入一个Cookie,Cookie字段会报曾经登陆过的账号密码自动保留,当下一次访问server就可以不用登陆了。
  
当将Cookie移除时,用户就需要重新登陆了
如何实现?
在http报头字段加入 Set-Cookie:username= ?
                   Set-Cookie: password=?
  


  
我们的Cookie有两类:文件级,内存级
保存的位置要么在文件要么在内存
tips:登陆网站后退出,当再次登陆,不需要输用户名密码则是在文件中储存。    
我们Cookie是基于会话管理的

我们自己设置一般的cookie存在一些问题
原因;当我们的电脑被入侵,黑客拿到了我们的Cookie,黑客可以直接拿我们的Cookie登陆我们的账号,就比如在之前我们的QQ特别容易被盗。
解决方案--->引入Sessionid
当用户输入账户和密码时,服务器返回的Cookie中不存用户的账户密码,而是存入Session,再构建Sessionid,Sessionid具有唯一性,返回给浏览器,这样我们用户的账户和密码就保存在了服务端,而不是客户端,而客户端再次访问时,客户端发给服务端Sessionid,服务端再用Sessionid去认证。
  
这时候又有个问题,黑客就算拿不到用户账户密码,也能拿到Sessionid,再通过服务端访问,Sessionid的引入好像只是解决了用户账户密码的暴漏问题。
这个问题我们无法解决,因为我们一旦把账户密码发送到客户端,用户信息就暴漏了。但是服务端有很多种策越解决这个问题,例如IP认证。一旦检测到陌生IP访问,服务端可以直接让Sessionid失效。
 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GitLab 老旧版本如何升级?

极狐GitLab 正式对外推出 GitLab 专业升级服务 https://dl.gitlab.cn/cm33bsfv&#xff01; 专业的技术人员为您的 GitLab 老旧版本实例进行专业升级&#xff01;服务详情可以在官网查看详细解读&#xff01; 那些因为老旧版本而被攻击的例子 话不多说&#xff0c;直接上图&a…

通用大模型应用研究七:RAGOS和AgentOS

RAG&#xff0c;即检索增强生成&#xff08;Retrieval-Augmented Generation&#xff09;&#xff0c;是一种结合了信息检索和大型语言模型&#xff08;LLM&#xff09;提示的技术。它通过从数据源检索相关信息&#xff0c;并将检索到的信息与问题一起注入到LLM提示中&#xff…

一起赚美元第九期及相关推荐

一、核心内容 &#xff08;一&#xff09;一起赚美元第九期文章导读 作者复盘了在 10 天内通过知识付费赚到 220750 美元的故事。运营数据&#xff1a;24 号课程做完&#xff0c;28 号课程开卖&#xff0c;10 天后 262 人付款&#xff0c;均价 800 美元&#xff0c;总金额 22…

【Android】事件分发机制

Android 的事件分发机制主要包括以下几个步骤&#xff1a; 事件生成&#xff1a;用户在设备上进行触摸、滑动等操作时&#xff0c;系统会生成相应的事件&#xff0c;如触摸事件&#xff08;MotionEvent&#xff09;。 事件发送&#xff1a;生成的事件会被发送到当前活动&#…

【linux】线程 (三)

13. 常见锁概念 &#xff08;一&#xff09;了解死锁 死锁是指在一组进程中的各个进程均占有不会释放的资源&#xff0c;但因互相申请被其他进程占有的&#xff0c;且不释放的资源&#xff0c;而处于的一种永久等待状态 &#xff08;二&#xff09;死锁四个必要条件 互斥条件…

uniapp项目结构基本了解

基本结构的解释 App.vue&#xff1a;应用的根组件&#xff0c;定义全局布局和逻辑。pages/&#xff1a;存放各个页面的 .vue 文件&#xff0c;定义应用的具体页面和功能模块。main.js&#xff1a;应用入口文件&#xff0c;初始化应用&#xff0c;挂载 App.vue。manifest.json&…

【C++】— 一篇文章让你认识STL

文章目录 &#x1f335;1.什么是STL&#xff1f;&#x1f335;2.STL的版本&#x1f335;3.STL的六大组件&#x1f335;4.STL的重要性&#x1f335;5. 如何学习STL&#x1f335;6. 学习STL的三种境界 &#x1f335;1.什么是STL&#xff1f; STL是Standard Template Library的简称…

『完整代码』靠近显示对话图标

在NPC预制体中增加Canvas 并设置 创建Image 并设置 隐藏Image 在场景中创建Canvas 重命名为CurrentCanvas 创建空物体设置底端锚点 重命名为DownPin 创建Image重命名为TalkUI 选择图片设置 创建Image并设置 重命名为imgNpc 创建文本并设置 重命名为txtNpc 可以给图片与文本加一…

centos 安装达梦数据库

一、环境准备 1.1、确认操作系统的版本和数据库的版本是否一致 ## 查看系统版本&#xff1a;cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core)1.2、关闭防火墙和Selinux # 查看selinux是不是disabled / enforce cat /etc/selinux/config## 查看防火墙状态 fir…

windows mysql 8.0版本重置root密码

1.停止mysql服务 以管理员运行cmd 2.安全模式启动 mysqld --console --skip-grant-tables --shared-memory 3.修改密码 再开个cmd窗口就可以进入了&#xff1a;mysql 先进入mysql database&#xff1a;use mysql 修改密码&#xff1a;ALTER USER rootlocalhost IDENTIFIED …

使用 InfiniBand 写入带宽对 NVIDIA GPUDirect RDMA 进行基准测试

简介 性能基准测试是 HPC 的标志。最现代的超级计算机是具有异构架构的计算节点集群。在这样的节点中&#xff0c;我们可以看到经典 CPU 和专用计算协处理器 (GPU)。本教程介绍了使用基于 InfiniBand 写入带宽 (ib_write_bw) 构建的定制脚本对 NVIDIA GPUDirect 远程直接内存访…

Xmind一款极简思维导图和头脑风暴软件,支持PC和移动端,Xmind 2024.10.01101版本如何升级到Pro版?简单操作,最新可用!

文章目录 Xmind下载安装Xmind免费升级到Pro Xmind 是一款全功能的思维导图和头脑风暴软件&#xff0c;不限制节点和文件数&#xff0c;创新无限&#xff0c;界面纯净简洁无广告&#xff0c;支持PC和移动端&#xff0c;思维导图和大纲视图自由切换&#xff0c;可本地化文档存储&…

AutoFixture:.NET 的假数据生成工具

上次推荐过《Bogus&#xff1a;.NET的假数据生成利器》方便我们制造假数据测试。今天继续推荐另外一个也是非常流行的工具。 01 项目简介 AutoFixture 是一个用于 .NET 的测试工具&#xff0c;它允许开发者在单元测试中自动生成随机的测试数据。它支持广泛的数据类型&#xf…

如何使用DockerSpy检测你的Docker镜像是否安全

关于DockerSpy DockerSpy是一款针对Docker镜像的敏感信息检测与安全审计工具&#xff0c;该工具可以帮助广大研究人员在Docker Hub上检测和搜索自己镜像的安全问题&#xff0c;并识别潜在的泄漏内容&#xff0c;例如身份验证密钥等敏感信息。 功能介绍 1、安全审计&#xff1a…

React源码03 - React 中的更新

03 - React 中的更新 React 中创建更新的方式&#xff1a; 初次渲染&#xff1a;ReactDOM.render、ReactDOM.hydrate 后续更新&#xff1a;setState、forceUpdate 1. ReactDOM.render() 先创建 ReactRoot 顶点对象然后创建 FiberRoot 和 RootFiber创建更新&#xff0c;使应用进…

ArcGIS应用指南:多尺度渔网创建

在GIS中&#xff0c;创建渔网矢量文件是GIS中的一项常见任务&#xff0c;通过将研究区域划分为规则的网格&#xff0c;可以更精细地分析和管理城市空间数据。本文以厦门市行政区为例&#xff0c;详细介绍了如何创建不同尺度的渔网矢量网格&#xff0c;以适应不同区域的发展特点…

DCS项目调试踩坑记录

最近在调试一个DCS项目&#xff08;集散控制系统&#xff09;&#xff0c;实际上就是一个新建厂区的控制系统。PLC用的是西门子1500&#xff0c;控制画面使用组态王7.5。 在调试过程中&#xff0c;发现给西门子DB块的变量转移到组态王太难了&#xff0c;因此记录一下&#xff0…

RHCE【远程连接服务器】

目录 一、远程连接服务器简介 二、加密技术简介 SSH工作过程&#xff1a; &#xff08;1&#xff09;版本协商阶段 &#xff08;2&#xff09;密钥和算法协商阶段 &#xff08;3&#xff09;认证阶段 &#xff08;4&#xff09;会话请求阶段 &#xff08;5&#xff0…

互联网人口红利趋缓下的社群粉丝经济新模式探索

摘要&#xff1a;随着互联网人口红利消失近十年&#xff0c;国内互联网人口红利爆发时期凭借大量用户取得成功的模式不再适用。如今互联网人口增长进入平缓期&#xff0c;社群粉丝经济成为新方向。其能借助人群画像精准推送营销信息&#xff0c;降低成本。如“21 链动模式 AI 智…

android openGL ES详解——混合

一、混合概念 混合是一种常用的技巧&#xff0c;通常可以用来实现半透明。但其实它也是十分灵活的&#xff0c;你可以通过不同的设置得到不同的混合结果&#xff0c;产生一些有趣或者奇怪的图象。混合是什么呢&#xff1f;混合就是把两种颜色混在一起。具体一点&#xff0c;就…