Moved mFinished/is_finished() from LegacyPolledResponder to Responder.

Slightly more robust, adds one boolean to all responders, 99%
of which don't need that though, and an extra call redirection,
but well... We might need it this way when I add the possibility
to abort a transfer.
This commit is contained in:
Aleric Inglewood
2012-10-22 22:52:18 +02:00
parent daac25c343
commit 243db9a3a8
5 changed files with 34 additions and 20 deletions

View File

@@ -433,7 +433,7 @@ std::string strerror(CURLcode errorcode)
// class Responder
//
Responder::Responder(void) : mReferenceCount(0)
Responder::Responder(void) : mReferenceCount(0), mFinished(false)
{
DoutEntering(dc::curl, "AICurlInterface::Responder() with this = " << (void*)this);
}
@@ -1340,7 +1340,7 @@ CurlResponderBuffer::~CurlResponderBuffer()
void CurlResponderBuffer::timed_out(void)
{
mResponder->completedRaw(HTTP_INTERNAL_ERROR, "Request timeout, aborted.", sChannels, mOutput);
mResponder->finished(HTTP_INTERNAL_ERROR, "Request timeout, aborted.", sChannels, mOutput);
mResponder = NULL;
}

View File

@@ -215,6 +215,9 @@ class Responder : public AICurlResponderBufferEvents {
// Headers received from the server.
AIHTTPReceivedHeaders mReceivedHeaders;
// Set when the transaction finished (with or without errors).
bool mFinished;
public:
// Called to set the URL of the current request for this Responder,
// used only when printing debug output regarding activity of the Responder.
@@ -223,6 +226,20 @@ class Responder : public AICurlResponderBufferEvents {
// Accessor.
std::string const& getURL(void) const { return mURL; }
// Called by CurlResponderBuffer::timed_out or CurlResponderBuffer::processOutput.
void finished(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer)
{
completedRaw(status, reason, channels, buffer);
mFinished = true;
}
// Return true if the curl thread is done with this transaction.
// If this returns true then it is guaranteed that none of the
// virtual functions will be called anymore: the curl thread
// will not access this object anymore.
// Note that normally you don't need to call this function.
bool is_finished(void) const { return mFinished; }
protected:
// Called when the "HTTP/1.x <status> <reason>" header is received.
/*virtual*/ void received_HTTP_header(void)
@@ -244,12 +261,6 @@ class Responder : public AICurlResponderBufferEvents {
completedHeaders(status, reason, mReceivedHeaders);
}
// Derived classes can override this to get the HTML headers that were received, when the message is completed.
virtual void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers)
{
// The default does nothing.
}
public:
// Derived classes that implement completed_headers()/completedHeaders() should return true here.
virtual bool needsHeaders(void) const { return false; }
@@ -257,15 +268,21 @@ class Responder : public AICurlResponderBufferEvents {
// Timeout policy to use.
virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const = 0;
// Derived classes can override this to get the raw data of the body of the HTML message that was received.
// The default is to interpret the content as LLSD and call completed().
virtual void completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer);
// A derived class should return true if curl should follow redirections.
// The default is not to follow redirections.
virtual bool followRedir(void) { return false; }
protected:
// Derived classes can override this to get the HTML headers that were received, when the message is completed.
virtual void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers)
{
// The default does nothing.
}
// Derived classes can override this to get the raw data of the body of the HTML message that was received.
// The default is to interpret the content as LLSD and call completed().
virtual void completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer);
// ... or, derived classes can override this to get the LLSD content when the message is completed.
// The default is to call result() (or errorWithContent() in case of a HTML status indicating an error).
virtual void completed(U32 status, std::string const& reason, LLSD const& content);
@@ -278,7 +295,7 @@ class Responder : public AICurlResponderBufferEvents {
// The default calls error().
virtual void errorWithContent(U32 status, std::string const& reason, LLSD const& content);
// ... or, derived classes can override this to get informed when a bad HTML statis code is received.
// ... or, derived classes can override this to get informed when a bad HTML status code is received.
// The default prints the error to llinfos.
virtual void error(U32 status, std::string const& reason);
@@ -311,21 +328,17 @@ class LegacyPolledResponder : public Responder {
CURLcode mCode;
U32 mStatus;
std::string mReason;
bool mFinished;
public:
LegacyPolledResponder(void) : mCode(CURLE_FAILED_INIT), mStatus(HTTP_INTERNAL_ERROR), mFinished(false) { }
LegacyPolledResponder(void) : mCode(CURLE_FAILED_INIT), mStatus(HTTP_INTERNAL_ERROR) { }
// Accessors.
CURLcode result_code(void) const { return mCode; }
U32 http_status(void) const { return mStatus; }
bool is_finished(void) const { return mFinished; }
std::string const& reason(void) const { return mReason; }
/*virtual*/ bool needsHeaders(void) const { return true; }
/*virtual*/ void completed_headers(U32 status, std::string const& reason, CURLcode code, AICurlInterface::TransferInfo* info);
// This must be defined by the derived class and set mFinished = true at the end.
/*virtual*/ void completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) = 0;
};
} // namespace AICurlInterface

View File

@@ -2109,7 +2109,7 @@ void CurlResponderBuffer::processOutput(AICurlEasyRequest_wat& curl_easy_request
// the body and provide completed/result/error calls.
mEventsTarget->completed_headers(responseCode, responseReason, code, (code == CURLE_FAILED_INIT) ? NULL : &info);
}
mResponder->completedRaw(responseCode, responseReason, sChannels, mOutput);
mResponder->finished(responseCode, responseReason, sChannels, mOutput);
mResponder = NULL;
}

View File

@@ -258,6 +258,8 @@ void BlockingResponder::completedRaw(U32, std::string const&, LLChannelDescripto
mBody << istr;
}
}
// Normally mFinished is set immediately after returning from this function,
// but we do it here, because we need to set it before calling mSignal.signal().
mSignal.lock();
mFinished = true;
mSignal.unlock();

View File

@@ -205,7 +205,6 @@ void XMLRPCResponder::completedRaw(U32 status, std::string const& reason, LLChan
}
}
}
mFinished = true;
}
LLXMLRPCValue XMLRPCResponder::responseValue(void) const