performRequest method

  1. @override
Future<FittorResponse> performRequest(
  1. FittorRequest request,
  2. Stopwatch stopwatch
)
override

Implementation

@override
Future<FittorResponse> performRequest(
    FittorRequest request, Stopwatch stopwatch) async {
  try {
    // Create HTTP request using the full URI to preserve scheme (HTTP/HTTPS)
    final HttpClientRequest httpRequest = await _httpClient.openUrl(
      request.methodName,
      request.uri,
    );

    // Set timeout
    final timeout = request.timeout ?? const Duration(seconds: 30);

    // Set headers
    request.headers.toMultiMap().forEach((key, values) {
      for (final value in values) {
        httpRequest.headers.add(key, value);
      }
    });

    // Set follow redirects
    httpRequest.followRedirects = request.followRedirects;
    httpRequest.maxRedirects = request.maxRedirects;

    // Write body if present
    if (request.body != null) {
      if (request.body is String) {
        httpRequest.write(request.body);
      } else if (request.body is List<int>) {
        httpRequest.add(request.body);
      } else {
        httpRequest.write(request.body.toString());
      }
    }

    // Send request and get response with timeout
    final httpResponse = await httpRequest.close().timeout(timeout);

    // Read response body
    final bodyBytes = await httpResponse.fold<List<int>>(
      <int>[],
      (previous, element) => previous..addAll(element),
    );

    stopwatch.stop();

    // Build response headers
    final responseHeaders = FittorHeaders();
    httpResponse.headers.forEach((key, values) {
      for (final value in values) {
        responseHeaders.add(key, value);
      }
    });

    return FittorResponse(
      statusCode: httpResponse.statusCode,
      statusMessage: httpResponse.reasonPhrase,
      headers: responseHeaders,
      bodyBytes: Uint8List.fromList(bodyBytes),
      requestDuration: stopwatch.elapsed,
    );
  } on SocketException catch (e) {
    stopwatch.stop();
    throw FittorNetworkException('Socket error: ${e.message}', e);
  } on TimeoutException catch (e) {
    stopwatch.stop();
    throw FittorTimeoutException(
        'Request timeout', request.timeout ?? const Duration(seconds: 30), e);
  } catch (e) {
    stopwatch.stop();
    throw FittorNetworkException('Request failed: $e', e);
  }
}