【Linux】HTTP协议2

在这里插入图片描述

欢迎来到Cefler的博客😁
🕌博客主页:折纸花满衣
🏠个人专栏:题目解析
🌎推荐文章:承接上文【Linux】HTTP协议1

在这里插入图片描述


目录

  • 👉🏻HTTP方法
  • 👉🏻HTTP状态码
  • 👉🏻HTTP常见header
  • 👉🏻HTTP Cookie
  • 👉🏻Http Session
  • 👉🏻HTTP协议(版本3,增设响应)
    • HttpProtocol.hpp

👉🏻HTTP方法

HTTP(Hypertext Transfer Protocol,超文本传输协议)是一个简单的请求-响应协议,它通常运行在TCP之上。它允许客户端向服务器发送请求,并获取服务器响应。通过HTTP,用户可以从网络上获取各种信息,例如网页、图片、音频、视频等。

HTTP定义了一系列的方法,或称为“动作”,用于指定客户端对服务器上资源的操作方式。这些方法包括:

  1. GET:用于请求服务器发送某个资源。这是最常用的方法之一,常用于请求网页、图片等资源。
  2. POST:用于向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立或现有资源的修改。
  3. PUT:用于向指定资源位置上传其最新内容。与POST不同,PUT请求具有幂等性,即多次执行相同的PUT请求,结果应该是一样的。
  4. DELETE:请求服务器删除指定的页面。
  5. HEAD:类似于GET请求,但服务器在响应中只返回HTTP头部,不返回实际数据。这种方式常用于获取报文的元数据,如内容类型或长度。
  6. OPTIONS:返回服务器支持的通信选项。客户端可以对特定的URL使用这个方法,以获取服务器支持的通信选项。

此外,HTTP1.1还新增了其他方法,如PATCH(用于对资源进行部分修改)、TRACE(用于回显服务器收到的请求,主要用于测试或诊断)和CONNECT(HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器)。

HTTP请求和响应都遵循特定的格式,包括请求行、请求头部、请求主体以及响应行、响应头部、响应主体。HTTP也使用状态码来表示请求的处理结果,并支持缓存机制,客户端可以将请求的资源保存到本地,并在下一次请求时直接使用本地资源,减少对服务器的访问。同时,HTTP还可以通过使用SSL/TLS等安全协议来增强数据传输的安全性。

👉🏻HTTP状态码

HTTP状态码是用于表示客户端请求与服务器响应之间的状态的三位数字代码。它们由RFC 2616规范定义,并得到其他相关规范的扩展。HTTP状态码的主要作用是提供有关请求是否成功、出现错误或需要进一步操作的信息,是Web开发中非常重要的一部分。

HTTP状态码主要分为五类:

  1. 1xx(信息性状态码):表示请求已经接收,继续处理。这一类的状态码是临时的响应,指示客户端应继续其请求或忽略该响应。
  2. 2xx(成功状态码):表示请求已经被成功接收、理解、并处理。这一类的状态码代表请求已成功被服务器接收、理解,并接受。
  3. 3xx(重定向状态码):表示请求需要进一步操作,以完成请求。这一类的状态码表示要完成请求,必须进一步执行的动作。
  4. 4xx(客户端错误状态码):表示客户端的请求有问题,服务器无法处理。这一类的状态码表示请求包含错误语法或无法完成请求。
  5. 5xx(服务器错误状态码):表示服务器处理请求时出现了错误。这一类的状态码表示服务器在尝试处理请求时发生了错误。

常见的HTTP状态码包括:

  • 200 OK:请求成功。
  • 404 Not Found:请求的页面不存在。
  • 500 Internal Server Error:服务器内部错误。

👉🏻HTTP常见header

HTTP的常见header包括请求头(Request Header)和响应头(Response Header),它们携带了关于HTTP请求和响应的元数据。以下是一些常见的HTTP header字段及其作用的简要说明:

请求头(Request Header):

  1. Host:指定目标服务器的域名或IP地址。这对于虚拟主机环境中的服务器至关重要,因为它告诉服务器客户端想要访问哪个域名的内容。
  2. User-Agent:发送请求的用户代理信息,通常是浏览器标识。它告诉服务器关于客户端的一些信息,如浏览器类型、版本和操作系统等。
  3. Accept:指定客户端可以接受的内容类型。例如,它可以告诉服务器客户端可以接受HTML、JSON或XML等格式的数据。
  4. Referer:指定当前请求的来源页面URL。它用于跟踪用户从哪个页面导航到当前页面,有助于分析用户行为和流量来源。
  5. Connection:指定是否保持网络连接。例如,“keep-alive”表示客户端希望保持连接,以便在多个请求之间重用同一个TCP连接,提高性能。
  6. location: 搭配3xx状态码使用, 告诉客户端接下来要去哪里访问;
  7. Cookie: 用于在客户端存储少量信息. 通常用于实现会话(session)的功能;

