handleGetOrHead method

Future<Response> handleGetOrHead (Request req)

GET or HEAD request handler.

Implementation

Future<Response> handleGetOrHead(Request req) async {
  // Determine the target URI

  final targetUrl = _targetUri(req);
  _logProxy.fine('[${req.id}] $method $targetUrl');

  try {
    // Determine the request headers to send to the target
    //
    // Note: the 'http' package does not support multiple headers with the
    // same name (which are possible in HTTP).

    final passHeaders = <String, String>{};

    final u = Uri.parse(targetUrl);
    passHeaders['host'] = (u.hasPort) ? '${u.host}:${u.port}' : u.host;

    req.headers.forEach((headerName, values) {
      if (!(requestHeadersNeverPass.contains(headerName) ||
          (requestBlockHeaders?.contains(headerName) ?? false))) {
        if (values.length == 1) {
          passHeaders[headerName] = values.first;
        } else {
          _logProxy.warning('request header not a single value: $headerName');
        }
      }
    });

    // Perform request for the target

    final targetResponse = await http.get(targetUrl, headers: passHeaders);
    assert(targetResponse != null);

    if (targetResponse.statusCode != HttpStatus.ok &&
        targetResponse.statusCode != HttpStatus.notModified) {
      if (!(targetResponse.statusCode == HttpStatus.notFound &&
          _ignoreNotFound.contains(targetUrl))) {
        _logProxy.warning("$targetUrl: status ${targetResponse.statusCode}");
      }
    }

    // Pass the target's response back as the response

    final contentType = (targetResponse.headers.containsKey('content-type'))
        ? ContentType.parse(targetResponse.headers['content-type'])
        : ContentType.binary;

    // Use the response from the target as the response

    final resp = new ResponseBuffered(contentType)
      ..status = targetResponse.statusCode;

    for (var headerName in targetResponse.headers.keys) {
      if (!(responseHeadersNeverPass.contains(headerName) ||
          (responseBlockHeaders?.contains(headerName) ?? false))) {
        // Not one of the special headers: copy it to the response
        resp.headerAdd(headerName, targetResponse.headers[headerName]);
      }
    }

    resp.write(targetResponse.body);
    return resp;
  } catch (e) {
    final proxyException = new ProxyHandlerException(targetUrl, e);
    _logProxy.fine('[${req.id}] $proxyException');
    throw proxyException;
  }
}