forward method

Future<void> forward(
  1. HttpRequest request,
  2. Response res_
)

Implementation

Future<void> forward(HttpRequest request, Response res_) async {
  var coding = res_.headers['transfer-encoding'];

  final statusCode = res_.statusCode;
  request.response.statusCode = statusCode;

  if (coding != null && !equalsIgnoreAsciiCase(coding, 'identity')) {
    // If the response is already in a chunked encoding, de-chunk it because
    // otherwise `dart:io` will try to add another layer of chunking.
    //
    // TODO(codekeyz): Do this more cleanly when sdk#27886 is fixed.
    final newStream = chunkedCoding.decoder.bind(res_.body!.read());
    res_.body = shelf.ShelfBody(newStream);
    request.headers.set(HttpHeaders.transferEncodingHeader, 'chunked');
  } else if (statusCode >= 200 &&
      statusCode != 204 &&
      statusCode != 304 &&
      res_.contentLength == null &&
      res_.mimeType != 'multipart/byteranges') {
    // If the response isn't chunked yet and there's no other way to tell its
    // length, enable `dart:io`'s chunked encoding.
    request.response.headers
        .set(HttpHeaders.transferEncodingHeader, 'chunked');
  }

  final responseHeaders = res_.headers;
  if (responseHeaders.isNotEmpty) {
    for (final key in responseHeaders.keys) {
      request.response.headers.add(key, responseHeaders[key]);
    }
  }

  if (!responseHeaders.containsKey(_XPoweredByHeader)) {
    request.response.headers.add(_XPoweredByHeader, 'Pharaoh');
  }

  if (!responseHeaders.containsKey(HttpHeaders.dateHeader)) {
    request.response.headers.add(
      HttpHeaders.dateHeader,
      DateTime.now().toUtc(),
    );
  }
  if (!responseHeaders.containsKey(HttpHeaders.contentLengthHeader) &&
      res_.contentLength != null) {
    request.response.headers.add(
      HttpHeaders.contentLengthHeader,
      res_.contentLength!,
    );
  }

  final body = res_.body;
  final response = request.response;
  if (body == null) return response.close();
  return response.addStream(body.read()).then((_) => response.close());
}