]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Make Downloader an basic AsyncJob class.
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Thu, 26 May 2016 13:48:16 +0000 (16:48 +0300)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Thu, 26 May 2016 13:48:16 +0000 (16:48 +0300)
This patch:
- Removes ConnStateData depedencies from Downloader. Downloader now is an
  AsyncJob class which builds an HttpRequest and related client objects
  (ClientHttpRequest, ClientStreamData and ClientRequestContext) and calls
  ClientHttpRequest::doCallouts
- Remove support for connectionless ConnStateData objects and the related
  changes previously done.

src/Downloader.cc
src/Downloader.h
src/HttpRequest.cc
src/HttpRequest.h
src/client_side.cc
src/client_side.h
src/client_side_reply.cc
src/client_side_request.cc
src/servers/Server.cc
src/ssl/PeerConnector.cc

index 0f1dc7be267fb7fb16a6b8782e58b3b0d8946c1e..045d1288bf577b119564f4f51675a9100f30a352 100644 (file)
@@ -2,26 +2,42 @@
 #include "client_side.h"
 #include "client_side_request.h"
 #include "client_side_reply.h"
+#include "ClientRequestContext.h"
 #include "Downloader.h"
 #include "http/one/RequestParser.h"
 #include "http/Stream.h"
 
+CBDATA_CLASS_INIT(DownloaderContext);
 CBDATA_CLASS_INIT(Downloader);
 
-Downloader::Downloader(SBuf &url, const MasterXaction::Pointer &xact, AsyncCall::Pointer &aCallback, unsigned int level):
+DownloaderContext::~DownloaderContext()
+{
+    debugs(33, 5, HERE);
+    cbdataReference(downloader);
+    if (http)
+        finished();
+}
+
+void
+DownloaderContext::finished()
+{
+    cbdataReference(http);
+    delete http;
+    http = NULL;
+}
+
+Downloader::Downloader(SBuf &url, AsyncCall::Pointer &aCallback, unsigned int level):
     AsyncJob("Downloader"),
-    ConnStateData(xact),
     url_(url),
     callback(aCallback),
     status(Http::scNone),
     level_(level)
 {
-    transferProtocol = AnyP::ProtocolVersion(AnyP::PROTO_HTTP,1,1);
 }
 
 Downloader::~Downloader()
 {
-    debugs(33 , 2, "Downloader Finished");
+    debugs(33 , 2, HERE);
 }
 
 bool
@@ -30,43 +46,39 @@ Downloader::doneAll() const
     return (!callback || callback->canceled()) && AsyncJob::doneAll();
 }
 
-void
-Downloader::start()
+static void
+downloaderRecipient(clientStreamNode * node, ClientHttpRequest * http,
+                    HttpReply * rep, StoreIOBuffer receivedData)
 {
-    ConnStateData::start();
-    if (Http::Stream *context = parseOneRequest()) {
-        context->registerWithConn();
-        processParsedRequest(context);
-        if (context->flags.deferred) {
-            if (context != context->http->getConn()->pipeline.front().getRaw())
-                context->deferRecipientForLater(context->deferredparams.node, context->deferredparams.rep, context->deferredparams.queuedBuffer);
-            else
-                context->http->getConn()->handleReply(context->deferredparams.rep, context->deferredparams.queuedBuffer); 
-        }
-    } else {
-        status = Http::scInternalServerError;
-        callBack();
-    }
-}
+    debugs(33, 6, HERE);
+     /* Test preconditions */
+    assert(node != NULL);
+
+    /* TODO: handle this rather than asserting
+     * - it should only ever happen if we cause an abort and
+     * the callback chain loops back to here, so we can simply return.
+     * However, that itself shouldn't happen, so it stays as an assert for now.
+     */
+    assert(cbdataReferenceValid(node));
+    assert(node->node.next == NULL);
+    DownloaderContext::Pointer context = dynamic_cast<DownloaderContext *>(node->data.getRaw());
+    assert(context != NULL);
+
+    if (!cbdataReferenceValid(context->downloader))
+        return;
 
-void
-Downloader::noteMoreBodySpaceAvailable(BodyPipe::Pointer)
-{
-    // This method required only if we need to support uploading data to server.
-    // Currently only GET requests are supported.
-    assert(false);
+    context->downloader->handleReply(node, http, rep, receivedData);
 }
 
