【Linux】http 协议

目录

一、http协议

(一)http 协议的概念

(二)URL的组成

(三)urlencode 和 urldecode

二、http 的协议格式

(一)http 请求方法

(二)http 响应状态码

(三)http 常见的响应报头

三、http 协议客户端和服务器通信过程

(一)应用层如何保证将请求或响应完整读取完了?

(二)http如何进行序列化和反序列化

(三)通信全过程

1、启动服务器

2、工具类

2、分析请求报文

3、发送响应报文

四、http 会话保持


一、http协议

(一)http 协议的概念

        上节我们提到可以自定协议,但是面对一些复杂的场景单靠自定协议是很难满足需求的。实际上已经有一些现成且好用的应用层协议,http 超文本传输协议就是其中之一。

(二)URL的组成

        URL即我们平时常称的网址。

        ip会标识一台网络主机,我们通过在浏览器中输入网址就可以访问该服务器,从指定的文件路径下找到用户请求的文件返回给用户。

(三)urlencode 和 urldecode

        对于URL而言,在浏览器中其并不是完全明文显式的,例如:

        我们可以看到当我们搜索 C++ 时, URL中不是显式的C++,而是 C%2B%2B 的形式,这是因为在http协议对于URL中的特殊字符,必须将其进行转义。

转义规则:

        一个字节是八个比特位,从中间划分左右各4位(不足4位直接处理),将左右4位分别转为16进制,将两位组合在一起后前面加上%便编码成%XY格式。

二、http 的协议格式

(一)http 请求方法

        本文只介绍两种常用的请求方法:GET和POST。

方法说明支持的HTTP协议版本
GET获得资源1.0、1.1
POST传输实体主题1.0、1.1

        虽然它们都是客户端向服务器发出的请求方法,但是二则略有不同。

        针对同一份前端表单form,当不同的请求方法时,浏览器会将执行不同的动作:

1、GET方法通过URL传递参数。例如上例中,当我们使用GET方法处理表单时,浏览器会将我们的表单内容拼接为URL发送给服务器,http://ip::port/XXX?key=value。使用URL进行传参注定了参数不能过大,当传输数据过大时使用GET方法请求就不合适了;

2、 POST方法则是通过http请求正文传递参数的,对于正文数据大小没有限制,适合传递一些大型文件。

3、POST方法相较于GET方法更加私密,GET方法通过URL传递参数,所以传递的数据可以被直接看到。虽然POST方法比GET方法更私密,但二者实际都是不安全的,如果需要加密安全的话得使用https协议。

(二)http 响应状态码

        https协议的状态码:

类别原因短语
1XXInformational(信息状态码)

接收的请求正在处理

2XXSuccess(成功状态码)请求正常处理完毕
3XXRedirection(重定向状态码)需要进行附加操作以完成请求
4XXClient Error(客户端错误状态码)服务器无法处理请求
5XXServer Error(服务器错误状态码)服务器处理请求出错

        常见错误码:

2XX:

  • 200 OK:请求成功
  • 201 Created:请求已经被实现,资源已经被创建。
  • 204 No Content:请求成功,但响应报文不含实体的主体部分。

3XX:

  • 301 Moved Permanently:永久性重定向
  • 302 Found:临时性重定向
  • 307 Temporary Redirect:临时性重定向

4XX:

  • 400 Bad Request:请求报文存在语法错误
  • 401 Unauthorized:未经授权,需要身份验证
  • 403 Forbidden:服务器拒绝请求
  • 404 Not Found:服务器无法找到请求的资源

5XX:

  • 500 Internal Server Error:服务器内部错误
  • 502 Bad Gateway:网关错误
  • 503 Service Unavailable:服务器暂时无法处理请求
  • 504 Gateway Timeout:网关超时

(三)http 常见的响应报头

  • Content-Type:指定响应体的MIME类型,例如text/html表示HTML文本,image/jpeg表示JPEG图片等。
  • Content-Length:指定响应体的长度,单位为字节
  • Host:客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上
  • User-Agent:声明用户的操作系统和浏览器版本信息
  • referer:当前页面是从哪个页面跳转过来的
  • location:搭配3xx状态码使用, 告诉客户端接下来要去哪里访问
  • cookie:用于在客户端存储少量信息. 通常用于实现会话的功能

三、http 协议客户端和服务器通信过程

(一)应用层如何保证将请求或响应完整读取完了?

        首先对于请求行、请求报头、状态行和响应报头都是按照 \r\n 为行分隔符,因此可以读取完整的一行。而报头与正文之间也存在着一个分隔符,因此可以区分请求报头是否读取完整。而请求报头中存在着 Content-Length 字段,其记录了正文的长度,因此应用层可以完整地读取请求正文或响应正文,从而保证了应用层可以完整地读取一个完整的请求或响应。

