Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2afd947d0 | ||
|
|
cfde1b4306 | ||
|
|
0a4e5d50f3 |
+83
-4
@@ -399,13 +399,20 @@ fn parse_http_request_usockets(raw string) (string, string, map[string]string, s
|
||||
|
||||
// 4. 检测 HTTP 版本 - "HTTP/1.0" vs "HTTP/1.1"
|
||||
// 请求行格式: "GET /path HTTP/1.1\r\n"
|
||||
// HTTP/1.x 版本字符串固定为 8 字符,直接检查第 8 个字符
|
||||
mut version_start := path_end + 1
|
||||
for version_start < line_end && raw[version_start] == ` ` {
|
||||
version_start++
|
||||
}
|
||||
if version_start < line_end {
|
||||
version_str := raw[version_start..line_end]
|
||||
is_http11 = !version_str.contains('1.0')
|
||||
// "HTTP/1.0" 或 "HTTP/1.1",检查索引 7 的字符(0-based)
|
||||
if version_start + 7 < line_end {
|
||||
is_http11 = raw[version_start + 7] != `0`
|
||||
}
|
||||
|
||||
// 对于 HTTP/1.0,检查 Connection 头是否包含 keep-alive
|
||||
// 参考 Go net/http: wantsHttp10KeepAlive() 只检查 Connection 头的值
|
||||
if !is_http11 {
|
||||
is_http11 = has_connection_keep_alive(raw, line_end, len)
|
||||
}
|
||||
|
||||
// 5. 查找 body(\r\n\r\n 之后)
|
||||
@@ -421,7 +428,79 @@ fn parse_http_request_usockets(raw string) (string, string, map[string]string, s
|
||||
return method, path, query_map, body, is_http11
|
||||
}
|
||||
|
||||
// 快速解析 query string(单次遍历,避免 split)
|
||||
// 检查 Connection 头是否包含 keep-alive(参考 Go net/http 实现)
|
||||
// 只检查 "Connection:" 头的值,避免误判请求体中的内容
|
||||
@[inline]
|
||||
fn has_connection_keep_alive(raw string, headers_start int, len int) bool {
|
||||
mut i := headers_start
|
||||
|
||||
// 遍历每一行头部
|
||||
for i < len - 12 { // 至少需要 "Connection:" + 一些值
|
||||
// 跳过 \r\n
|
||||
if raw[i] == `\r` && i + 1 < len && raw[i + 1] == `\n` {
|
||||
i += 2
|
||||
// 检查是否到达头部结束(空行)
|
||||
if i < len - 1 && raw[i] == `\r` && raw[i + 1] == `\n` {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否是 "Connection:" 头(不区分大小写)
|
||||
if (raw[i] == `C` || raw[i] == `c`) && i + 11 < len {
|
||||
// 检查 "onnection:"
|
||||
if (raw[i+1] == `o` || raw[i+1] == `O`) &&
|
||||
(raw[i+2] == `n` || raw[i+2] == `N`) &&
|
||||
(raw[i+3] == `n` || raw[i+3] == `N`) &&
|
||||
(raw[i+4] == `e` || raw[i+4] == `E`) &&
|
||||
(raw[i+5] == `c` || raw[i+5] == `C`) &&
|
||||
(raw[i+6] == `t` || raw[i+6] == `T`) &&
|
||||
(raw[i+7] == `i` || raw[i+7] == `I`) &&
|
||||
(raw[i+8] == `o` || raw[i+8] == `O`) &&
|
||||
(raw[i+9] == `n` || raw[i+9] == `N`) &&
|
||||
raw[i+10] == `:` {
|
||||
// 找到 Connection 头,检查值是否包含 keep-alive
|
||||
mut value_start := i + 11
|
||||
// 跳过空格
|
||||
for value_start < len && raw[value_start] == ` ` {
|
||||
value_start++
|
||||
}
|
||||
// 查找行尾
|
||||
mut value_end := value_start
|
||||
for value_end < len && raw[value_end] != `\r` && raw[value_end] != `\n` {
|
||||
value_end++
|
||||
}
|
||||
// 在值中查找 "keep-alive"(不区分大小写)
|
||||
return contains_keep_alive_token(raw, value_start, value_end)
|
||||
}
|
||||
}
|
||||
i++
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查字符串片段是否包含 keep-alive token
|
||||
@[inline]
|
||||
fn contains_keep_alive_token(raw string, start int, end int) bool {
|
||||
// 查找 "keep-alive" 或 "Keep-Alive"(支持多值如 "keep-alive, upgrade")
|
||||
mut i := start
|
||||
for i <= end - 10 {
|
||||
if raw[i] == `k` || raw[i] == `K` {
|
||||
if (raw[i+1] == `e` || raw[i+1] == `E`) &&
|
||||
(raw[i+2] == `e` || raw[i+2] == `E`) &&
|
||||
(raw[i+3] == `p` || raw[i+3] == `P`) &&
|
||||
raw[i+4] == `-` &&
|
||||
(raw[i+5] == `a` || raw[i+5] == `A`) &&
|
||||
(raw[i+6] == `l` || raw[i+6] == `L`) &&
|
||||
(raw[i+7] == `i` || raw[i+7] == `I`) &&
|
||||
(raw[i+8] == `v` || raw[i+8] == `V`) &&
|
||||
(raw[i+9] == `e` || raw[i+9] == `E`) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
i++
|
||||
}
|
||||
return false
|
||||
}// 快速解析 query string(单次遍历,避免 split)
|
||||
@[inline]
|
||||
fn parse_query_string_fast(raw string, start int, end int) map[string]string {
|
||||
mut query_map := map[string]string{}
|
||||
|
||||
Reference in New Issue
Block a user