-void
-Downloader::noteBodyConsumerAborted(BodyPipe::Pointer)
+static void
+downloaderDetach(clientStreamNode * node, ClientHttpRequest * http)
 {
-    // This method required only if we need to support uploading data to server.
-    // Currently only GET requests are supported.
-    assert(false);
+    debugs(33, 5, HERE);
+    clientStreamDetach(node, http);
 }
 
-Http::Stream *
-Downloader::parseOneRequest()
+bool
+Downloader::buildRequest()
 { 
     const HttpRequestMethod method = Http::METHOD_GET;
 
@@ -75,67 +87,69 @@ Downloader::parseOneRequest()
     if (!request) {
         debugs(33, 5, "Invalid FTP URL: " << uri);
         safe_free(uri);
-        return nullptr; //earlyError(...)
+        return false; //earlyError(...)
     }
     request->http_ver = Http::ProtocolVersion();
     request->header.putStr(Http::HdrType::HOST, request->url.host());
     request->header.putTime(Http::HdrType::DATE, squid_curtime);
-
-    ClientHttpRequest *const http = new ClientHttpRequest(this);
+    request->flags.internalClient = true;
+    request->client_addr.setNoAddr();
+#if FOLLOW_X_FORWARDED_FOR
+    request->indirect_client_addr.setNoAddr();
+#endif /* FOLLOW_X_FORWARDED_FOR */
+    request->my_addr.setNoAddr();   /* undefined for internal requests */
+    request->my_addr.port(0);
+    request->downloader = this;
+
+    ClientHttpRequest *const http = new ClientHttpRequest(NULL);
     http->request = request;
     HTTPMSGLOCK(http->request);
     http->req_sz = 0;
     http->uri = uri;
 
-    Http::Stream *const context = new Http::Stream(nullptr, http);
+    context_ = new DownloaderContext(this, http);
     StoreIOBuffer tempBuffer;
-    tempBuffer.data = context->reqbuf;
+    tempBuffer.data = context_->requestBuffer;
     tempBuffer.length = HTTP_REQBUF_SZ;
 
     ClientStreamData newServer = new clientReplyContext(http);
-    ClientStreamData newClient = context;
+    ClientStreamData newClient = context_.getRaw();
     clientStreamInit(&http->client_stream, clientGetMoreData, clientReplyDetach,
-                     clientReplyStatus, newServer, clientSocketRecipient,
-                     clientSocketDetach, newClient, tempBuffer);
-
-    context->flags.parsed_ok = 1;
-    return context;
-}
+                     clientReplyStatus, newServer, downloaderRecipient,
+                     downloaderDetach, newClient, tempBuffer);
 
-void
-Downloader::processParsedRequest(Http::Stream *context)
-{
-    Must(context);
-    Must(pipeline.nrequests == 1);
+    // Build a ClientRequestContext to start doCallouts
+    http->calloutContext = new ClientRequestContext(http);
 
-    ClientHttpRequest *const http = context->http;
-    Must(http);
+    // Do not check for redirect, tos,nfmark and sslBump
+    http->calloutContext->redirect_done = true;
+    http->calloutContext->tosToClientDone = true;
+    http->calloutContext->nfmarkToClientDone = true;
+    http->calloutContext->sslBumpCheckDone = true;
+    http->al->ssl.bumpMode = Ssl::bumpEnd; // SslBump does not apply; log -
 
-    debugs(33, 4, "forwarding request to server side");
-    Must(http->storeEntry() == nullptr);
-    clientProcessRequest(this, Http1::RequestParserPointer(), context);
-}
-
-time_t
-Downloader::idleTimeout() const
-{
-    // No need to be implemented for connection-less ConnStateData object.
-    assert(false);
-    return 0;
+    http->doCallouts();
+    return true;
 }
 
 void
-Downloader::writeControlMsgAndCall(HttpReply *rep, AsyncCall::Pointer &call)
+Downloader::start()
 {
-    // nobody to forward the control message to
+    if (!buildRequest()) {
+        status = Http::scInternalServerError;
+        callBack();
+    }
 }
 
 void
