requestParse static method

Request requestParse(
  1. Uint8List data
)

将原始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;
}