216 lines
5.7 KiB
C++
216 lines
5.7 KiB
C++
#ifndef CCWeb_Request_H
|
||
#define CCWeb_Request_H
|
||
#pragma once
|
||
|
||
#include "CORS.h"
|
||
#include "CCNetwork.h"
|
||
#include "CCHttpResolver.h"
|
||
#include "CC.h"
|
||
#include "CCThread.h"
|
||
#include "CCFile.h"
|
||
#include "CCObject.h"
|
||
#include <CCFIleInStream.h>
|
||
#include <CCFileOutStream.h>
|
||
|
||
#include <utility>
|
||
#include "CCJSONObject.h"
|
||
#include "openssl/ssl.h"
|
||
#include "openssl/err.h"
|
||
#include "HttpSocketChannel.h"
|
||
#include "EventLoop.h"
|
||
|
||
namespace CTL {
|
||
// 请求数据结构体,用于存储HTTP请求的相关信息
|
||
struct RequestData_t{
|
||
CTL::String RawData; // 原始请求数据
|
||
CTL::String Method; // HTTP方法(GET, POST等)
|
||
CTL::String Path; // 请求路径
|
||
CTL::String Version; // HTTP版本
|
||
CCMap<CTL::String, CTL::String> Headers; // 请求头信息
|
||
CCMap<StdString, StdString> Params; // 请求参数
|
||
CTL::String Body; // 请求体内容
|
||
CCVector<char> Buffer; // 数据缓冲区
|
||
CTL::String Buf; // 临时缓冲区
|
||
CCMap<CTL::String, CTL::String> FileHeaders; // 文件头信息
|
||
};
|
||
|
||
/**
|
||
* 请求类,用于处理HTTP请求
|
||
*/
|
||
class Request{
|
||
using ReceiveFileCallback = std::function<bool(const CCVector<char>&, size_t)>;
|
||
inline static CCMutex File_Mutex_T;
|
||
inline static std::atomic_uint8_t IsRun = 0;
|
||
inline static int MAX_UPLOAD_FILE_CONCURRENT = 10;
|
||
// CORS对象指针
|
||
CORS* cors = nullptr;
|
||
// int File_Buffer_Max = 4096;
|
||
bool IsFileUploadSize = true;
|
||
HttpSocketChannel* channel = nullptr;
|
||
public:
|
||
/**
|
||
* 默认构造函数
|
||
*/
|
||
Request() = default;
|
||
|
||
/**
|
||
* 请求数据成员变量
|
||
*/
|
||
RequestData_t RequestData;
|
||
|
||
/**
|
||
* 获取请求参数的值
|
||
* @param key 参数键名
|
||
* @param Body 是否从Body中获取参数
|
||
* @return 参数对应的值
|
||
*/
|
||
CTL::String GetParameter(const CTL::String& key,bool Body = false);
|
||
|
||
/**
|
||
* 获取文件信息
|
||
* @param key 文件键名
|
||
* @return 文件信息
|
||
*/
|
||
CTL::String GetFileInfo(const CTL::String& key);
|
||
|
||
/**
|
||
* 获取请求头信息
|
||
* @param key 请求头键名
|
||
* @return 请求头对应的值
|
||
*/
|
||
CTL::String GetHeader(const CTL::String& key);
|
||
|
||
/**
|
||
* 获取JSON对象
|
||
* @return JSON对象
|
||
*/
|
||
[[nodiscard]] CTL::JSONObject GetJson() const;
|
||
|
||
/**
|
||
* 获取媒体文件
|
||
* @param Path 文件路径
|
||
* @return 是否成功获取文件
|
||
*/
|
||
bool GetMediaFiles(const CTL::String& Path);
|
||
|
||
/**
|
||
* 获取媒体文件
|
||
* @param callback 接收数据回调函数 --> bool --> CCVector<char> --> size_t
|
||
* @return 是否执行成功
|
||
*/
|
||
bool GetMediaFiles(const ReceiveFileCallback& callback);
|
||
|
||
/**
|
||
* 初始化请求对象
|
||
* @param channel 客户端套接字
|
||
* @param cors CORS对象指针
|
||
*/
|
||
void Init(HttpSocketChannel* channel, CORS* cors);
|
||
|
||
/**
|
||
* 获取文件后缀名
|
||
* @param filePath 文件路径
|
||
* @return 文件后缀名
|
||
*/
|
||
static CTL::String GetFileSuffix(const CTL::String& filePath);
|
||
|
||
/**
|
||
* 获取文件类型
|
||
* @param str 文件路径或名称
|
||
* @return 文件类型
|
||
*/
|
||
static CTL::String GetFileType(const CTL::String& str);
|
||
|
||
/**
|
||
* 获取文件大小
|
||
* @param path 文件路径
|
||
* @return 文件大小
|
||
*/
|
||
static unsigned int GetFileSize(const CTL::String& path);
|
||
|
||
/**
|
||
* URL解码
|
||
* @param in 需要解码的字符串
|
||
* @return 解码后的字符串
|
||
*/
|
||
static CTL::String URL_Decode(const CTL::String& in);
|
||
|
||
/**
|
||
* 获取文件日期头信息
|
||
* @param in 输入字符串
|
||
* @param map 存储解析结果的映射表
|
||
* @return 处理后的字符串
|
||
*/
|
||
static CTL::String GetFileDateHeader(CTL::String& in, std::map<CTL::String, CTL::String>& map);
|
||
|
||
/**
|
||
* 获取表单数据
|
||
* @param input 输入字符串
|
||
* @param key 键名
|
||
* @param value 键值
|
||
*/
|
||
static void GetFormData(CTL::String& input, CTL::String& key, CTL::String& value);
|
||
|
||
/**
|
||
* 解析键值对
|
||
* @param input 输入字符串
|
||
* @return 键值对映射表
|
||
*/
|
||
static CCMap<CTL::String, CTL::String> parseKeyValuePairs(const CTL::String& input);
|
||
|
||
/**
|
||
* 解析键值对
|
||
* @param Num 最大文件上传并发数
|
||
*/
|
||
static void SetMaxConcurrentFileUploads(int Num);
|
||
|
||
/**
|
||
* 解析键值对
|
||
* @param Size 设置文件上传接收缓冲区大小
|
||
*/
|
||
void SetFileUploadSize(int Size);
|
||
private:
|
||
static void FileWriting(const CTL::String& path,const CCVector<char>& buffer, size_t size);
|
||
static String getFileName(const CTL::String& contentDisposition);
|
||
};
|
||
|
||
class BoundaryMatcher {
|
||
String boundary_pattern;
|
||
size_t matched_length = 0;
|
||
public:
|
||
explicit BoundaryMatcher(String pattern) : boundary_pattern(std::move(pattern)) {}
|
||
bool match_data(const CCVector<char>& data) {
|
||
for (const char i : data) {
|
||
if (matched_length < boundary_pattern.length() &&
|
||
i == boundary_pattern[matched_length]) {
|
||
matched_length++;
|
||
if (matched_length == boundary_pattern.length()) {
|
||
return true; // 完全匹配
|
||
}
|
||
}
|
||
else {
|
||
matched_length = 0; // 不匹配时重置
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
void reset() {
|
||
matched_length = 0;
|
||
}
|
||
[[nodiscard]] size_t get_matched_length() const {
|
||
return matched_length;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 获取请求头信息
|
||
* @param key 请求头键名
|
||
* @return 请求头对应的值
|
||
*/
|
||
inline CTL::String Request::GetHeader(const CTL::String& key) {
|
||
return RequestData.Headers[key];
|
||
}
|
||
}
|
||
|
||
#endif
|