]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
merge from trunk r14597
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Fri, 18 Mar 2016 18:00:56 +0000 (20:00 +0200)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Fri, 18 Mar 2016 18:00:56 +0000 (20:00 +0200)
1  2 
src/Downloader.cc
src/Makefile.am
src/client_side_request.cc
src/debug.cc

index 167abc99682f86fa661028666166a646cf1f7930,0000000000000000000000000000000000000000..901c5b4a74e64cc08cd03dd3ce6d30ed9a0193d3
mode 100644,000000..100644
--- /dev/null
@@@ -1,224 -1,0 +1,224 @@@
-     HttpRequest *const request = HttpRequest::CreateFromUrlAndMethod(uri, method);
 +#include "squid.h"
 +#include "client_side.h"
 +#include "client_side_request.h"
 +#include "client_side_reply.h"
 +#include "Downloader.h"
 +#include "http/one/RequestParser.h"
 +#include "http/Stream.h"
 +
 +CBDATA_CLASS_INIT(Downloader);
 +
 +Downloader::Downloader(SBuf &url, const MasterXaction::Pointer &xact, 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");
 +}
 +
 +void
 +Downloader::callException(const std::exception &e)
 +{
 +    debugs(33 , 2, "Downloader caught:" << e.what());
 +    AsyncJob::callException(e);
 +}
 +
 +bool
 +Downloader::doneAll() const
 +{
 +    return (!callback || callback->canceled()) && AsyncJob::doneAll();
 +}
 +
 +void
 +Downloader::start()
 +{
 +    BodyProducer::start();
 +    HttpControlMsgSink::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); 
 +        }
 +        /**/
 +
 +    }
 +    
 +}
 +
 +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(0);
 +}
 +
 +void
 +Downloader::noteBodyConsumerAborted(BodyPipe::Pointer)
 +{
 +    // This method required only if we need to support uploading data to server
 +    // Currently only GET requests are supported
 +    assert(0);
 +}
 +
 +Http::Stream *
 +Downloader::parseOneRequest()
 +{ 
 +    const HttpRequestMethod method = Http::METHOD_GET;
 +
 +    char *uri = strdup(url_.c_str());
++    HttpRequest *const request = HttpRequest::CreateFromUrl(uri, method);
 +    if (!request) {
 +        debugs(33, 5, "Invalid FTP URL: " << uri);
 +        safe_free(uri);
 +        return NULL; //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);
 +    http->request = request;
 +    HTTPMSGLOCK(http->request);
 +    http->req_sz = 0;
 +    http->uri = uri;
 +
 +    Http::Stream *const context = new Http::Stream(NULL, http);
 +    StoreIOBuffer tempBuffer;
 +    tempBuffer.data = context->reqbuf;
 +    tempBuffer.length = HTTP_REQBUF_SZ;
 +
 +    ClientStreamData newServer = new clientReplyContext(http);
 +    ClientStreamData newClient = context;
 +    clientStreamInit(&http->client_stream, clientGetMoreData, clientReplyDetach,
 +                     clientReplyStatus, newServer, clientSocketRecipient,
 +                     clientSocketDetach, newClient, tempBuffer);
 +
 +    context->flags.parsed_ok = 1;
 +    return context;
 +}
 +
 +void
 +Downloader::processParsedRequest(Http::Stream *context)
 +{
 +    Must(context != NULL);
 +    Must(pipeline.nrequests == 1);
 +
 +    ClientHttpRequest *const http = context->http;
 +    assert(http != NULL);
 +
 +    debugs(33, 4, "forwarding request to server side");
 +    assert(http->storeEntry() == NULL);
 +    clientProcessRequest(this, Http1::RequestParserPointer(), context);
 +}
 +
 +time_t
 +Downloader::idleTimeout() const
 +{
 +    // No need to be implemented for connection-less ConnStateData object.
 +    assert(0);
 +    return 0;
 +}
 +
 +void
 +Downloader::writeControlMsgAndCall(HttpReply *rep, AsyncCall::Pointer &call)
 +{
 +}
 +
 +void
 +Downloader::handleReply(HttpReply *reply, StoreIOBuffer receivedData)
 +{
 +    Http::StreamPointer context = pipeline.front();
 +    bool existingContent = reply ? reply->content_length : 0;
 +    bool exceedSize = (context->startOfOutput() && existingContent > -1 && (size_t)existingContent > MaxObjectSize) || 
 +        ((object.length() + receivedData.length) > MaxObjectSize);
 +
 +    if (exceedSize) {
 +        status = Http::scInternalServerError;
 +        callBack();
 +        return;
 +    }
 +
 +    debugs(33, 4, "Received " << receivedData.length <<
 +           " object data, offset: " << receivedData.offset <<
 +           " error flag:" << receivedData.flags.error);
 +
 +    if (receivedData.length > 0) {
 +        object.append(receivedData.data, receivedData.length);
 +        context->http->out.size += receivedData.length;
 +        context->noteSentBodyBytes(receivedData.length);
 +    }
 +
 +    switch (context->socketState()) {
 +    case STREAM_NONE:
 +         debugs(33, 3, "Get more data");
 +        context->pullData();
 +        break;
 +    case STREAM_COMPLETE:
 +        debugs(33, 3, "Object data transfer successfully complete");
 +        status = Http::scOkay;
 +        callBack();
 +        break;
 +    case STREAM_UNPLANNED_COMPLETE:
 +        debugs(33, 3, "Object data transfer failed: STREAM_UNPLANNED_COMPLETE");
 +        status = Http::scInternalServerError;
 +        callBack();
 +        break;
 +    case STREAM_FAILED:
 +        debugs(33, 3, "Object data transfer failed: STREAM_FAILED");
 +        status = Http::scInternalServerError;
 +        callBack();
 +        break;
 +    default:
 +        fatal("unreachable code");
 +    }
 +}
 +
 +void
 +Downloader::downloadFinished()
 +{
 +    debugs(33, 3, "fake call, to just delete the Downloader");
 +
 +    // Not really needed. Squid will delete this object because "doneAll" is true.
 +    //deleteThis("completed");
 +}
 +
 +void
 +Downloader::callBack()
 +{
 +     CbDialer *dialer = dynamic_cast<CbDialer*>(callback->getDialer());
 +     Must(dialer);
 +     dialer->status = status;
 +     if (status == Http::scOkay)
 +         dialer->object = object;
 +     ScheduleCallHere(callback);
 +     callback = NULL;
 +     // Calling deleteThis method here to finish Downloader
 +     // may result to squid crash.
 +     // This method called by handleReply method which maybe called
 +     // by ClientHttpRequest::doCallouts. The doCallouts after this object deleted
 +     // may operate on non valid objects.
 +     // Schedule a fake call here just to force squid to delete this object
 +     CallJobHere(33, 7, CbcPointer<Downloader>(this), Downloader, downloadFinished);
 +}
 +
 +bool
 +Downloader::isOpen() const
 +{
 +    return cbdataReferenceValid(this) && // XXX: checking "this" in a method
 +        callback != NULL;
 +}
diff --cc src/Makefile.am
Simple merge
Simple merge
diff --cc src/debug.cc
Simple merge