-Downloader::handleReply(HttpReply *reply, StoreIOBuffer receivedData)
+Downloader::handleReply(clientStreamNode * node, ClientHttpRequest *http, HttpReply *reply, StoreIOBuffer receivedData)
 {
-    Http::StreamPointer context = pipeline.front();
+    // TODO: remove the following check:
+    DownloaderContext::Pointer callerContext = dynamic_cast<DownloaderContext *>(node->data.getRaw());
+    assert(callerContext == context_);
+
     bool existingContent = reply ? reply->content_length : 0;
-    bool exceedSize = (context->startOfOutput() && existingContent > -1 && (size_t)existingContent > MaxObjectSize) || 
+    bool exceedSize = (existingContent > -1 && (size_t)existingContent > MaxObjectSize) || 
         ((object.length() + receivedData.length) > MaxObjectSize);
 
     if (exceedSize) {
@@ -150,27 +164,32 @@ Downloader::handleReply(HttpReply *reply, StoreIOBuffer receivedData)
 
     if (receivedData.length > 0) {
         object.append(receivedData.data, receivedData.length);
-        context->http->out.size += receivedData.length;
-        context->noteSentBodyBytes(receivedData.length);
+        http->out.size += receivedData.length;
+        http->out.offset += receivedData.length;
     }
 
-    switch (context->socketState()) {
-    case STREAM_NONE:
-         debugs(33, 3, "Get more data");
-        context->pullData();
+    switch (clientStreamStatus (node, http)) {
+    case STREAM_NONE: {
+        debugs(33, 3, HERE << "Get more data");
+        StoreIOBuffer tempBuffer;
+        tempBuffer.offset = http->out.offset;
+        tempBuffer.data = context_->requestBuffer;
+        tempBuffer.length = HTTP_REQBUF_SZ;
+        clientStreamRead (node, http, tempBuffer);
+    }
         break;
     case STREAM_COMPLETE:
-        debugs(33, 3, "Object data transfer successfully complete");
+        debugs(33, 3, HERE << "Object data transfer successfully complete");
         status = Http::scOkay;
         callBack();
         break;
     case STREAM_UNPLANNED_COMPLETE:
-        debugs(33, 3, "Object data transfer failed: STREAM_UNPLANNED_COMPLETE");
+        debugs(33, 3, HERE << "Object data transfer failed: STREAM_UNPLANNED_COMPLETE");
         status = Http::scInternalServerError;
         callBack();
         break;
     case STREAM_FAILED:
-        debugs(33, 3, "Object data transfer failed: STREAM_FAILED");
+        debugs(33, 3, HERE << "Object data transfer failed: STREAM_FAILED");
         status = Http::scInternalServerError;
         callBack();
         break;
@@ -183,6 +202,8 @@ void
 Downloader::downloadFinished()
 {
     debugs(33, 7, this);
+    context_->finished();
+    context_ = NULL;
     Must(done());
     // Not really needed. Squid will delete this object because "doneAll" is true.
     //deleteThis("completed");
@@ -207,8 +228,3 @@ Downloader::callBack()
      CallJobHere(33, 7, CbcPointer<Downloader>(this), Downloader, downloadFinished);
 }
 
-bool
-Downloader::isOpen() const
-{
-    return cbdataReferenceValid(this) && !doneAll();
-}
index cbb883759f5ae092eb9fb4ad10a3c33964c7d538..b11a112a83a8572bfd8f2b82f2d0440185666669 100644 (file)
@@ -1,10 +1,38 @@
 #ifndef SQUID_DOWNLOADER_H
 #define SQUID_DOWNLOADER_H
 
-#include "client_side.h"
+#include "base/AsyncCall.h"
+#include "base/AsyncJob.h"
 #include "cbdata.h"
+#include "defines.h"
+#include "http/StatusCode.h"
+#include "sbuf/SBuf.h"
 
-class Downloader: public ConnStateData
+class ClientHttpRequest;
+class StoreIOBuffer;
+class clientStreamNode;
+class HttpReply;
+class Downloader;
+
+class DownloaderContext: public RefCountable
+{
+    CBDATA_CLASS(DownloaderContext);
+
+public:
+    typedef RefCount<DownloaderContext> Pointer;
+
+    DownloaderContext(Downloader *dl, ClientHttpRequest *h):
+        downloader(cbdataReference(dl)),
+        http(cbdataReference(h))
+        {}
+    ~DownloaderContext();
+    void finished();
+    Downloader* downloader;
+    ClientHttpRequest *http;
+    char requestBuffer[HTTP_REQBUF_SZ];
+};
+
+class Downloader: virtual public AsyncJob
 {
     CBDATA_CLASS(Downloader);
 public:
@@ -18,7 +46,7 @@ public:
         Http::StatusCode status;
     };
 
-    Downloader(SBuf &url, const MasterXaction::Pointer &xact, AsyncCall::Pointer &aCallback, unsigned int level = 0);
+    Downloader(SBuf &url, AsyncCall::Pointer &aCallback, unsigned int level = 0);
     virtual ~Downloader();
 
     /// Fake call used internally by Downloader.
@@ -27,29 +55,21 @@ public:
     /// The nested level of Downloader object (downloads inside downloads).
     unsigned int nestedLevel() const {return level_;}
     
-    /* ConnStateData API */
-    virtual bool isOpen() const;
-
     /* AsyncJob API */
     virtual bool doneAll() const;
 
-    /*Bodypipe API*/
-    virtual void noteMoreBodySpaceAvailable(BodyPipe::Pointer);
-    virtual void noteBodyConsumerAborted(BodyPipe::Pointer);
-
+    DownloaderContext::Pointer const &context() {return context_;};
+    void handleReply(clientStreamNode * node, ClientHttpRequest *http, HttpReply *header, StoreIOBuffer receivedData);
 protected:
-    /* ConnStateData API */
-    virtual Http::Stream *parseOneRequest();
-    virtual void processParsedRequest(Http::Stream *context);
-    virtual time_t idleTimeout() const;
-    virtual void writeControlMsgAndCall(HttpReply *rep, AsyncCall::Pointer &call);
-    virtual void handleReply(HttpReply *header, StoreIOBuffer receivedData);
 
     /* AsyncJob API */
     virtual void start();
     virtual void prepUserConnection() {};
 
 private:
+
+    bool buildRequest();
+
     /// Schedules for execution the "callback" with parameters the status
     /// and object.
     void callBack();
@@ -62,6 +82,8 @@ private:
     Http::StatusCode status; ///< the download status code
     SBuf object; ///< the object body data
     unsigned int level_; ///< holds the nested downloads level
+
+    DownloaderContext::Pointer context_;
 };
 
 #endif
index 604bb5e0f2f4b72d861c9a372189a68e1f8ae22d..8b926323b0cb4bf9a8c2dd42aa50c25d0fa664d1 100644 (file)
@@ -14,6 +14,7 @@
 #include "acl/FilledChecklist.h"
 #include "client_side.h"
 #include "dns/LookupDetails.h"
+#include "Downloader.h"
 #include "err_detail_type.h"
 #include "globals.h"
 #include "gopher.h"
@@ -250,6 +251,8 @@ HttpRequest::inheritProperties(const HttpMsg *aMsg)
     // main property is which connection the request was received on (if any)
     clientConnectionManager = aReq->clientConnectionManager;
 
+    downloader = aReq->downloader;
+
     notes = aReq->notes;
 
     sources = aReq->sources;
index 4651839c6ba0e26c0bd32eb814a2b497fa8e4f7f..66422d1fd84f60c67c8738e18f2669a2ca4895de 100644 (file)
@@ -34,6 +34,7 @@
 #endif
 
 class ConnStateData;
+class Downloader;
 
 /*  Http Request */
 void httpRequestPack(void *obj, Packable *p);
@@ -212,6 +213,9 @@ public:
      */
     CbcPointer<ConnStateData> clientConnectionManager;
 
+    /// The Downloader object intiated the HTTP request if exist
+    CbcPointer<Downloader> downloader;
+
     /// forgets about the cached Range header (for a reason)
     void ignoreRange(const char *reason);
     int64_t getRangeOffsetLimit(); /* the result of this function gets cached in rangeOffsetLimit */
index fe01dbd5221d194e63bf8b331ec1267ed58aca81..74ca44c8559dff6ef53265397ea99de50721b47c 100644 (file)
@@ -586,8 +586,7 @@ ConnStateData::swanSong()
     debugs(33, 2, HERE << clientConnection);
     flags.readMore = false;
     DeregisterRunner(this);
-    if (clientConnection != nullptr)
-        clientdbEstablished(clientConnection->remote, -1);  /* decrement */
+    clientdbEstablished(clientConnection->remote, -1);  /* decrement */
     pipeline.terminateAll(0);
 
     unpinConnection(true);
@@ -792,14 +791,9 @@ clientSocketRecipient(clientStreamNode * node, ClientHttpRequest * http,
                       HttpReply * rep, StoreIOBuffer receivedData)
 {
     // dont tryt to deliver if client already ABORTED
-    if (!http->getConn() || !cbdataReferenceValid(http->getConn()))
+    if (!http->getConn() || !cbdataReferenceValid(http->getConn()) || !Comm::IsConnOpen(http->getConn()->clientConnection))
         return;
 
-    // If it is not connectionless and connection is closed return  
-    if (!http->getConn()->connectionless() && !Comm::IsConnOpen(http->getConn()->clientConnection))
-        return;
-
-
     /* Test preconditions */
     assert(node != NULL);
     PROF_start(clientSocketRecipient);
@@ -1645,14 +1639,12 @@ clientProcessRequest(ConnStateData *conn, const Http1::RequestParserPointer &hp,
 
     request->flags.accelerated = http->flags.accel;
     request->flags.sslBumped=conn->switchedToHttps();
-    if (!conn->connectionless()) {
-        request->flags.ignoreCc = conn->port->ignore_cc;
-        // TODO: decouple http->flags.accel from request->flags.sslBumped
-        request->flags.noDirect = (request->flags.accelerated && !request->flags.sslBumped) ?
-                                  !conn->port->allow_direct : 0;
-        request->sources |= isFtp ? HttpMsg::srcFtp :
-                            ((request->flags.sslBumped || conn->port->transport.protocol == AnyP::PROTO_HTTPS) ? HttpMsg::srcHttps : HttpMsg::srcHttp);
-    }
+    request->flags.ignoreCc = conn->port->ignore_cc;
+    // TODO: decouple http->flags.accel from request->flags.sslBumped
+    request->flags.noDirect = (request->flags.accelerated && !request->flags.sslBumped) ?
+                              !conn->port->allow_direct : 0;
+    request->sources |= isFtp ? HttpMsg::srcFtp :
+                        ((request->flags.sslBumped || conn->port->transport.protocol == AnyP::PROTO_HTTPS) ? HttpMsg::srcHttps : HttpMsg::srcHttp);
 #if USE_AUTH
     if (request->flags.sslBumped) {
         if (conn->getAuth() != NULL)
@@ -1695,16 +1687,14 @@ clientProcessRequest(ConnStateData *conn, const Http1::RequestParserPointer &hp,
 
     request->flags.internal = http->flags.internal;
     setLogUri (http, urlCanonicalClean(request.getRaw()));
-    if (!conn->connectionless()) {
-        request->client_addr = conn->clientConnection->remote; // XXX: remove reuest->client_addr member.
+    request->client_addr = conn->clientConnection->remote; // XXX: remove reuest->client_addr member.
 #if FOLLOW_X_FORWARDED_FOR
     // indirect client gets stored here because it is an HTTP header result (from X-Forwarded-For:)
     // not a details about teh TCP connection itself
-        request->indirect_client_addr = conn->clientConnection->remote;
+    request->indirect_client_addr = conn->clientConnection->remote;
 #endif /* FOLLOW_X_FORWARDED_FOR */
-        request->my_addr = conn->clientConnection->local;
-        request->myportname = conn->port->name;
-    }
+    request->my_addr = conn->clientConnection->local;
+    request->myportname = conn->port->name;
 
     if (!isFtp) {
         // XXX: for non-HTTP messages instantiate a different HttpMsg child type
@@ -2452,9 +2442,7 @@ ConnStateData::ConnStateData(const MasterXaction::Pointer &xact) :
     pinning.peer = NULL;
 
     // store the details required for creating more MasterXaction objects as new requests come in
-    if (xact->tcpClient)
-        log_addr = xact->tcpClient->remote;
-
+    log_addr = xact->tcpClient->remote;
     log_addr.applyMask(Config.Addrs.client_netmask);
 
     // register to receive notice of Squid signal events
@@ -2467,12 +2455,7 @@ ConnStateData::start()
 {
     BodyProducer::start();
     HttpControlMsgSink::start();
-    prepUserConnection();
-}
 
-void
-ConnStateData::prepUserConnection()
-{
     if (port->disable_pmtu_discovery != DISABLE_PMTU_OFF &&
             (transparent() || port->disable_pmtu_discovery == DISABLE_PMTU_ALWAYS)) {
 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
@@ -3276,6 +3259,7 @@ bool
 ConnStateData::splice()
 {
     // normally we can splice here, because we just got client hello message
+
     if (fd_table[clientConnection->fd].ssl.get()) {
         // Restore default read methods
         fd_table[clientConnection->fd].read_method = &default_read_method;
index 8d4d92063ec8c21315fbbb7d8461e031a63d1b2e..c3d0761d6874b4b8f042f373968baaf1b1825997 100644 (file)
@@ -85,7 +85,7 @@ public:
     /// try to make progress on a transaction or read more I/O
     void kick();
 
-    virtual bool isOpen() const;
+    bool isOpen() const;
 
     Http1::TeChunkedParser *bodyParser; ///< parses HTTP/1.1 chunked request body
 
@@ -134,10 +134,6 @@ public:
         AsyncCall::Pointer closeHandler; /*The close handler for pinned server side connection*/
     } pinning;
 
-    /// If the port is not set then it is a connection-less object 
-    /// created by an internal squid subsystem
-    bool connectionless() const { return port == nullptr; }
-
     bool transparent() const;
 
     /// true if we stopped receiving the request
@@ -195,10 +191,6 @@ public:
     virtual bool doneAll() const { return BodyProducer::doneAll() && false;}
     virtual void swanSong();
 
-    /// Do the related hooks related to start retrieving requests from
-    /// client connection
-    virtual void prepUserConnection();
-
     /// Changes state so that we close the connection and quit after serving
     /// the client-side-detected error response instead of getting stuck.
     void quitAfterError(HttpRequest *request); // meant to be private
index 324a2afcd6d8af7bf5f023123a3aab467fa2af2a..63184289782c8c27c0009d06bf7623fed2574a32 100644 (file)
@@ -1352,7 +1352,7 @@ clientReplyContext::buildReplyHeader()
         if (EBIT_TEST(http->storeEntry()->flags, ENTRY_SPECIAL)) {
             hdr->delById(Http::HdrType::DATE);
             hdr->putTime(Http::HdrType::DATE, squid_curtime);
-        } else if (http->getConn() &&  !http->getConn()->connectionless() && http->getConn()->port->actAsOrigin) {
+        } else if (http->getConn() && http->getConn()->port->actAsOrigin) {
             // Swap the Date: header to current time if we are simulating an origin
             HttpHeaderEntry *h = hdr->findEntry(Http::HdrType::DATE);
             if (h)
@@ -1524,10 +1524,7 @@ clientReplyContext::buildReplyHeader()
         request->flags.proxyKeepalive = false;
     } else if (http->getConn()) {
         ConnStateData * conn = http->getConn();
-        if (conn->connectionless()) {
-            debugs(88, 3, "connection-less object, close after finished");
-            request->flags.proxyKeepalive = false;
-        } else if (!Comm::IsConnOpen(conn->port->listenConn)) {
+        if (!Comm::IsConnOpen(conn->port->listenConn)) {
             // The listening port closed because of a reconfigure
             debugs(88, 3, "listening port closed");
             request->flags.proxyKeepalive = false;
@@ -2123,21 +2120,29 @@ clientReplyContext::sendMoreData (StoreIOBuffer result)
 
     StoreEntry *entry = http->storeEntry();
 
-    ConnStateData * conn = http->getConn();
+    if (ConnStateData * conn = http->getConn()) {
+        if (!conn->isOpen()) {
+            debugs(33,3, "not sending more data to closing connection " << conn->clientConnection);
+            return;
+        }
+        if (conn->pinning.zeroReply) {
+            debugs(33,3, "not sending more data after a pinned zero reply " << conn->clientConnection);
+            return;
+        }
 
-    // too late, our conn is closing
-    // TODO: should we also quit?
-    if (conn == NULL) {
-        debugs(33,3, "not sending more data to a closed connection" );
-        return;
-    }
-    if (!conn->isOpen()) {
-        debugs(33,3, "not sending more data to closing connection " << conn->clientConnection);
-        return;
-    }
-    if (conn->pinning.zeroReply) {
-        debugs(33,3, "not sending more data after a pinned zero reply " << conn->clientConnection);
-        return;
+        if (reqofs==0 && !http->logType.isTcpHit() && Comm::IsConnOpen(conn->clientConnection)) {
+            if (Ip::Qos::TheConfig.isHitTosActive()) {
+                Ip::Qos::doTosLocalMiss(conn->clientConnection, http->request->hier.code);
+            }
+            if (Ip::Qos::TheConfig.isHitNfmarkActive()) {
+                Ip::Qos::doNfmarkLocalMiss(conn->clientConnection, http->request->hier.code);
+            }
+        }
+
+        debugs(88, 5, "clientReplyContext::sendMoreData:" <<
+               conn->clientConnection <<
+               " '" << entry->url() << "'" <<
+               " out.offset=" << http->out.offset);
     }
 
     char *buf = next()->readBuffer.data;
@@ -2148,15 +2153,6 @@ clientReplyContext::sendMoreData (StoreIOBuffer result)
         memcpy(buf, result.data, result.length);
     }
 
-    if (reqofs==0 && !http->logType.isTcpHit() && Comm::IsConnOpen(conn->clientConnection)) {
-        if (Ip::Qos::TheConfig.isHitTosActive()) {
-            Ip::Qos::doTosLocalMiss(conn->clientConnection, http->request->hier.code);
-        }
-        if (Ip::Qos::TheConfig.isHitNfmarkActive()) {
-            Ip::Qos::doNfmarkLocalMiss(conn->clientConnection, http->request->hier.code);
-        }
-    }
-
     /* We've got the final data to start pushing... */
     flags.storelogiccomplete = 1;
 
@@ -2175,10 +2171,6 @@ clientReplyContext::sendMoreData (StoreIOBuffer result)
     debugs(88, 5, "clientReplyContext::sendMoreData: " << http->uri << ", " <<
            reqofs << " bytes (" << result.length <<
            " new bytes)");
-    debugs(88, 5, "clientReplyContext::sendMoreData:"
-           << conn->clientConnection <<
-           " '" << entry->url() << "'" <<
-           " out.offset=" << http->out.offset);
 
     /* update size of the request */
     reqsize = reqofs;
index 9ed8eddf0851ae4f23866108273ba2180fa79a67..d8da5694124e3dc10e9b2e96d7347a17514d4e90 100644 (file)
@@ -1000,11 +1000,6 @@ clientCheckPinning(ClientHttpRequest * http)
     if (!http_conn)
         return;
 
-    // Internal requests such as those from Downloader does not have
-    // local port.
-    if (!http_conn->port)
-        return;
-
     request->flags.connectionAuthDisabled = http_conn->port->connection_auth_disabled;
     if (!request->flags.connectionAuthDisabled) {
         if (Comm::IsConnOpen(http_conn->pinning.serverConnection)) {
index c3b3608ab00f9ae3c099dd3e29af03edb7edf9cb..ef86a4ddea9058d12c4c9596344cba7d087f0540 100644 (file)
 Server::Server(const MasterXaction::Pointer &xact) :
     AsyncJob("::Server"), // kids overwrite
     clientConnection(xact->tcpClient),
+    transferProtocol(xact->squidPort->transport),
     port(xact->squidPort),
     receivedFirstByte_(false)
-{
-    if (xact->squidPort)
-        transferProtocol = xact->squidPort->transport;
-}
+{}
 
 bool
 Server::doneAll() const
index e99e8b099a526c9f2c47e18cda4763416c2f190f..abdf5cfc57b0d73a72d0c2ba22d6d6478198f3a8 100644 (file)
@@ -541,9 +541,9 @@ Ssl::PeerConnector::startCertDownloading(SBuf &url)
                                             "Ssl::PeerConnector::certDownloadingDone",
                                             PeerConnectorCertDownloaderDialer(&Ssl::PeerConnector::certDownloadingDone, this));
 
-    const Downloader *csd = dynamic_cast<const Downloader*>(request->clientConnectionManager.valid());
-    MasterXaction *xaction = new MasterXaction;
-    Downloader *dl = new Downloader(url, xaction, certCallback, csd ? csd->nestedLevel() + 1 : 1);
+    // XXX: find a way to link HttpRequest and Downloader, the following always fails.
+    const Downloader *csd = dynamic_cast<const Downloader*>(request->downloader.valid());
+    Downloader *dl = new Downloader(url, certCallback, csd ? csd->nestedLevel() + 1 : 1);
     AsyncJob::Start(dl);
 }
 
@@ -588,7 +588,10 @@ Ssl::PeerConnector::checkForMissingCertificates ()
     // Check for nested SSL certificates downloads. For example when the
     // certificate located in an SSL site which requires to download a
     // a missing certificate (... from an SSL site which requires to ...).
-    const Downloader *csd = dynamic_cast<const Downloader*>(request->clientConnectionManager.valid());
+
+    // XXX: find a way to link HttpRequest with Downloader.
+    // The following always fails:
+    const Downloader *csd = dynamic_cast<const Downloader*>(request->downloader.valid());
     if (csd && csd->nestedLevel() >= MaxNestedDownloads)
         return false;