Linux---HTTP协议

HTTP

HTTP协议(Hypertext Transfer Protocol,超文本传输协议)是一种应用层协议,主要用于在Web浏览器和Web服务器之间传输数据。

一、认识URL

平时我们俗称的 " 网址 " 其实就是说的 URL

http请求样例

看起来是一行一行的,但是本质还是一个大字符串,中间以换行符分割,跟我们在自定义协议时操作一样,通过换行对字符串进行解析

如何理解web根目录?

web根目录实际就是服务器上的一个指定的目录,里面存放了所有http的资源,如果请求url= / ,我们请求的是默认首页,我们会对请求的路径进行拼接,从而找到服务器中的某个资源,其他情况也是同理,都需要服务器进行相关的路径处理。

std::string GetFileContent(std::string path) // 读相应目录下的文件资源
{
    std::ifstream in(path,std::ifstream::binary);
    std::string content;
    if (!in.is_open())
        return "";
    in.seekg(0,in.end);
    size_t n = in.tellg();
    in.seekg(0,in.beg);
    std::vector<char> v(n);
    in.read(v.data(),v.size());
    in.close();
    return std::string(v.begin(),v.end());
}

std::string Handler(std::string &request)
{
    HttpRequest req;
    req.Deserialize(request);// 反序列化http请求
    req.Parse();// 解析 http 请求
    req.Debug();

    //创建响应报文
    std::string httpstatusline = "http/1.1 200 ok"; //响应行
    std::string content = GetFileContent(req.Path()); // 响应正文
    std::string httpheader = "Content-Length: " + std::to_string(content.size()) + "\r\n";// 相应报头
    httpheader += "\r\n"; // 空行
    std::string httpresponse = httpstatusline + httpheader + content;
    return httpresponse;
}

二、Get/post

我们上网不仅仅可以获取资源,也可以上传数据,可以结合html进行传参,如登录、注册、搜索等都需要我们向服务器传递数据。

Get:可以用来获取资源,也能用来传递参数

post:传递参数,通过正文进行传输

GET vs POST

  • GET用url进行传参,POST请求正文传参
  • url传参,字节个数有限制,POST方法,参数没有限制
  • GET私密性更差一些,因为输入的参数会回显出来

但是GET和POST都不安全,GET能被看到,POST是明文传输,可以被捕捉到,安全和加密有关

一些其他方法的介绍

方法说明支持的http版本
PUT传输文件1.0、1.1
HEAD获取报文首部1.0、1.1
DELETE删除文件1.1、1.1
OPTIONS询问支持的方法1.1
TRACE追踪路径1.1
CONNECT要求用隧道协议连接代理1.1

三、http的状态码

类别原因短语
1XXInformation (信息性状态码)接收的请求正在处理
2XXSuccess (成功状态码)请求正常处理完毕
3XXRedirection (重定向状态码)需要进行附加操作以完成请求
4XXClient Error (客户端错误码)服务器无法处理请求
5XXServer Error (服务器错误状态码)服务器处理请求出错

最常见的状态码, 比如 200(OK), 404(Not Found), 403(Forbidden), 302(Redirect, 重定向), 504(Bad Gateway) 

简单说明一下:

  1. 1xx(信息性状态码):表示请求已经接收,继续处理。例如:
    • 100 Continue:客户端应继续其请求。
    • 101 Switching Protocols:服务器根据客户端的请求切换协议。
  2. 2xx(成功状态码):表示请求已经被成功接收、理解、并处理。例如:
    • 200 OK:请求成功,成功被服务器接收、理解、并接受。
    • 201 Created:请求已经被服务器接收并创建了新的资源。
    • 204 No Content:服务器成功处理了部分GET请求,但没有返回任何内容。
  3. 3xx(重定向状态码):表示请求需要进一步操作,以完成请求。例如:
    • 301 Moved Permanently:被请求的资源已永久移动到新位置,将来任何对此资源的引用都应该使用本响应返回的URI。
    • 302 Found(或302 Moved Temporarily):请求的资源现在临时从不同的URI响应请求。
  4. 4xx(客户端错误状态码):表示客户端的请求有问题。例如:
    • 400 Bad Request:请求错误,通常是访问的域名未绑定引起。
    • 403 Forbidden:禁止访问。
  5. 5xx(服务器错误状态码):表示服务器处理请求时出现了错误