(二)http如何进行序列化和反序列化

        上节我们自定义协议的时候是需要对请求和响应进行序列化和反序列化的,那么 http 协议是如何进行需要序列化和反序列化呢?实际 http 协议本身无需用户关注序列化和反序列化,直接发送即可,而对于正文部分,如果有需要用户可以自定义序列化和反序列化方案。

(三)通信全过程

1、启动服务器

    void httpHandler(int fd, func_t func)
    {
        // 读取数据
        char buffer[1024];
        ssize_t n = recv(fd, buffer, sizeof(buffer) - 1, 0);
        if (n >= 0)
        {
            buffer[n] = 0;
            Request req;
            Response resp;
            req.parse(buffer);
            func(req, resp);
            send(fd, resp.outbuffer.c_str(), resp.outbuffer.size(), 0);
        }
    }
    void start(func_t func)
    {
        while (1)
        {
            signal(SIGCHLD, SIG_IGN);
            sockaddr_in addr;
            socklen_t len = sizeof(addr);
            int socket = accept(_fd, (struct sockaddr *)&addr, &len);
            if (socket == -1)
            {
                cerr << "accept failure : " << strerror(errno) << endl;
                continue;
            }

            pid_t pid = fork();
            if (pid == 0)
            {
                close(_fd);
                httpHandler(socket, func);
                close(socket);
                exit(0);
            }
            close(socket);
        }
    }

2、工具类

#include <iostream>
#include <string>
#include <fstream>
using namespace std;
class Util
{
public:
    static string getLine(string &buffer, const string &sep)
    {
        auto index = buffer.find(sep);
        if (index == string::npos)
            return "";
        string ret = buffer.substr(0, index);
        buffer.erase(0, index);
        return ret;
    }
    static bool readFile(const string &text, char *buffer, int size)
    {
        fstream in(text, ios_base::binary | ios_base::in);
        if (!in.is_open())
            return false;
        in.read(buffer, size);
        in.close();
        return true;
    }
};

2、分析请求报文

class Request
{
public:
    Request() {}
    ~Request() {}

    void parse(const string &in)
    {
        inbuffer = in;
        string firstLine = Util::getLine(inbuffer, SEP);
        stringstream s(firstLine);
        s >> method >> url >> httpversion;

        path = DEFAULT_PATH;
        path += url;
        if (path[path.size() - 1] == '/')
            path += HOME_PAGE;
        else
            path += ".html";
        struct stat st;
        int ret = stat(path.c_str(), &st);
        if (ret == 0)
            size = st.st_size;
        else
            size = -1;
    }

public:
    string inbuffer;
    string method;
    string url;
    string path;
    string httpversion;
    string suffix;
    string parm;
    int size;
};

3、发送响应报文

void Get(const Request &req, Response &resp)
{
    cout << "----------------------http recv start---------------------------" << endl;
    cout << req.inbuffer << std::endl;
    std::cout << "method: " << req.method << std::endl;
    std::cout << "url: " << req.url << std::endl;
    std::cout << "httpversion: " << req.httpversion << std::endl;
    std::cout << "path: " << req.path << std::endl;
    cout << "----------------------http recv end---------------------------" << endl;

    cout << "----------------------http send start---------------------------" << endl;
    resp.outbuffer += "HTTP/1.1 200 OK\r\n";
    // resp.outbuffer += "HTTP/1.1 302 Found\r\n";
    resp.outbuffer += "Content-Type: text/html\r\n";
    // resp.outbuffer += "Location:https://blog.csdn.net/Sweet_0115?spm=1000.2115.3001.5343\r\n";
    resp.outbuffer += "\r\n";
    string body;
    body.resize(req.size + 1);
    if (!Util::readFile(req.path, (char *)body.c_str(), body.size()))
        !Util::readFile("./wwwroot/404.html", (char *)body.c_str(), body.size());
    cout << "test : -----------" << req.path << endl;
    // cout << body << endl;
    resp.outbuffer += body;
    cout << resp.outbuffer << endl;
    cout << "----------------------http send end---------------------------" << endl;
}

