http协议补充

7.7实现http请求

class httprequest
{
public:
    void Deserialize(std::string content)
    {
        while (true)
        {
            auto pos = content.find(sep);
            if (pos == std::string::npos)
            {
                break;
            }
            std::string temp = content.substr(0, pos);
            if (temp.empty())
            {
                break;
            }
            req_header_.push_back(temp);
            content.erase(0, pos + sep.size());
        }
        auto pos = content.find(sep);
        text_ = content.substr(pos + sep.size());
    }
    void parse()
    {
        std::stringstream sstr(req_header_[0]);
        sstr >> method_ >> url_ >> httpversion_; // 默认以空格分割
        path_ = wwwroot;
        if (url_ == "/" || url_ == "/index.html")
        {
            path_ += "/";
            path_ += homepage;
        }
        else
        {
            path_ += url_;
        }
    }
    void debugprint()
    {
        std::cout << "---------------------" << std::endl;
        for (auto &e : req_header_)
        {
            std::cout << e << std::endl;
        }
        std::cout << text_ << std::endl;
        std::cout << "method: " << method_ << std::endl;
        std::cout << "url: " << url_ << std::endl;
        std::cout << "http_version: " << httpversion_ << std::endl;
        std::cout << "path: " << path_ << std::endl;
        std::cout << "---------------------" << std::endl;
    }

public:
    std::vector<std::string> req_header_;
    std::string text_;

    std::string method_;
    std::string url_;
    std::string httpversion_;
    std::string path_;
};

7.8http细节

http的方法

GET 获取资源
//提交的参数使用拼接到url结尾的方式提交;参数数量受限且不安全;
POST 传输实体主体
//提交的参数是放在了请求正文部分;
CONNECT 用隧道协议建立代理

​ 数据都是通过表单提交的;

http状态码

在这里插入图片描述

​ 常见的如200 OK,404 Not Found;

​ 对于浏览器标准是有点的,但是支持的并不是很好;

​ 对于重定向包括临时重定向和永久重定向,浏览器发送请求,服务器不是直接提供服务,而是返回一个响应;响应报头是3XX,location里是一个新的地址;浏览器收到后会重新向新地址发起一个请求;

​ 临时重定向就是还是每次都要先访问服务器,然后服务器重定向,使用场景如:登录界面成功后跳转;

response_line = "HTTP/1.0 302 Found\r\n";
std::string response_header = "Content-Length: ";
response_header += std::to_string(text.size());
response_header += "\r\n";
response_header += "Location: https://www.qq.com\r\n";
response_header += "\r\n";

http常见的报头

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

​ 一个页面是包含非常多的元素的,每个元素就是一个资源;

​ 对于一个请求响应一个资源,然后关闭连接是短连接,http/1.0支持的就是短连接;而只建立一个连接,发送多个请求和响应是长连接,http/1.1支持的就是长连接;

​ http协议默认是无状态的;http有对登录用户的会话保持功能;

​ 响应报头中有Set - Cookie字段,设置了属性值,发送给浏览器保存起来,这种保存了属性值的文件叫做cookie文件;浏览器每一次向该服务发起请求时,都会携带cookie文件中的内容;保存cookie文件一般有有文件级的方式iye有内存级的方式;对于内存级设计,浏览器启动后就变成了一个进程,在进程当中是可以new空间的,可以将cookie的内容保存在进程的内存当中,不往磁盘上写;如果是文件级设计会直接将cookie信息保存到文件当中;这个文件被保存的浏览器特定的安装路径下; cookie文件会自动删除;

​ 响应的cookie设置,“Set-Cookie: value=123\r\n”,如果是n个参数就需要设计n个Set-Cookie;请求的cookie设置,"Set-Cookie: value=123&&abd=456\r\n"支持多个参数用&&连接;

​ qq邮箱登录也是使用了类似http协议的方式,在跳转邮箱的时候,会携带cookie文件,这样就会让恶意用户获取cookie文件,导致:1.cookie文件被盗取;2.个人私有信息泄露;

​ 为了解决上述问题,使用了如下方案:浏览器发起了登录请求,服务端进行了认证之后生成一个session文件(保存了用户登陆的相关内容)同时还生成了唯一的session id(是一个字符序列)用来给session文件命名;之后会设置Set-Cookie:字段,将session id发送回浏览器;这样就使得浏览器的cookie文件内容变成了id而不是具体的私密属性;这样就保证了私密信息不会泄露,但是还是可以让别人拿到session id进行访问;对于这种访问是难以避免的,但是可以采取一些策略解决小部分问题,如:检测短时间内异地登陆,会向浏览器发起认证请求,失败了就将session文件的id暂停,要求用户重新登陆,失败了就系那个session文件删除;

​ session文件也要进行管理,设置属性结构体和数据结构进行维护;将这些文件用redis集群进行管理,使用redis提供的数据结构进行维护;

​ 总结:cookie文件使得浏览器与服务端能有会话保持的功能,但是会产生一系列安全问题,需要在服务端构建session文件进行维护并且设计访问session文件的访问策略,这样会存在问题,但是增加了用户使用浏览器的体验;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值