Ai
1 Star 0 Fork 0

Aurora/Linux

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
HttpProtocol.hpp 5.47 KB
一键复制 编辑 原始数据 按行查看 历史
Aurora 提交于 2025-07-11 13:06 +08:00 . http version3
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <unordered_map>
#include "Common.hpp"
const std::string Sep = "\r\n";
const std::string LineSep = " ";
const std::string HeaderLineSep = ": ";
const std::string BlankLine = Sep;
const std::string defaulthomepage = "wwwroot";
const std::string http_version = "HTTP/1.0";
const std::string page404 = "wwwroot/404.html";
const std::string firstpage = "index.html";
// B/S模式 S客户端就是浏览器
class HttpRequest
{
public:
HttpRequest() {}
~HttpRequest() {}
// GET / HTTP/1.1
// Host: 112.126.76.148:8080
// Connection: keep-alive
// Cache-Control: max-age=0
// Upgrade-Insecure-Requests: 1
// User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
// Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
// Accept-Encoding: gzip, deflate
// Accept-Language: zh-CN,zh;q=0.9
bool ParseHeaderkv()
{
std::string key,value;
for(auto &header : _req_header)
{
// Connection: keep-alive
if(SplitString(header,HeaderLineSep,&key,&value))
{
_headerkv.insert(std::make_pair(key,value));
}
}
return true;
}
bool ParseHeader(std::string &request_str)
{
std::string line;
while(true)
{
bool r = ParseOneLine(request_str,&line,Sep);
if(r && !line.empty())
{
_req_header.push_back(line);
}
else if(r && line.empty())
{
_blank_line = Sep;
break;
}
else
{
return false;
}
}
ParseHeaderkv();
return true;
}
void Deserialize(std::string &request_str)
{
if (ParseOneLine(request_str, &_req_line, Sep))
{
// 提取请求行中的详细字段
ParseReqLine(_req_line, LineSep);
ParseHeader(request_str);
_body = request_str;
}
}
std::string GetContent()
{
// 暂时做法
std::string content;
std::ifstream in(_uri);
if(!in.is_open()) return std::string();
std::string line;
while(std::getline(in,line))
{
content += line;
}
in.close();
return content;
}
void Print()
{
std::cout << "_method: " << _method << std::endl;
std::cout << "_uri: " << _uri << std::endl;
std::cout << "_version: " << _version << std::endl;
// for(auto &line : _req_header)
// {
// std::cout << line << "\n" << std::endl;
// }
for(auto &kv : _headerkv)
{
std::cout << kv.first << "#" << kv.second << std::endl;
}
std::cout << "_blank_line: " << _blank_line << std::endl;
std::cout << "_body: " << _body << std::endl;
}
std::string Uri()
{
return _uri;
}
void SetUri(const std::string newuri)
{
_uri = newuri;
}
private:
void ParseReqLine(std::string &_req_line, const std::string sep)
{
(void)sep;
std::stringstream ss(_req_line);
ss >> _method >> _uri >> _version;
_uri = defaulthomepage + _uri;
}
private:
std::string _req_line;
std::vector<std::string> _req_header;
std::string _blank_line;
std::string _body;
// 在反序列化的过程中,细化我们解析出来的字段
std::string _method;
std::string _uri; // 用户想要这个
std::string _version;
std::unordered_map<std::string,std::string> _headerkv;
};
class HttpResponse
{
public:
HttpResponse() : _version(http_version),_blank_line(Sep)
{}
~HttpResponse()
{}
void Build(HttpRequest &req)
{
std::string uri = req.Uri();
if(uri.back() == '/')
{
uri += firstpage; // wwwroot/index.html
req.SetUri(uri);
}
_content = req.GetContent();
if(_content.empty())
{
// 用户请求的资源并不存在
_status_code = 404;
req.SetUri(page404);
_content = req.GetContent();
}
else
{
_status_code = 200;
}
_status_desc = Code2Desc(_status_code); // 和状态码是强相关的
}
void Seserialize(std::string *resp_str)
{
_resp_line = _version + LineSep + std::to_string(_status_code) + LineSep + _status_desc + Sep;
_body = _content;
//序列化
*resp_str = _resp_line;
for(auto &line : _resp_header)
{
*resp_str += (line + Sep);
}
*resp_str += _blank_line;
*resp_str += _body;
}
private:
std::string Code2Desc(int code)
{
switch(code)
{
case 200:
return "OK";
case 404:
return "Not Found";
default:
return std::string();
}
}
private:
// 必备的要素
std::string _version;
int _status_code;
std::string _status_desc;
std::string _content;
// 最终要这四部分,,构建应答
std::string _resp_line;
std::vector<std::string> _resp_header;
std::string _blank_line;
std::string _body;
};
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/Axurea/linux.git
git@gitee.com:Axurea/linux.git
Axurea
linux
Linux
master

搜索帮助