响应头(Response Header):

  1. Content-Type:指定响应体的媒体类型。例如,它可以告诉客户端返回的数据是HTML、图片、JSON或其他类型。
  2. Content-Length:指定响应体的长度(以字节为单位)。这有助于客户端了解接收到的数据量。
  3. Cache-Control:指定缓存策略,如缓存的有效期、是否可以缓存等。它帮助客户端和缓存服务器确定如何缓存和重用响应内容。
  4. Set-Cookie:在客户端设置Cookie。Cookie是一种用于在客户端存储会话信息的机制,可以在多个请求之间共享状态。

👉🏻HTTP Cookie

HTTP的cookie(浏览网页后存储在计算机的缓存文件)是一种在HTTP协议下,服务器或脚本可以维护客户工作站上信息的方式。它是由Web服务器保存在用户浏览器(客户端)上的小文本文件,通常内容会经过加密处理。每当用户链接到服务器时,Web站点都可以访问这些cookie信息,因此,cookie可以被看作是浏览器缓存

cookie的主要特点包括:

  1. 创建与存储:cookie是在用户浏览网站时由服务器端创建的,并由用户的浏览器放置在用户的计算机或其他设备上。浏览器负责存储cookie,并在之后的请求中将其发送回服务器
  2. 数据格式:cookie的格式通常是以键值对的形式出现,使用分号和空格进行分隔。一个cookie可以包含多个键值对,每个键值对表示一项具体的数据。
  3. 属性设置:cookie可以设置多种属性,如过期时间(Expires)、可访问路径(Path)、可访问域名(Domain)以及是否只在HTTPS连接中传输(Secure)等。这些属性可以帮助服务器更精细地控制cookie的使用范围和行为。
  4. 应用场景:cookie的主要应用场景包括会话管理个性化跟踪。例如,通过cookie,服务器可以保持用户的登录状态、记录购物车信息、设置个性化主题等。同时,服务器还可以利用cookie来记录和分析用户行为,以优化服务。

cookie的存在,就解释了为什么HTTP协议虽然说是无状态(即服务器不会保留之前请求的状态信息),是因为这些状态信息被本地浏览器缓存存储,本地浏览器访问服务器时,会将这些信息放在报头中发送给服务端,服务端自然就认识你了

此外,cookie还具有httpOnly属性,可以防止XSS攻击,提供了一定的安全性保障。但需要注意的是,虽然cookie可以增强Web应用程序的功能和用户体验,但如果不当使用或管理不善,也可能带来安全风险,如泄露用户隐私等。因此,在使用cookie时,需要遵循相关的最佳实践和安全规范。

👉🏻Http Session

HTTP的session会话代表客户端与服务器之间的一次交互过程,这个过程可以是连续的,也可以是时断时续的。session机制用于在HTTP请求中识别和区分不同的客户端,并记录它们的状态信息。这对于需要保持用户状态的Web应用程序尤为重要,比如Web登录和购物车等功能。

当用户与服务器交互时,服务器会为用户创建一个session,并分配一个唯一的session ID。这个session ID通常通过两种方式传递给客户端:一种是作为cookie保存在客户端浏览器中,另一种是直接携带在URL中。每次客户端发送请求时,都会带上这个session ID,以便服务器能够识别并关联到对应的session。

在session中,服务器可以保存用户的各种信息,如登录状态、购物车内容等。这些信息在用户的整个会话期间都是有效的,并且可以在多个请求之间共享。因此,通过session机制,服务器能够跟踪和管理用户的会话状态,从而提供个性化的服务和体验。

需要注意的是,session信息需要存储在服务器上,可以是系统文件、数据库或内存等。此外,为了安全性考虑,session ID通常会进行加密处理,以防止被恶意攻击者利用。

session还有一个重要的属性是可过期性。服务器可以设置session的有效期,一旦session过期,服务器将不再识别该session ID,用户需要重新登录或进行其他身份验证操作。这有助于保护用户数据的安全性,并防止未授权的访问。

总之,HTTP的session会话机制为Web应用程序提供了一种有效的手段来跟踪和管理用户的会话状态,从而提供个性化的服务和体验。


在ssesion出来前,cookie的安全性其实非常低,因为如果我的登录账号和密码都存储在cookie中,那么我的http请求信息一旦被黑客截取,那么密码就直接暴露了,账号的安全就得不到保障。

