requestParse static method
将原始Socket字节数据解析为http.Request对象
Implementation
static http.Request requestParse(Uint8List data) {
// 解析请求头(必须是文本)和请求体(可能是二进制)
final headerEndIndex = _findHeaderEnd(data);
if (headerEndIndex == -1) {
throw FormatException('Could not find end of HTTP headers');
}
// 提取并解析请求头(只处理这部分的编码)
final headerData = data.sublist(0, headerEndIndex);
String headerString;
// 更健壮的编码检测和处理
try {
// 尝试UTF-8
headerString = utf8.decode(headerData, allowMalformed: false);
} on FormatException {
try {
// 尝试Latin-1 (ISO-8859-1)
headerString = latin1.decode(headerData);
} on FormatException {
// 最后尝试允许畸形的UTF-8
headerString = utf8.decode(headerData, allowMalformed: true);
}
}
// 解析请求行和头字段
final headerLines = headerString.split('\r\n');
if (headerLines.isEmpty) {
throw FormatException('Missing request line in HTTP request');
}
// 解析请求行
final requestLine = headerLines[0];
final requestLineParts = requestLine.split(' ');
if (requestLineParts.length != 3) {
throw FormatException('Invalid request line format: $requestLine');
}
final method = requestLineParts[0];
final path = requestLineParts[1];
final httpVersion = requestLineParts[2];
if (!httpVersion.startsWith('HTTP/')) {
throw FormatException('Invalid HTTP version: $httpVersion');
}
// 解析请求头
final headers = <String, String>{};
for (int i = 1; i < headerLines.length; i++) {
final line = headerLines[i];
if (line.isEmpty) continue;
final colonIndex = line.indexOf(':');
if (colonIndex == -1) {
throw FormatException('Invalid header format: $line');
}
final name = line.substring(0, colonIndex).trim().toLowerCase();
final value = line.substring(colonIndex + 1).trim();
// 处理重复的头字段
if (headers.containsKey(name)) {
headers[name] = '${headers[name]}, $value';
} else {
headers[name] = value;
}
}
// 处理请求体(直接使用原始字节,避免编码转换问题)
Uint8List body = Uint8List(0);
final bodyStartIndex = headerEndIndex + 4; // 跳过\r\n\r\n
if (bodyStartIndex < data.length) {
// 根据Content-Length验证体长度
final contentLengthStr = headers['content-length'];
if (contentLengthStr != null) {
final contentLength = int.tryParse(contentLengthStr) ?? 0;
final actualLength = data.length - bodyStartIndex;
// 处理实际长度与声明长度不匹配的情况
if (actualLength < contentLength) {
body = data.sublist(bodyStartIndex);
} else if (actualLength > contentLength) {
body = data.sublist(bodyStartIndex, bodyStartIndex + contentLength);
} else {
body = data.sublist(bodyStartIndex);
}
} else {
// 没有Content-Length时,使用所有剩余数据
body = data.sublist(bodyStartIndex);
}
}
// 创建请求对象
final request = http.Request(method, Uri.parse(path));
// 设置请求头
headers.forEach((key, value) {
request.headers[key] = value;
});
// 设置请求体
request.bodyBytes = body;
// 存储HTTP版本信息
//request.headers['http-version'] = httpVersion;
return request;
}