这里挑几个重要的说一下

1、404 Not Found

当我们访问的资源不存在时,就会返回,具体的实现就是将正文部分的内容变成下面的网页内容

2、307 Temporary Redirect  临时重定向

需要配合报头"Location: 网页链接"使用

3、301 Moved Permanently  永久移动

用法和307相同,但是两者的应用场景不一样

307:应用于页面的跳转,比如跳转到登录或注册页面

301:应用于当网络域名改变/网站过期,可以通过它来重定向之前的链接,让它指向新的域名网址

四、http的报头字段

HTTP 常见 Header
  • Content-Type: 数据类型(text/html等)
  • Content-Length: Body的长度
  • Host: 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上
  • User-Agent: 声明用户的操作系统和浏览器版本信息
  • referer: 当前页面是从哪个页面跳转过来的
  • location: 搭配3xx状态码使用, 告诉客户端接下来要去哪里访问
  • Cookie: 用于在客户端存储少量信息. 通常用于实现会话(session)的功能

注意:请求的所有资源都有后缀,后缀决定了文件的类型。浏览器可以通过正文部分的文件后缀知道文件类型,但是有些浏览器无法自动识别文件类型,需要通过Content-Type来获取文件类型,所以http有专门的文件后缀和Content-Type的映射表,下面是网上截取的一部分

五、Cookie和session

HTTP协议中的无连接和无状态是其两个重要特性。

  • 首先,无连接的含义是限制每次连接只处理一个请求。当服务器处理完客户的请求并收到客户的应答后,连接就会断开。这种设计方式的主要目的是节省传输时间,使得请求时建立连接,请求完成后释放连接,以便尽快将资源释放出来服务其他客户端。尽管无连接可以提高效率,但在某些情况下也可能导致额外的开销,因为每次请求都需要重新建立连接。然而,HTTP/1.1版本引入了Keep-Alive功能,使得客户端到服务器端的连接可以持续有效,当出现对服务器的后继请求时,可以避免重新建立连接。
  • 其次,无状态指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即我们给服务器发送HTTP请求之后,服务器根据请求会给我们发送数据过来,但是发送完不会记录任何信息。这意味着每个HTTP请求都是独立的,服务器不会记住前一个请求的状态或信息。这种设计方式简化了服务器的实现,并减轻了其负担,但也带来了一些问题。例如,由于每个请求都是独立的,单个请求所需要的所有信息都必须包含在请求中一次发送到服务器,这可能导致单个消息的结构变得复杂,需要支持大量的元数据。

为了解决HTTP无状态的问题,人们提出了多种方案,如使用cookie进行身份验证和状态管理。这样,服务器可以通过cookie来识别不同的客户端和它们的会话状态,从而在一定程度上模拟有状态的行为。

实际在使用浏览器访问网页时,尤其是那种需要vip身份才能访问特定资源的网站,都会要求我们去登录注册,用来标识每一个用户,但http是无状态的,即服务器不会记录用户的信息,所以每次我们在访问时,都需要发送身份信息,如果每次都需要用户手动输入,用户肯定会有砸掉电脑的冲动,所以浏览器可以用cookie对用户信息作记录,每次访问网页就可以自动帮我们在请求报文中加上我们的用户信息。

cookie分为内存级和文件级:

  • 内存级:将信息存放在浏览器进程的上下文中,只在进程运行时有效,一旦关闭再打开就失效了
  • 文件级:将信息存放在浏览器软件的特定目录的文件中,一直有效,除非手动删除/修改文件内容

通过把"Set-Cookie: username=zxws"这样的语句添加到http报头字段实现Cookie

这种基于Cookie实现的就是会话管理