所以现在,基本就是cookie存储的是ssesionID,服务器负责在服务器本地开放一片区域session存储你的登录信息,服务端只要根据你发送来的ssesionID,就可以在服务端找到相关的信息。

👉🏻HTTP协议(版本3,增设响应)

HttpProtocol.hpp

#pragma once

#include <iostream>
#include <string>
#include <vector>

#include <sstream>

using namespace std;
const string HttpSep = "\r\n";

const string homepage = "index.html";
const string wwwroot = "./wwwroot"; // 根目录

class HttpRequest
{
public:
    HttpRequest() : _req_blank(HttpSep), _path(wwwroot)
    {
    }
    ~HttpRequest()
    {
    }
    bool Getline(string &str, string *line) // 获取请求行的内容
    {
        // 1.找到内容停止符的位置
        auto pos = str.find(HttpSep);
        if (pos == string::npos)
            return false;

        // 2.截取正文
        *line = str.substr(0, pos);
        // 3.读取完后,将str中已提取的内容清空
        str.erase(0, pos + HttpSep.size());
        return true;
    }

    void Deserialize(string &request)
    {
        // 1.先读请求行
        string line;
        bool ok = Getline(request, &line);
        if (!ok)
            return; // 如果读不到\r\n则退出
        _req_line = line;

        // 2.再读报文每一行的内容
        while (true)
        {
            bool ok = Getline(request, &line); // 再接着往下读取
            if (ok && line.empty())
            {
                // 如果读到了,但是内容为空
                // 则剩下的内容为
                _req_content = request;
            }
            else if (ok && !line.empty())
            {
                _req_header.push_back(line);
            }
            else
                break;
        }
    }
    void ParseReqLine()
    {
        stringstream ss(_req_line);

        ss >> _method >> _url >> _http_version;

        if (_url == "/")
        {
            // 如果是在当前下目录,则直接令它的路径资源终点为index.html
            _path += _url;
            _path += homepage;
        }
        else
        {
            _path += _url;
        }
    }
    void ParseSuffix()
    {
        auto pos = _path.rfind(".");
        if (pos == string::npos)
            _suffix = ".html";
        else
            _suffix = _path.substr(pos);
    }
    void Parse()
    {
        // 1.解析请求行
        ParseReqLine();

        // 2.解析资源后缀
        ParseSuffix();
    }
    void DebugHttp()
    {
        std::cout << "_req_line" << _req_line << std::endl;
        for (auto &line : _req_header)
        {
            std::cout << "---> " << line << std::endl;
        }
        std::cout << "_req_blank: " << _req_blank << std::endl;
        std::cout << "_req_content: " << _req_content << std::endl;

        std::cout << "Method: " << _method << std::endl;
        std::cout << "url: " << _url << std::endl;
        std::cout << "http_version: " << _http_version << std::endl;
    }

    // 接下来再整几个返回解析后内容的函数接口
    string Url()
    {
        return _url;
    }
    string Path()
    {
        return _path;
    }
    string Suffix()
    {
        return _suffix;
    }
    // 返回正文内容的函数
    string GetFileContent(const string &path)
    {
        // 为了中间不出现字符解码出现问题
        // 我们读取文件内容,而是以二进制形式读取
        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);       // 读完大小后回到开头

        string content; // 存储读到的二进制内容
        content.resize(filesize);
        in.read((char *)content.c_str(), filesize);

        in.close();

        return content;
    }
 

private:
    string _req_line;           // 请求行
    vector<string> _req_header; // 用来存储请求数据中所有的请求行数据
    string _req_content;        // 报文内容
    string _req_blank;          // 空行

    // 解析之后的内容
    string _method;       // 请求方法
    string _url;          // 资源路径
    string _http_version; // http版本
    string _path;         // 资源的具体文件路径位置,path包含在url中,所以需要从url中解析
    string _suffix;       // 请求资源的后缀
};

const string BlankSep = " ";
const string LineSep = "\r\n";

class HttpResponse
{
public:
    HttpResponse()
        : _http_version("HTTP/1.0"), _status_code(200), _status_code_desc("OK"),
          _resp_blank(LineSep)
    {
    }
    ~HttpResponse() {}
    void SetCode(int code)
    {
        _status_code = code;
    }
    void SetDesc(const string &desc)
    {
        _status_code_desc = desc;
    }

    void SetContent(const string &content) // 设置正文内容
    {
        _resp_content = content;
    }
    void MakeStatusLine() // 组合成状态行
    {
        _status_line = _http_version + BlankSep + to_string(_status_code) + BlankSep + _status_code_desc + LineSep;
    }

