Skip to content

Commit 48783b6

Browse files
committed
fix(http): 1.12.8, 解决RequestParser将header为空当成格式异常的问题
1 parent 879796d commit 48783b6

8 files changed

+120
-114
lines changed

modules/http/server/middlewares/file_downloader_middleware.cpp

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -36,34 +36,34 @@ namespace server {
3636

3737
namespace {
3838
bool IsPathSafe(const std::string& path) {
39-
// 检查是否有".."路径组件,这可能导致目录遍历
39+
//! 检查是否有".."路径组件,这可能导致目录遍历
4040
std::istringstream path_stream(path);
4141
std::string component;
4242

4343
while (std::getline(path_stream, component, '/')) {
4444
if (component == "..")
45-
return false; // 不允许上级目录访问
45+
return false; //! 不允许上级目录访问
4646
}
4747

4848
return true;
4949
}
5050
}
5151

52-
// 目录配置项
52+
//! 目录配置项
5353
struct DirectoryConfig {
54-
std::string url_prefix; // URL前缀
55-
std::string local_path; // 本地路径
56-
std::string default_file; // 默认文件
54+
std::string url_prefix; //! URL前缀
55+
std::string local_path; //! 本地路径
56+
std::string default_file; //! 默认文件
5757
};
5858

59-
// 中间件私有数据结构
59+
//! 中间件私有数据结构
6060
struct FileDownloaderMiddleware::Data {
6161
eventx::WorkThread worker;
62-
std::vector<DirectoryConfig> directories; // 目录配置列表
63-
std::map<std::string, std::string> path_mappings;// 特定路径映射
64-
std::map<std::string, std::string> mime_types; // MIME类型映射
65-
std::string default_mime_type; // 默认MIME类型
66-
bool directory_listing_enabled; // 是否允许目录列表
62+
std::vector<DirectoryConfig> directories; //! 目录配置列表
63+
std::map<std::string, std::string> path_mappings;//! 特定路径映射
64+
std::map<std::string, std::string> mime_types; //! MIME类型映射
65+
std::string default_mime_type; //! 默认MIME类型
66+
bool directory_listing_enabled; //! 是否允许目录列表
6767
size_t switch_to_worker_filesize_threshold;
6868

6969
Data(event::Loop *wp_loop)
@@ -72,7 +72,7 @@ struct FileDownloaderMiddleware::Data {
7272
, directory_listing_enabled(false)
7373
, switch_to_worker_filesize_threshold(100 << 10)
7474
{
75-
// 初始化常见MIME类型
75+
//! 初始化常见MIME类型
7676
mime_types["html"] = "text/html";
7777
mime_types["htm"] = "text/html";
7878
mime_types["css"] = "text/css";
@@ -109,25 +109,25 @@ FileDownloaderMiddleware::~FileDownloaderMiddleware() { delete d_; }
109109
bool FileDownloaderMiddleware::addDirectory(const std::string& url_prefix,
110110
const std::string& local_path,
111111
const std::string& default_file) {
112-
// 验证URL前缀是否以'/'开头
112+
//! 验证URL前缀是否以'/'开头
113113
if (url_prefix.empty() || url_prefix[0] != '/') {
114114
LogErr("Invalid URL prefix: %s. Must start with '/'", url_prefix.c_str());
115115
return false;
116116
}
117117

118-
// 验证本地路径是否存在且是目录
118+
//! 验证本地路径是否存在且是目录
119119
if (!util::fs::IsDirectoryExist(local_path)) {
120120
LogErr("Invalid local path: %s. Directory does not exist", local_path.c_str());
121121
return false;
122122
}
123123

124-
// 添加到目录列表
124+
//! 添加到目录列表
125125
DirectoryConfig config;
126126
config.url_prefix = url_prefix;
127127
config.local_path = local_path;
128128
config.default_file = default_file;
129129

130-
// 确保本地路径以'/'结尾
130+
//! 确保本地路径以'/'结尾
131131
if (!config.local_path.empty() && config.local_path.back() != '/')
132132
config.local_path += '/';
133133

@@ -155,101 +155,101 @@ void FileDownloaderMiddleware::setMimeType(const std::string& ext, const std::st
155155
void FileDownloaderMiddleware::handle(ContextSptr sp_ctx, const NextFunc& next) {
156156
const auto& request = sp_ctx->req();
157157

158-
// 只处理GET和HEAD请求
158+
//! 只处理GET和HEAD请求
159159
if (request.method != Method::kGet && request.method != Method::kHead) {
160160
next();
161161
return;
162162
}
163163

164164
const std::string& request_path = request.url.path;
165165

166-
// 检查特定路径映射
166+
//! 检查特定路径映射
167167
auto mapping_it = d_->path_mappings.find(request_path);
168168
if (mapping_it != d_->path_mappings.end()) {
169169
if (respondFile(sp_ctx, mapping_it->second))
170170
return;
171171
}
172172

173-
// 查找匹配的目录配置
173+
//! 查找匹配的目录配置
174174
for (const auto& dir : d_->directories) {
175-
// 检查URL是否以该目录前缀开头
175+
//! 检查URL是否以该目录前缀开头
176176
if (request_path.find(dir.url_prefix) == 0) {
177-
// 获取相对路径部分
177+
//! 获取相对路径部分
178178
std::string rel_path = request_path.substr(dir.url_prefix.length());
179179

180-
// 如果路径以'/'开头,去掉这个斜杠避免双斜杠
180+
//! 如果路径以'/'开头,去掉这个斜杠避免双斜杠
181181
if (!rel_path.empty() && rel_path[0] == '/')
182182
rel_path = rel_path.substr(1);
183183

184-
// 构造本地文件路径
184+
//! 构造本地文件路径
185185
std::string file_path = dir.local_path + rel_path;
186186

187-
// 检查路径安全性
187+
//! 检查路径安全性
188188
if (!IsPathSafe(file_path)) {
189189
LogWarn("Unsafe path detected: %s", file_path.c_str());
190190
sp_ctx->res().status_code = StatusCode::k403_Forbidden;
191191
return;
192192
}
193193

194194
auto file_type = util::fs::GetFileType(file_path);
195-
// 检查路径是否是目录
195+
//! 检查路径是否是目录
196196
if (file_type == util::fs::FileType::kDirectory) {
197-
// 如果是目录且路径不以'/'结尾,进行重定向
197+
//! 如果是目录且路径不以'/'结尾,进行重定向
198198
if (!request_path.empty() && request_path.back() != '/') {
199199
sp_ctx->res().status_code = StatusCode::k301_MovedPermanently;
200200
sp_ctx->res().headers["Location"] = request_path + "/";
201201
return;
202202
}
203203

204-
// 尝试访问默认文件
204+
//! 尝试访问默认文件
205205
std::string default_file_path = file_path + dir.default_file;
206206
if (util::fs::GetFileType(default_file_path) == util::fs::FileType::kRegular) {
207207
if (respondFile(sp_ctx, default_file_path))
208208
return;
209209
}
210210

211-
// 如果允许目录列表,生成目录内容
211+
//! 如果允许目录列表,生成目录内容
212212
if (d_->directory_listing_enabled) {
213213
if (respondDirectory(sp_ctx, file_path, request_path))
214214
return;
215215
}
216216

217-
// 否则返回403 Forbidden
217+
//! 否则返回403 Forbidden
218218
LogNotice("Directory listing disabled for: %s", file_path.c_str());
219219
sp_ctx->res().status_code = StatusCode::k403_Forbidden;
220220
return;
221221

222222
} else if (file_type == util::fs::FileType::kRegular) {
223-
// 如果是普通文件,直接响应文件内容
223+
//! 如果是普通文件,直接响应文件内容
224224
if (respondFile(sp_ctx, file_path))
225225
return;
226226
}
227227
}
228228
}
229229

230-
// 如果没有找到匹配的文件,传递给下一个中间件
230+
//! 如果没有找到匹配的文件,传递给下一个中间件
231231
next();
232232
}
233233

234234
std::string FileDownloaderMiddleware::getMimeType(const std::string& filename) const {
235-
// 查找最后一个点的位置
235+
//! 查找最后一个点的位置
236236
size_t dot_pos = filename.find_last_of('.');
237237
if (dot_pos != std::string::npos) {
238238
std::string ext = util::string::ToLower(filename.substr(dot_pos + 1));
239-
// 在MIME类型映射中查找
239+
//! 在MIME类型映射中查找
240240
auto it = d_->mime_types.find(ext);
241241
if (it != d_->mime_types.end())
242242
return it->second;
243243
}
244244

245-
// 未找到匹配的MIME类型,返回默认值
245+
//! 未找到匹配的MIME类型,返回默认值
246246
return d_->default_mime_type;
247247
}
248248

249249
bool FileDownloaderMiddleware::respondFile(ContextSptr sp_ctx, const std::string& file_path) {
250250
auto& res = sp_ctx->res();
251251

252-
// 打开文件
252+
//! 打开文件
253253
std::ifstream file(file_path, std::ios::binary | std::ios::ate);
254254
if (!file.is_open()) {
255255
res.status_code = StatusCode::k404_NotFound;
@@ -258,11 +258,11 @@ bool FileDownloaderMiddleware::respondFile(ContextSptr sp_ctx, const std::string
258258

259259
res.headers["Content-Type"] = getMimeType(file_path);
260260

261-
// 获取文件大小
261+
//! 获取文件大小
262262
size_t file_size = static_cast<size_t>(file.tellg());
263263
file.seekg(0, std::ios::beg);
264264

265-
// 如果是HEAD请求,不返回内容
265+
//! 如果是HEAD请求,不返回内容
266266
if (sp_ctx->req().method == Method::kHead) {
267267
res.status_code = StatusCode::k200_OK;
268268
res.headers["Content-Length"] = std::to_string(file_size);
@@ -302,7 +302,7 @@ bool FileDownloaderMiddleware::respondDirectory(ContextSptr sp_ctx,
302302
const std::string& dir_path,
303303
const std::string& url_path) {
304304
try {
305-
// 生成HTML目录列表
305+
//! 生成HTML目录列表
306306
std::stringstream html;
307307
html << "<!DOCTYPE html>\n"
308308
<< "<html>\n"
@@ -322,7 +322,7 @@ bool FileDownloaderMiddleware::respondDirectory(ContextSptr sp_ctx,
322322
<< " <h1>Directory listing for " << url_path << "</h1>\n"
323323
<< " <ul>\n";
324324

325-
// 如果不是根目录,添加返回上级目录的链接
325+
//! 如果不是根目录,添加返回上级目录的链接
326326
if (url_path != "/") {
327327
size_t last_slash = url_path.find_last_of('/', url_path.size() - 2);
328328
if (last_slash != std::string::npos) {
@@ -331,7 +331,7 @@ bool FileDownloaderMiddleware::respondDirectory(ContextSptr sp_ctx,
331331
}
332332
}
333333

334-
// 列出目录中的项目
334+
//! 列出目录中的项目
335335
std::vector<std::string> entries;
336336
if (!util::fs::ListDirectory(dir_path, entries)) {
337337
LogErr("Failed to list directory: %s", dir_path.c_str());
@@ -355,7 +355,7 @@ bool FileDownloaderMiddleware::respondDirectory(ContextSptr sp_ctx,
355355
<< "</body>\n"
356356
<< "</html>";
357357

358-
// 设置响应
358+
//! 设置响应
359359
auto& res = sp_ctx->res();
360360
res.status_code = StatusCode::k200_OK;
361361
res.headers["Content-Type"] = "text/html; charset=utf-8";

modules/http/server/middlewares/form_data.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,16 @@ namespace server {
3333
*/
3434
struct FormItem {
3535
enum class Type {
36-
kField, // 普通字段
37-
kFile // 文件
36+
kField, //! 普通字段
37+
kFile //! 文件
3838
};
3939

4040
Type type = Type::kField;
41-
std::string name; // 字段名称
42-
std::string value; // 字段值(对于普通字段)
43-
std::string filename; // 文件名(对于文件)
44-
std::string content_type; // 内容类型
45-
std::map<std::string, std::string> headers; // 其他头部信息
41+
std::string name; //! 字段名称
42+
std::string value; //! 字段值(对于普通字段)
43+
std::string filename; //! 文件名(对于文件)
44+
std::string content_type; //! 内容类型
45+
std::map<std::string, std::string> headers; //! 其他头部信息
4646
};
4747

4848
/**
@@ -95,7 +95,7 @@ class FormData {
9595

9696
private:
9797
std::vector<FormItem> items_;
98-
std::map<std::string, std::vector<size_t>> name_index_; // 名称到索引的映射
98+
std::map<std::string, std::vector<size_t>> name_index_; //! 名称到索引的映射
9999
};
100100

101101
}

0 commit comments

Comments
 (0)