四、http 会话保持

        当我们打开CSDN登录后,即使我们关闭了浏览器,短期内我们再打开CSDN仍然不需要重复登录。同样的,我们在CSDN内进行网页跳转时,也不需要再重复登录。http 协议是无状态的,那么浏览器是怎么做到网页跳转时用户不需要重复登录呢?

        这实际就是会话保持,http请求是无状态的,也就是以上功能并不是 http 提供的,而是session和cookie提供的。

        当用户首次登录时,浏览器会将用户的账号和密码保存在cookie文件里,当用户近期再次访问该网站或在网站内进行跳转时,浏览器会自动将cookie文件里的数据推送给服务器,从而不需要用户再次登录。例如当我们使用软件观看一些会员视频时,利用以上机制可以鉴权进行身份判断。

        但以上方式实际很不安全,例如一些不法分子可以通过劫持 http请求 从而获取到用户的账号和密码,所以以上机制是很危险的。

        实际当用户登录后,服务器会为用户建立会话(session),其会保存用户的信息,同时会返回给浏览器 session id。当用户近期再次访问网站或再网站内进行跳转时,浏览器则向服务器发送 session id,而服务器则通过该 session id 进行身份鉴权判断。

        但实际以上机制仍存在风险,不法分子仍然可以通过劫持 http 请求获取 session id,通过该id仍然可以向服务器伪造请求,但相比于第一种方案,至少用户的账户密码信息没有丢失。上述方案也可以配合别的机制,例如短信验证或人脸识别保障信息安全,例如当账号突然被异地登录(用户信息泄漏),服务器检测后使 session id 失效并令用户重新进行验证登录,一定程度上保护了用户的信息安全。

        http请求并不安全,如果有安全防护需求必须得使用https协议。

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

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

相关文章

ACE协议学习1

在多核系统或复杂SoC&#xff08;System on Chip&#xff09;中&#xff0c;不同处理器核心或IP&#xff08;Intellectual Property&#xff09;模块之间需要保持数据的一致性。常用的是ACE协议or CHI。 先对ACE协议进行学习 ACE协议&#xff08;Advanced Microcontroller Bu…

ES-分词器安装与使用详解

安装分词器 windows环境&#xff0c;分词器有2种安装方式&#xff0c;1.直接命令安装&#xff1b;2.压缩包安装 IK分词器 查看ik分词器文档&#xff0c;找到安装方式介绍 文档链接&#xff1a; 方式1 elasticsearch-plugin install https://get.infini.cloud/elasticsearch/an…

FY-3D MWRI亮温绘制

1、FY-3D MWRI介绍 风云三号气象卫星&#xff08;FY-3&#xff09;是我国自行研制的第二代极轨气象卫星&#xff0c;其有效载荷覆 盖了紫外、可见光、红外、微波等频段&#xff0c;其目标是实现全球全天候、多光谱、三维定量 探测&#xff0c;为中期数值天气预报提供卫星观测数…

P8686 [蓝桥杯 2019 省 A] 修改数组--并查集 or Set--lower_bound()的解法!!!

P8686 [蓝桥杯 2019 省 A] 修改数组--并查集 题目 并查集解析代码【并查集解】 Set 解法解析lower_bound代码 题目 并查集解析 首先先让所有的f&#xff08;i&#xff09;i&#xff0c;即每个人最开始的祖先都是自己&#xff0c;然后就每一次都让轮到那个数的父亲1&#xff08…

docker启动jenkins,jenkins中调用docker

在jenkins中执行docker 思路 jenkins中安装docker客户端&#xff0c;使用第三方的docker(需要付费)。jenkins中安装docker客户端&#xff0c;另一个容器中安装docker服务&#xff0c; docker-in-docker&#xff0c;需要特权模式&#xff0c;或者第三方的工具。jenkins中什么都…

【GPT入门】第9课 思维树概念与原理

【GPT入门】第9课 思维树概念与原理 1.思维树概念与原理2. 算24游戏的方法 1.思维树概念与原理 思维树&#xff08;Tree of Thought&#xff0c;ToT &#xff09;是一种大模型推理框架&#xff0c;旨在解决更加复杂的多步骤推理任务&#xff0c;让大模型能够探索多种可能的解决…