    void AddHeader(string &header) // 添加报头内容
    {
        _resp_header.push_back(header);
    }

    // 接下来将以上信息全部整合序列化
    string Serialize()
    {
        string response_str = _status_line;
        for (auto &header : _resp_header)
        {
            response_str += header;
        }
        response_str += _resp_blank;
        response_str += _resp_content;

        return response_str;
    }

private:
    string _status_line;         // 状态栏
    vector<string> _resp_header; // 报头内容
    string _resp_blank;          // 空行
    string _resp_content;        // 正文

    // 接下来是要组成状态栏的部分:版本,状态码,状态描述码
    string _http_version;
    int _status_code;
    string _status_code_desc;
};

如上便是本期的所有内容了,如果喜欢并觉得有帮助的话,希望可以博个点赞+收藏+关注🌹🌹🌹❤️ 🧡 💛,学海无涯苦作舟,愿与君一起共勉成长

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

Swift - 流程控制

文章目录 Swift - 流程控制if-else2. while3. for3.1 闭区间运算符3.2 半开区间运算符3.3 for - 区间运算符用在数组上3.3.1 单侧区间 3.4 区间类型3.5 带间隔的区间值 4. switch4.1 fallthrough4.2 switch注意点 5. 复合条件6. 区间匹配、元组匹配7. 值绑定8. where9. 标签语句…

webpack中mode、NODE_ENV、DefinePlugin、cross-env的使用

本文讲的全部知识点&#xff0c;都是和webpack相关的。如果你之前有疑问&#xff0c;那本文一定能帮你搞清楚。 问题来源一般是类似下面代码&#xff08;webpack.json中&#xff09;&#xff1a; "scripts": {"dev": "cross-env NODE_ENVdevelopmen…

BUUCTF_[BSidesCF 2020]Had a bad day

[BSidesCF 2020]Had a bad day 1.一看题目直接尝试文件包含 2.直接报错&#xff0c;确实是存在文件包含漏洞 http://307b4461-36d6-443f-879a-68803a57f721.node5.buuoj.cn:81/index.php?categoryphp://filter/convert.base64-encode/resourceindex strpos() 函数查找字符串…

StarRocks x Paimon 构建极速实时湖仓分析架构实践

Paimon 介绍 Apache Paimon 是新一代的湖格式&#xff0c;可以使用 Flink 和 Spark 构建实时 Lakehouse 架构&#xff0c;以进行流式处理和批处理操作。Paimon 创新性地使用 LSM&#xff08;日志结构合并树&#xff09;结构&#xff0c;将实时流式更新引入 Lakehouse 架构中。 …

Docker基本操作 容器相关命令

docker run:运行镜像; docker pause:暂停容器&#xff0c;会让该容器暂时挂起&#xff1b; docker unpauser:从暂停到运行; docker stop:停止容器&#xff0c;杀死进程; docker start:重新创建进程。 docker ps&#xff1a;查看所有运行的容器及其状态&#xff0c;默认只展…

WildCard开通GitHub Copilot

更多AI内容请关注我的专栏&#xff1a;《体验AI》 期待您的点赞&#x1f44d;收藏⭐评论✍ WildCard开通GitHub Copilot GitHub Copilot 简介主要功能工作原理 开通过程1、注册Github账号2、准备一张信用卡或虚拟卡3、进入github copilot页4、选择试用5、选择支付方式6、填写卡…

实现SpringMVC底层机制(一)

文章目录 1.环境配置1.创建maven项目2.创建文件目录3.导入jar包 2.开发核心控制器文件目录1.流程图2.编写核心控制器SunDispatcherServlet.java3.类路径下编写spring配置文件sunspringmvc.xml4.配置中央控制器web.xml5.配置tomcat&#xff0c;完成测试1.配置发布方式2.配置热加…

创建Spring Boot项目

选择Maven Archetype,之后再Archetype选择webapp 两个都打勾 这是当前的打勾 这个是以后都默认勾上 打开对应的路径&#xff0c;用vscode打开settings.xml 加入国内源 阿里云 若没有此文件可上网查找 若jar包出现问题&#xff0c;可在repostitory文件内全删除 之后在Maven刷…

巴特沃斯滤波原理及代码实现(matlab详细过程版)

目录 一、算法原理1、原理概述2、参考文献 二、代码实现三、结果展示 本文由CSDN点云侠原创&#xff0c;原文链接。如果你不是在点云侠的博客中看到该文章&#xff0c;那么此处便是不要脸的爬虫与GPT。 一、算法原理 1、原理概述 巴特沃斯滤波器&#xff08;Butterworth filt…

