Allow TOS redirect. Fix upload finished detection when redirecting.
This fixes https://code.google.com/p/singularity-viewer/issues/detail?id=705 Adds 'bool redirect_status_ok(void) const { return true; }' to LLIamHere, because it's ok to receive a 302 status there. Likewise added to LLIamHereVoice, because that has the same comment in its error() method. Also fixes the problem that if two redirects occur on a row, then the upload_finished detection asserted because it would detect the third time that libcurl turned off writing to the socket as a failure (the second time wasn't a problem because mUploadFinished was reset upon receiving the first 302 header, but not upon receiving the second header).
This commit is contained in:
@@ -806,7 +806,15 @@ void CurlSocketInfo::set_action(int action)
|
||||
if ((toggle_action & CURL_POLL_OUT))
|
||||
{
|
||||
if ((action & CURL_POLL_OUT))
|
||||
{
|
||||
mMultiHandle.mWritePollSet->add(this);
|
||||
if (mTimeout)
|
||||
{
|
||||
// Note that this detection normally doesn't work because mTimeout will be zero.
|
||||
// However, it works in the case of a redirect - and then we need it.
|
||||
mTimeout->upload_starting(); // Update timeout administration.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mMultiHandle.mWritePollSet->remove(this);
|
||||
@@ -2140,6 +2148,11 @@ size_t BufferedCurlEasyRequest::curlHeaderCallback(char* data, size_t size, size
|
||||
self_w->received_HTTP_header();
|
||||
self_w->setStatusAndReason(status, reason);
|
||||
done = true;
|
||||
if (status >= 300 && status < 400)
|
||||
{
|
||||
// Timeout administration needs to know if we're being redirected.
|
||||
self_w->httptimeout()->being_redirected();
|
||||
}
|
||||
}
|
||||
// Update timeout administration. This must be done after the status is already known.
|
||||
if (self_w->httptimeout()->data_received(header_len/*,*/ ASSERT_ONLY_COMMA(self_w->upload_error_status())))
|
||||
|
||||
@@ -133,6 +133,20 @@ void HTTPTimeout::reset_lowspeed(void)
|
||||
DoutCurl("reset_lowspeed: mLowSpeedClock = " << mLowSpeedClock << "; mStalled = -1");
|
||||
}
|
||||
|
||||
void HTTPTimeout::being_redirected(void)
|
||||
{
|
||||
mBeingRedirected = true;
|
||||
}
|
||||
|
||||
void HTTPTimeout::upload_starting(void)
|
||||
{
|
||||
// We're not supposed start with an upload when it already finished, unless we're being redirected.
|
||||
llassert(!mUploadFinished || mBeingRedirected);
|
||||
mUploadFinished = false;
|
||||
// Apparently there is something to upload. Start detecting low speed timeouts.
|
||||
reset_lowspeed();
|
||||
}
|
||||
|
||||
// CURL-THREAD
|
||||
// This is called when everything we had to send to the server has been sent.
|
||||
// <-----mLowSpeedOn------>
|
||||
@@ -143,7 +157,9 @@ void HTTPTimeout::upload_finished(void)
|
||||
{
|
||||
llassert(!mUploadFinished); // If we get here twice, then the 'upload finished' detection failed.
|
||||
mUploadFinished = true;
|
||||
// We finished uploading (if there was a body to upload at all), so not more transfer rate timeouts.
|
||||
// Only accept a call to upload_starting() if being_redirected() is called after this point.
|
||||
mBeingRedirected = false;
|
||||
// We finished uploading (if there was a body to upload at all), so no more transfer rate timeouts.
|
||||
mLowSpeedOn = false;
|
||||
// Timeout if the server doesn't reply quick enough.
|
||||
mStalled = sClockCount + mPolicy->getReplyDelay() / sClockWidth;
|
||||
@@ -179,11 +195,6 @@ bool HTTPTimeout::data_received(size_t n/*,*/
|
||||
// 'Upload finished' detection failed, generate it now.
|
||||
upload_finished();
|
||||
}
|
||||
// Turn this flag off again now that we received data, so that if 'upload_finished()' is called again
|
||||
// for a future upload on the same descriptor, then that won't trigger an assert.
|
||||
// Note that because we also set mNothingReceivedYet here, we won't enter this code block anymore,
|
||||
// so it's safe to do this.
|
||||
mUploadFinished = false;
|
||||
// Mark that something was received.
|
||||
mNothingReceivedYet = false;
|
||||
// We received something; switch to getLowSpeedLimit()/getLowSpeedTime().
|
||||
|
||||
@@ -77,9 +77,10 @@ class HTTPTimeout : public LLRefCount {
|
||||
AIHTTPTimeoutPolicy const* mPolicy; // A pointer to the used timeout policy.
|
||||
std::vector<U32> mBuckets; // An array with the number of bytes transfered in each second.
|
||||
U16 mBucket; // The bucket corresponding to mLastSecond.
|
||||
bool mNothingReceivedYet; // Set when created, reset when the HTML reply header from the server is received.
|
||||
bool mNothingReceivedYet; // Set when created, reset when the first HTML reply header from the server is received.
|
||||
bool mLowSpeedOn; // Set while uploading or downloading data.
|
||||
bool mLastBytesSent; // Set when the last bytes were sent to libcurl to be uploaded.
|
||||
bool mBeingRedirected; // Set when a 302 header is received, reset when upload finished is detected.
|
||||
bool mUploadFinished; // Used to keep track of whether upload_finished was called yet.
|
||||
S32 mLastSecond; // The time at which lowspeed() was last called, in seconds since mLowSpeedClock.
|
||||
S32 mOverwriteSecond; // The second at which the first bucket of this transfer will be overwritten.
|
||||
@@ -95,12 +96,18 @@ class HTTPTimeout : public LLRefCount {
|
||||
|
||||
public:
|
||||
HTTPTimeout(AIHTTPTimeoutPolicy const* policy, ThreadSafeBufferedCurlEasyRequest* lock_obj) :
|
||||
mPolicy(policy), mNothingReceivedYet(true), mLowSpeedOn(false), mLastBytesSent(false), mUploadFinished(false), mStalled((U64)-1)
|
||||
mPolicy(policy), mNothingReceivedYet(true), mLowSpeedOn(false), mLastBytesSent(false), mBeingRedirected(false), mUploadFinished(false), mStalled((U64)-1)
|
||||
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
|
||||
, mLockObj(lock_obj)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
// Called when a redirect header is received.
|
||||
void being_redirected(void);
|
||||
|
||||
// Called when curl makes the socket writable (again).
|
||||
void upload_starting(void);
|
||||
|
||||
// Called when everything we had to send to the server has been sent.
|
||||
void upload_finished(void);
|
||||
|
||||
|
||||
@@ -104,6 +104,7 @@ class LLIamHereVoice : public LLHTTPClient::ResponderWithResult
|
||||
};
|
||||
|
||||
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return iamHereVoice_timeout; }
|
||||
/*virtual*/ bool redirect_status_ok(void) const { return true; }
|
||||
/*virtual*/ char const* getName(void) const { return "LLIamHereVoice"; }
|
||||
};
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@ class LLIamHere : public LLHTTPClient::ResponderWithResult
|
||||
};
|
||||
|
||||
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return iamHere_timeout; }
|
||||
/*virtual*/ bool redirect_status_ok(void) const { return true; }
|
||||
/*virtual*/ char const* getName(void) const { return "LLIamHere"; }
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user