时态--02--⼀般将来时

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 ⼀般将来时1.肯定句结构:主am/is/aregoing to do(v.原型) 2.否定句结构:主am/is/arenotgoing to do(v.原型) 3.一般疑问句结构:Am/Is/Are(提句⾸)主going to do (v.…

模型压缩技术(二),模型量化让模型“轻装上阵”

一、技术应用背景 在人工智能蓬勃发展的浪潮下&#xff0c;大模型在自然语言处理、计算机视觉等诸多领域大放异彩&#xff0c;像知名的GPT以及各类开源大语言模型&#xff0c;其规模与复杂度持续攀升。然而&#xff0c;这一发展也带来了挑战&#xff0c;模型越大&#xff0c;对…

swift-5-汇编分析闭包本质

一、枚举、结构体、类都定义方法 方法占用对象的内存么&#xff1f; 不占用 方法的本质就是函数 方法、函数都存放在代码段&#xff0c;因为方法都是公共的&#xff0c;不管 对象一还是对对象二调用都是一样的&#xff0c;所以放在代码段&#xff0c;但是每个对象的成员不一样所…

通义千问本地配置并实现微调

通义千问本地配置并实现微调 最小Qwen模型大小942mb from modelscope import snapshot_download model_dir = snapshot_download(“qwen/Qwen2.5-0.5B”, cache_dir=“./models2.5”) Qwen2.5-0.5B:942MB from modelscope import snapshot_download model_dir = snapshot_d…

< 自用文儿 > CertBot 申请 SSL 证书 使用 challenge 模式 避开防火墙的阻挡

环境&#xff1a; 腾讯 VPS 腾讯会向你销售 SSL &#xff0c; 这个本是免费的。CertBot 默认申请证书要用到 80 端口&#xff0c;会蹭边什么什么条款&#xff0c;备案法律来阻止80端口的通讯&#xff0c;没有网站也一样被阻拦。 通过腾讯买的域名&#xff1a; bestherbs.cn …

<建模软件安装教程1>Blender4.2系列

Blender4.2安装教程 0注意&#xff1a;Windows环境下安装 第一步&#xff0c;百度网盘提取安装包。百度网盘链接&#xff1a;通过网盘分享的文件&#xff1a;blender.zip 链接: https://pan.baidu.com/s/1OG0jMMtN0qWDSQ6z_rE-9w 提取码: 0309 --来自百度网盘超级会员v3的分…

SpringBoot统一响应类型3.1.1版本

前言&#xff1a; 通过实践而发现真理&#xff0c;又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识&#xff0c;又从理性认识而能动地指导革命实践&#xff0c;改造主观世界和客观世界。实践、认识、再实践、再认识&#xff0c;这种形式&#xff0c;循环往…

如是APP:AI精准匹配需求,信用体系重构信任,双轮驱动打造无套路电商

如是APP:AI精准匹配需求,信用体系重构信任,双轮驱动打造无套路电商 2024年3月,一款结合AI导购与信用体系的电商平台——如是APP即将上线。如是APP通过AI对话帮助用户精准快速购物,并通过全维度信用体系实现产品信息透明化,旨在打造一个“信息对称”的电商平台,实现“无套路”的…

[SAP MM] 查看物料主数据的物料类型

创建物料主数据时&#xff0c;必须为物料分配物料类型&#xff0c;如原材料或半成品 在标准系统中&#xff0c;物料类型ROH(原材料)的所有物料都要从外部采购&#xff0c;而类型为NLAG(非库存物料)的物料则可从外部采购也可在内部生产 ① 特殊物料类型&#xff1a;NLAG 该物料…

Linux中部署DeepSeek,WSL(ubunt)中使用ollama部署deepseek-R1-7b

想在自己的Win11电脑上部署Linux的DeepSeek模型&#xff0c;但在网上一直没有找到合适的相应教程&#xff0c;自己查询各种网上资源&#xff0c;以及询问一些AI大模型后成功安装&#xff0c;并整理了以下步骤。仅作为个人学习笔记使用&#xff0c;由于本人对各方面知识掌握不足…

NoteGen是一款开源跨平台的 AI 笔记应用,专注于 recording 和 writing ,基于 Tauri 开发

一、软件介绍 文末提供程序和源码下载 NoteGen 是一款专注于记录和写作的跨平台 AI 笔记应用&#xff0c;基于 Tauri 开发。NoteGen 的核心理念是将记录、写作和 AI 结合使用&#xff0c;三者相辅相成。记录功能可以帮助用户快速捕捉和整理碎片化知识。整理功能是连接记录和写…

C++性能分析工具

C性能分析工具常用的三种。perf、gprof、pprof perf工具需要root权限&#xff0c;设置perf的suid位并不行&#xff0c;需要设置perf对应的内核参数。 perf使用&#xff1a; g -o example example.cpp -O2 # 运行程序并采样 sudo perf record -g ./example # 查看采样结果 sud…

【编译器】VSCODE搭建ESP32-C3

【编译器】VSCODE搭建ESP32-C3 文章目录 [TOC](文章目录) 前言一、下载配置二、编译三、烧录四、参考资料总结 前言 使用工具&#xff1a; 1. 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、下载配置 安装IDF&#xff0c;打开例程 二、编译 三…

《云原生监控体系构建实录:从Prometheus到Grafana的观测革命》

PrometheusGrafana部署配置 Prometheus安装 下载Prometheus服务端 Download | PrometheusAn open-source monitoring system with a dimensional data model, flexible query language, efficient time series database and modern alerting approach.https://prometheus.io/…