但是这种会话管理并不安全,因为我们是用账户密码直接进行的http请求,很容易被别人拿到,为了加强安全性,我们一般将用户的账户和密码哈希成一个标识符sessionid,用它进行身份的验证

 附录

// HttpProtocol.hpp
// 仅仅是模拟实现最简单的http的请求和响应的基本功能
// 代码并不全面和严谨,仅仅是为了方便我们直观的认识和了解http底层到底是如何做的
// 可以用网络套接字通信模拟实现一个简单的http网页服务,有兴趣可以尝试一下
#pragma once
#include "TcpServer.hpp"
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
const std::string HttpSeq = "\r\n";
const std::string wwwroot = "./wwwroot";
const std::string homepage = "index.html";

class HttpRequest
{
public:
    HttpRequest() : _path(wwwroot)
    {
    }

    bool GetLine(std::string &request, std::string *line)
    {
        auto pos = request.find(HttpSeq);
        if (pos == std::string::npos)
            return false;
        *line = request.substr(0, pos);
        request.erase(0, pos + HttpSeq.size());
        return true;
    }

    void Deserialize(std::string request)
    {
        std::string line;
        bool ok = GetLine(request, &line);
        if (!ok)
            return;
        _req_line = line;
        while (1)
        {
            ok = GetLine(request, &line);
            if (ok)
            {
                if (line.empty())
                {
                    _req_content = request;
                    break;
                }
                else
                {
                    _req_header.emplace_back(line);
                }
            }
            else
            {
                break;
            }
        }
    }

    void Parse()
    {
        ParseLine();

        if (_url == "/")
        {
            _path += _url;
            _path += homepage;
        }
        else
        {
            _path += _url; // ps:需要处理一些只有路径没有文件资源的问题
        }
    }

    std::string Suffix()
    {
        size_t pos = _path.rfind('.');
        if (pos == std::string::npos)
            return "";
        return _path.substr(pos + 1);
    }

    std::string GetFileContentHelper(const std::string &path)
    {
        std::ifstream in(path, std::ifstream::binary);
        std::string content;
        if (!in.is_open())
            return "";
        in.seekg(0, in.end);
        size_t n = in.tellg();
        in.seekg(0, in.beg);
        std::vector<char> v(n);
        in.read(v.data(), v.size());
        in.close();
        return std::string(v.begin(), v.end());
    }

    std::string GetFileContent()
    {
        return GetFileContentHelper(_path);
    }

    void ParseLine()
    {
        std::stringstream ss(_req_line);
        ss >> _method >> _url >> _version;
    }

    std::string Path()
    {
        return _path;
    }

    void Debug()
    {
        std::cout << _req_line << std::endl;
        for (auto line : _req_header)
        {
            std::cout << line << std::endl;
        }
        std::cout << _req_blank << std::endl;
        std::cout << _req_content << std::endl;

        // std::cout << _method << std::endl;
        // std::cout << _url << std::endl;
        // std::cout << _version << std::endl;
    }

    std::string Get_404()
    {
        return GetFileContentHelper("./wwwroot/404.html"); // 该404.html网页大家可以自己写
    }

private:
    std::string _req_line;
    std::vector<std::string> _req_header;
    std::string _req_blank = "";
    std::string _req_content;

    // method url 版本号
    std::string _method;
    std::string _url;
    std::string _version;
    std::string _path;

    std::string _suffix;
};

class HttpResponce
{
public:
    HttpResponce() : _version("http/1.1"), _status_code(200), _status_code_desc("ok"), _resp_blank("\r\n")
    {
    }
    void MakeStatusLine()
    {
        _status_line = _version + " " + std::to_string(_status_code) + " " + _status_code_desc;
    }

    void SetCode(int code)
    {
        _status_code = code;
    }

    void SetDesc(const std::string &desc)
    {
        _status_code_desc = desc;
    }

    void AddHeader(const std::string &header)
    {
        _resp_header.emplace_back(header);
    }

    void AddContent(const std::string &content)
    {
        _resp_content = content;
    }

