ConnStateData::initiateTunneledRequest(HttpRequest::Pointer const &cause, Http::MethodType const method, const char *reason, const SBuf &payload)
{
    // fake a CONNECT request to force connState to tunnel
    SBuf connectHost;
    unsigned short connectPort = 0;

    if (pinning.serverConnection != nullptr) {
        static char ip[MAX_IPSTRLEN];
        connectHost = pinning.serverConnection->remote.toStr(ip, sizeof(ip));
        connectPort = pinning.serverConnection->remote.port();
    } else if (cause) {
        connectHost = cause->url.hostOrIp();
        connectPort = cause->url.port();
#if USE_OPENSSL
    } else if (!tlsConnectHostOrIp.isEmpty()) {
        connectHost = tlsConnectHostOrIp;
        connectPort = tlsConnectPort;
#endif
    } else if (transparent()) {
        static char ip[MAX_IPSTRLEN];
        connectHost = clientConnection->local.toStr(ip, sizeof(ip));
        connectPort = clientConnection->local.port();
    } else {
        // Typical cases are malformed HTTP requests on http_port and malformed
        // TLS handshakes on non-bumping https_port. TODO: Discover these
        // problems earlier so that they can be classified/detailed better.
        debugs(33, 2, "Not able to compute URL, abort request tunneling for " << reason);
        // TODO: throw when nonBlockingCheck() callbacks gain job protections
        static const auto d = MakeNamedErrorDetail("TUNNEL_TARGET");
        updateError(ERR_INVALID_REQ, d);
        return false;
    }

    debugs(33, 2, "Request tunneling for " << reason);
    ClientHttpRequest *http = buildFakeRequest(method, connectHost, connectPort, payload);
    HttpRequest::Pointer request = http->request;
    request->flags.forceTunnel = true;
    http->calloutContext = new ClientRequestContext(http);
    http->doCallouts();
    clientProcessRequestFinished(this, request);
    return true;
}
ConnStateData::initiateTunneledRequest(HttpRequest::Pointer const &cause, Http::MethodType const method, const char *reason, const SBuf &payload)
{
     
    SBuf connectHost;
    unsigned short connectPort = 0;

    if (pinning.serverConnection != nullptr) {
        static char ip[MAX_IPSTRLEN];
        connectHost = pinning.serverConnection->remote.toStr(ip, sizeof(ip));
        connectPort = pinning.serverConnection->remote.port();
    } else if (cause) {
        connectHost = cause->url.hostOrIp();
        connectPort = cause->url.port();
#if USE_OPENSSL
    } else if (!tlsConnectHostOrIp.isEmpty()) {
        connectHost = tlsConnectHostOrIp;
        connectPort = tlsConnectPort;
#endif
    } else if (transparent()) {
        static char ip[MAX_IPSTRLEN];
        connectHost = clientConnection->local.toStr(ip, sizeof(ip));
        connectPort = clientConnection->local.port();
    } else {
         
         
         
        debugs(33, 2, "Not able to compute URL, abort request tunneling for " << reason);
         
        static const auto d = MakeNamedErrorDetail("TUNNEL_TARGET");
        updateError(ERR_INVALID_REQ, d);
        return false;
    }

    debugs(33, 2, "Request tunneling for " << reason);
    ClientHttpRequest *http = buildFakeRequest(method, connectHost, connectPort, payload);
    HttpRequest::Pointer request = http->request;
    request->flags.forceTunnel = true;
    http->calloutContext = new ClientRequestContext(http);
    http->doCallouts();
    clientProcessRequestFinished(this, request);
    return true;
}