主成分分析(PCA)在 Java 中的简单应用

在数据科学的众多工具中&#xff0c;主成分分析&#xff08;PCA&#xff09;是一种非常重要的统计技术&#xff0c;用于数据降维和模式识别。它通过提取数据中的关键特征来简化数据结构&#xff0c;从而帮助我们更好地理解数据集的主要变化因素。本文将介绍如何在 Java 编程环境…

CARLA (I)--Ubuntu20.04 服务器安装 CARLA_0.9.13服务端和客户端详细步骤

目录 0. 说明0.1 应用场景&#xff1a;0.2 本文动机&#xff1a; 1. 准备工作2. 安装 CARLA 服务端软件【远程服务器】3. 安装 CARLA 客户端【远程服务器】3.1 .egg 文件安装&#xff1a;3.2 .whl 文件安装&#xff1a;3.3 从Pypi下载Python package 4. 运行服务端程序5. 运行客…

arcgis js 4.x加载SceneLayer并实现基于属性查询定位及高亮

一、代码 <!DOCTYPE html> <html> <head><meta charset"utf-8" /><meta name"viewport" content"widthdevice-width, initial-scale1,maximum-scale1,user-scalableno"><title></title><link rel…

北京车展创新纷呈,移远通信网联赋能

时隔四年&#xff0c;备受瞩目的2024&#xff08;第十八届&#xff09;北京国际汽车展览会于4月25日盛大开幕。在这场汽车行业盛会上&#xff0c;各大主流车企竞相炫技&#xff0c;众多全球首发车、概念车、新能源车在这里汇聚&#xff0c;深刻揭示了汽车产业的最新成果和发展潮…

神经网络的激活函数

目录 神经网络 激活函数 sigmoid 激活函数 tanh 激活函数 backward方法 relu 激活函数 softmax 激活函数 神经网络 人工神经网络&#xff08; Artificial Neural Network&#xff0c; 简写为ANN&#xff09;也简称为神经网络&#xff08;NN&#xff09;&#xff0c…

杰发科技AC7840——CAN通信简介(7)_波形分析

参考&#xff1a; CAN总线协议_stm32_mustfeng-GitCode 开源社区 0. 简介 隐形和显性波形 整帧数据表示 1. 字节描述 CAN数据帧标准格式域段域段名位宽&#xff1a;bit描述帧起始SOF(Start Of Frame)1数据帧起始标志&#xff0c;固定为1bit显性(b0)仲裁段dentify(ID)11本数…

c++图论基础(2)

目录 图的存储方式&#xff1a; 邻接矩阵&#xff1a; 代码实现&#xff1a; 邻接表&#xff1a; 代码实现&#xff1a; 邻接矩阵邻接表对比&#xff1a; 带权图&#xff1a; 邻接矩阵存储&#xff1a; 邻接表存储(代码实现)&#xff1a; 图的存储方式&#xff1a; 邻…

Unreal Engine添加UGameInstanceSubsystem子类

点击C类文件夹&#xff0c;在右边的区域点击鼠标右键&#xff0c;在弹出的菜单中选择“新建C类”在弹出的菜单中选中“显示所有类”&#xff0c;选择GameInstanceSubsystem作为父类, 点击“下一步”按钮输入子类名称“UVRVIUOnlineGameSubsystem”&#xff0c;选择插件作为新类…

Qt 创建控件的两种方式

目录 Qt 创建控件的两种方式 通过ui界面创建控件 通过代码方式创建控件 Qt 创建控件的两种方式 通过ui界面创建控件 这里当然我们是需要先有一个项目的&#xff0c;按照我们之前创建项目的步骤&#xff0c;我们可以先创建一个 Widget 的项目&#xff0c;但是 MainWindow 也…

EasyRecovery数据恢复软件2025激活码及下载使用步骤教程

EasyRecovery数据恢复软件是一款功能强大且用户友好的数据恢复工具&#xff0c;专为帮助用户找回因各种原因丢失的数据而设计。该软件由全球知名的数据恢复技术公司开发&#xff0c;经过多年的技术积累和更新迭代&#xff0c;已经成为行业内备受推崇的数据恢复解决方案。 EasyR…

Spring MVC系列之九大核心组件

概述 Spring MVC是面试必问知识点其一&#xff0c;Spring MVC知识体系庞杂&#xff0c;有以下九大核心组件&#xff1a; HandlerMappingHandlerAdapterHandlerExceptionResolverViewResolverRequestToViewNameTranslatorLocaleResolverThemeResolverMultipartResolverFlashMa…
最新文章