    std::string Serialize()
    {
        std::string res = _status_line + HttpSeq;
        for (auto &header : _resp_header)
            res += header;
        res += _resp_blank;
        res += _resp_content;
        // std::cout << res << std::endl;
        return res;
    }

private:
    std::string _status_line;
    std::vector<std::string> _resp_header;
    std::string _resp_blank;
    std::string _resp_content;

    std::string _version;          // 版本号
    int _status_code;              // 状态码
    std::string _status_code_desc; // 状态信息
};

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

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

相关文章

英语学习笔记7——Are you a teacher?

Are you a teacher? 你是教师吗&#xff1f; 词汇 Vocabulary name /neɪm/ n. 名字&#xff0c;名声 英文名字构成&#xff1a; 名 字 姓      given name family name  也叫做&#xff1a;first name last name      例&#xff1a;Yanyan Gao 例句&#xff1…

Baidu Comate智能编码助手-程序员的神助攻

&#x1f389;Baidu Comate:程序员编程最牛的辅助利器&#xff0c;没有之一 &#x1f388;AI编程助力开发者提质增效 智能代码补全&#xff1a;AI编程助手可以根据上下文和用户的编码习惯&#xff0c;智能地提供代码补全和建议&#xff0c;帮助程序员更快速地编写代码&#xf…

Service 和 Ingress

文章目录 Service 和 IngressServiceEndpointservice 的定义代理集群外部服务反向代理外部域名Service 常用类型 IngressIngress-nginx安装使用 Service 和 Ingress service 和 ingress 是kubernetes 中用来转发网络请求的两个服务&#xff0c;两个服务用处不同&#xff0c;se…

OpenGL 入门(四)—— 贴纸与美颜滤镜

本篇我们来介绍贴纸效果与美颜滤镜的实现。 1、贴纸效果 贴纸实际上是一个图片&#xff0c;用 Bitmap 加载图片后用 OpenGL 渲染到指定的位置上。我们举例添加一个耳朵贴纸&#xff1a; 1.1 获取人脸位置 上一篇我们在讲大眼滤镜时&#xff0c;在 Native 层除了获取到人脸 5…

JAVA学习笔记(第三周)

文章目录 继承概述使用场景继承的特点子类继承的内容成员变量访问特点成员方法访问特点方法的重写构造方法this super 多态多态的表现形式多态的前提成员变量和方法调用instanceof优势弊端 包包名的规则全类名final常量 权限修饰符代码块 继承 概述 继承就是子类继承父类的特征…

PHP ASCII码的字符串用mb_convert_encoding 转utf-8之后不生效

