responseParse static method
将原始Socket字节数据解析为http.Response对象
Implementation
static http.Response responseParse(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 status line in HTTP response');
}
// 解析状态行 (格式: HTTP/version statusCode reasonPhrase)
final statusLine = headerLines[0];
final statusLineParts = Utils.splitUntil(statusLine, ' ', maxParts: 3); // 最多分成3部分,避免原因短语包含空格
if (statusLineParts.length < 2) {
throw FormatException('Invalid status line format: $statusLine');
}
final httpVersion = statusLineParts[0];
final statusCode = int.tryParse(statusLineParts[1]) ??
(throw FormatException('Invalid status code: ${statusLineParts[1]}'));
final reasonPhrase = statusLineParts.length > 2 ? statusLineParts[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 response = http.Response.bytes(
body,
statusCode,
headers: headers,
reasonPhrase: reasonPhrase,
request: null, // 可以根据需要关联请求对象
);
return response;
}