Fix for 'with active responder' llerrs crash.

This fixes at least one case (crash report 8407), which comes
down to not cleanly informing a responder of failure when the
request url is empty (or so badly formed that it isn't a valid
url). As a result, the statemachine would abort() without
informing the responder - which is bad, sort of.

The previous cases where the responder needed to be informed
of a failure, namely "statemachine timed_out()" and "bad_socket()"
when a socket suddenly becomes bad for unknown reason, have been
replaced with the more general 'aborted()' function, which must
be called before the statemachine calls abort(). Clearly this
has been done for all cases of abort() now, so that if the
llerrs fires again in the future then that would have to be
after the statemachine calls finish(), which is still as "impossible"
as it was - hence the llerrs is still there to make sure.

The reason that this seldom happened on SL, and more often on
opensim, even more often on home-brew test grids, seems plausible:
malformed urls happen more in those cases.

I also took the opportunity to improve the robustness of cases
where the curl error code is checked: it makes no sense to check
what curl gives as error code when an internal error occurred.
This commit is contained in:
Aleric Inglewood
2013-11-18 18:07:51 +01:00
parent bddb1ba48c
commit 7b9f854c66
6 changed files with 28 additions and 34 deletions

View File

@@ -121,6 +121,7 @@ void AICurlEasyRequestStateMachine::multiplex_impl(state_type run_state)
bool empty_url = AICurlEasyRequest_rat(*mCurlEasyRequest)->getLowercaseServicename().empty();
if (empty_url)
{
AICurlEasyRequest_wat(*mCurlEasyRequest)->aborted(HTTP_INTERNAL_ERROR_OTHER, "Not a valid URL.");
abort();
break;
}
@@ -195,16 +196,14 @@ void AICurlEasyRequestStateMachine::multiplex_impl(state_type run_state)
case AICurlEasyRequestStateMachine_removed:
{
// The request was removed from the multi handle.
if (mTimedOut)
{
AICurlEasyRequest_wat easy_request_w(*mCurlEasyRequest);
easy_request_w->timed_out();
}
// We're done. If we timed out, abort -- or else the application will
// think that getResult() will return a valid error code from libcurl.
if (mTimedOut)
{
AICurlEasyRequest_wat(*mCurlEasyRequest)->aborted(HTTP_INTERNAL_ERROR_CURL_LOCKUP, "Request timeout, aborted.");
abort();
}
else
finish();
@@ -212,7 +211,7 @@ void AICurlEasyRequestStateMachine::multiplex_impl(state_type run_state)
}
case AICurlEasyRequestStateMachine_bad_file_descriptor:
{
AICurlEasyRequest_wat(*mCurlEasyRequest)->bad_socket();
AICurlEasyRequest_wat(*mCurlEasyRequest)->aborted(HTTP_INTERNAL_ERROR_CURL_BADSOCKET, "File descriptor went bad! Aborted.");
abort();
}
}
@@ -224,7 +223,7 @@ void AICurlEasyRequestStateMachine::abort_impl(void)
// Revert call to addRequest() if that was already called (and the request wasn't removed again already).
if (mAdded)
{
// Note that it's safe to call this even if the curl thread already removed it, or will removes it
// Note that it's safe to call this even if the curl thread already removed it, or will remove it
// after we called this, before processing the remove command; only the curl thread calls
// MultiHandle::remove_easy_request, which is a no-op when called twice for the same easy request.
mAdded = false;