检测数据类型是ascii,转码之后再检测还是utf-8没生效 private function toUTF8($str){$encode mb_detect_encoding($str, array("ASCII",UTF-8,"GB2312","GBK",BIG5,LATIN1));if ($encode ! UTF-8) {$str1 mb_convert_encoding($str, UTF-8, …

(2024,LSTM,Transformer,指数门控,归一化器状态,多头内存混合)xLSTM:扩展的 LSTM

xLSTM: Extended Long Short-Term Memory 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 1. 简介 2. 扩展的 LSTM 2.1 LSTM 回顾 2.2 sLSTM 2.3 mLSTM 2.4 xLSTM 架构 2…

python:画饼图

我现在因工作需要在写一篇中文文章&#xff0c;领导要我用python处理数据和画图&#xff0c;那我也刚好学习一下python画图。 import matplotlib.pyplot as plt # 饼图数据 labels [A, B, C, D] sizes [15, 30, 45, 10] # 每个部分的大小 # 绘制饼图 plt.figure(figsize(6,…

读书笔记——《高质量C++/C编程指南》(2)

目录 前言 命名规则 共性规则 简单的Windows应用程序命名规则 表达式和基本语句 运算符优先级 复合表达式 if语句 布尔变量与零值比较 整型变量与零值比较 浮点变量与零值比较 指针变量与零值比较 对if 语句的补充说明 循环语句的效率 for 语句的循环控制变量 s…

数据库大作业——基于qt开发的图书管理系统(四)项目目录的整理与绘制登录页面

项目目录的管理 前言 在上几篇的文章里面我们完成了基本环境的搭建,整理了项目数据库表结构并且成功的手动的加载了Qt的mysql数据库驱动&#xff0c;现在就要开始完成项目准备工作的最后一步:构建项目目录,一个好的项目离不开一个好的代码组织结构,所以在开始动手写我们这个项…

Java | Leetcode Java题解之第70题爬楼梯

题目&#xff1a; 题解&#xff1a; public class Solution {public int climbStairs(int n) {double sqrt5 Math.sqrt(5);double fibn Math.pow((1 sqrt5) / 2, n 1) - Math.pow((1 - sqrt5) / 2, n 1);return (int) Math.round(fibn / sqrt5);} }

无人机+通信中继:短波电台技术详解

随着无线通信技术的不断发展&#xff0c;无人机作为一种新型的信息传输平台&#xff0c;已经在多个领域得到了广泛应用。其中&#xff0c;无人机与短波电台的结合&#xff0c;为通信中继领域带来了全新的可能性。本文将详细解析无人机在通信中继中的应用&#xff0c;以及短波电…

产品专访|“产品”远程运维系统与“设备”远程运维系统的区别?

在日益复杂的工业制造环境下&#xff0c;远程运维已经成为生产制造企业不可或缺的一部分。在这个大背景下&#xff0c;产品远程运维系统和设备远程运维系统的需求越来越多&#xff0c;各自发挥着独特的作用。然而&#xff0c;尽管它们都涉及到远程运维的概念&#xff0c;但在实…

Nest.js中使用任务调度

java中的xxl在nestJs中是有内置的任务调度nestjs/schedule npm install --save nestjs/schedule 在model中引入使用 在service中直接使用就行 具体间隔多久看官方配置 Task Scheduling | NestJS 中文文档 | NestJS 中文网

STM32F1#1(入门了解)

一、STM32开发平台和工具 1.1 STM32芯片介绍 典型微控制器由CPU&#xff08;运算器、控制器&#xff09;、RAM、ROM和输入输出组成。 1.2 STM32核心板 STM32核心板配件&#xff1a; ①JTAG/SWD仿真-下载器 ②通信-下载模块 ③OLED显示屏 1&#xff09; 通信-下载模…

智慧工厂管理系统

随着科技的飞速发展&#xff0c;传统工厂正经历着一场前所未有的变革。在这个以智能化、信息化为主导的新时代&#xff0c;HiWoo Cloud平台以其卓越的智慧工厂管理系统&#xff0c;成为了众多企业转型升级的首选工具。今天&#xff0c;就让我们一起走进HiWoo Cloud的世界&#…

FTTR(光猫)ITMS注册NCE纳管

ITMS注册 TR069交互过程&#xff1a; 1.1. TR069交互—主动连接机制 主动连接机制是指CPE主动发出请求连接事件(事件可以为&#xff1a; 0 BOOTSTRAP&#xff1b; 1 BOOT; PERIODIC等等)给ACS。在连接建立之后才能进行业务处理(通过调用RPC方法实现)。 备注&#xff1a;政企…

【2024最新华为OD-C卷试题汇总】字符串分割(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; 文章目录 前…

2024.5.8

聊天框完善 #include "mywidget.h" #include "ui_mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent), ui(new Ui::MyWidget) {ui->setupUi(this);//设置窗口大小this->resize(400,560);//设置窗口图标和标题this->setWindowTit…

快过VS Code,10天暴增20k star,高性能多人协作IDE横空出世

道歉 其实不意味着道歉的人错了 而是他认为这段关系 比自己的尊严更重要 失败了 不是说你有多差 而是说 你需要更努力了 写代码最重要的一个选择就是选哪个IDE了&#xff0c;目前主流的选择是vscode和IDEA了。 但是vscode虽然轻量&#xff0c;但是对于大型的项目仍然显得…