Commit Graph

44 Commits

Author SHA1 Message Date
Aleric Inglewood
b8d999066d Allow usage of default timeout policy 2014-07-26 02:46:11 +02:00
Aleric Inglewood
74dff061ff Support for new LL Responder API.
This adds mStatus, mReason and mContent to ResponderBase
and fills those in instead of passing it to member functions.
The added danger here is that now code can accidently try
to access these variables while they didn't already get a
correct value.

Affected members of ResponderBase (that now have less arguments):
decode_llsd_body, decode_raw_body, completedHeaders,
completed -> httpCompleted, result -> httpSuccess,
errorWithContent and error -> httpFailure.

New API:

ResponderBase::setResult
ResponderBase::getStatus()
ResponderBase::getReason()
ResponderBase::getContent()
ResponderBase::getResponseHeaders() (returns AIHTTPReceivedHeaders though, not LLSD)
ResponderBase::dumpResponse()
ResponderWithCompleted::completeResult
ResponderWithResult::failureResult (previously pubErrorWithContent)
ResponderWithResult::successResult (previously pubResult)

Not implemented:

getHTTPMethod() - use getName() instead which returns the class name of the responder.

completedHeaders() is still called as usual, although you can ignore
it (not implement in a derived responder) and call getResponseHeaders()
instead, provided you implement needsHeaders() and have it return true.

However, classes derived from ResponderHeadersOnly do not have
completedHeaders(), so they still must implement completedHeaders(),
and then call getResponseHeaders() or just access mReceivedHeaders
directly, as usual.
2014-07-12 18:29:44 +02:00
Aleric Inglewood
589035c1db Attempt to fix gray avatars on mobile networks.
Ported from
e879862791
2014-06-16 21:02:27 +02:00
Inusaito Sayori
5c06afc977 [LLMeshRepo sync] AICurl updates toward LLCurl
LLHTTPClient::getByteRange no longer throws AICurlNoEasyHandle, instead it returns whether or not it threw, to match the true/false convention of LLCurl.
- In addition, the header param has been shifted to earlier in this function to ease diffings.
ResponderBase now has static bool isGoodStatus, introduced into the Responder base class of LLCurl
2014-04-17 20:23:48 -04:00
Aleric Inglewood
723f4963e0 Do not count long poll connections against CurlConcurrentConnectionsPerService
This is necessary for opensim mega regions that can have up to 16 long
poll connections for a single service, while upping the maximum number
of connections per service just for that is clearly nonsense.

I also changed that long poll connections do not "use" the "Other"
capability type (which shows that the debug info in the HTTP debug
console for the Other capability type turns grey when it only has event
poll connections). As a result additional connections become available
for textures, mesh and the inventory (the other capability types) on
opensim, which has all types on the same service, because now Other
does no longer constantly reserves a full share of the available
connections. This makes the actual number of connections used for
textures and mesh a lot more like it is on Second Life.
2013-09-30 17:39:17 +02:00
Aleric Inglewood
1c0f87d82f Let curl follow redirects by default.
Turns out that the only responders that want to get the redirect
status codes themselves are the ones that already had a
redirect_status_ok() exception.
2013-09-28 20:41:10 +02:00
Aleric Inglewood
0353498b9c Set CURLOPT_FORBID_REUSE for XMLRPCResponder
XMLRPCResponder is used to login, which is a HTTP 1.0 server
that doesn't support reuse of connections.
It's cleaner to close connections from our side too.

This changes,
0x7fffdcf93700   CURLIO      0x7fffcd86db40   * Connection #0 to host login.agni.lindenlab.com left intact
into
0x7fffdcf93700   CURLIO      0x7fffcd8b0bd0   * Closing connection #0
2013-07-01 15:44:47 +02:00
Aleric Inglewood
cf4c4a72c2 Added AICapabilityType and related.
This splits the AIPerService queue up into four queues: one for each
"capability type". On Second Life that doesn't make a difference in
itself for textures because the texture service only serves one
capability type: textures. Other services however can serve two types,
while on Avination - that currently only has one services for everything
- this really makes a difference because that single service now has
four queues.

More importantly however is that the administration of how many requests
are in the "pipeline" (from approving that a new HTTP request may be
added for given service, till curl finished it) is now per capability
type (or service/capabitity type pair actually). This means downloads of
a certain capability type (textures, inventory, mesh, other) will no
longer stall because unapproved requests cluttered the queue for a given
service.

Moreover, before when a request did finished, it would only look for a
new request in the queue of the service that just finished. This simple
algorithm worked when there were no 'PerSerice' objects, and only one
'Curl' queue: because if anything was queued that that was because there
were running requests, and when one of those running requests finished
it made sense to see if one of those queued requests could be added now.
However, after adding multiple queues, one for each service, it could
happen that service A had queued requests while only requests from
service B were actually running: only requests of B would ever finish
and the requests of A would be queued forever.

With this patch the algorithm is to look alternating first in the
texture request queue and then in the inventory request queue - or vice
versa, and if there are none of those, look for a request of a different
type. If also that cannot be found, look for a request in another
service. This is still not optimal and subject to change.
2013-05-21 23:34:23 +02:00
Aleric Inglewood
929badb110 Let statemachine honor approvements.
The inventory bulk fetch is not thread-safe, so the it doesn't start
right away, causing the approvement not to be honored upon return from
post_approved (formerly post_nb).

This patch renames wantsMoreHTTPReqestsFor to approveHTTPRequestFor,
and has it return NULL or a AIPerService::Approvement object.
The latter is now passed to the CurlEasyHandle object instead of just a
boolean mQueueIfTooMuchBandwidthUsage, and then the Approvement is
honored by the state machine right after the request is actually added
to the command queue.

This should avoid a flood of inventory requests in the case
approveHTTPRequestFor is called multiple times before the main thread
adds the requests to the command queue. I don't think that actually ever
happens, but I added debug code (to find some problem) that is so damn
strictly checking everything that I need to be this precise in order to
do that testing.
2013-05-12 04:19:44 +02:00
Aleric Inglewood
1d629438c0 Add HTTP bandwidth throttling for every other responder.
Most notably getMesh (the only one possibly using any significant
bandwidth), but in general every type of requests that just have to
happen anyway and in the order they are requested: they are just passed
to the curl thread, but now the curl thread will queue them and hold
back if the (general) service they use is loaded too heavily.
2013-05-06 02:54:10 +02:00
Aleric Inglewood
7dfef31469 Possible upload timeout improvement.
When uploading finishes, but is not detected, the timeout should be for
"reply delay", the time that the server takes before it replies, and not
CurlTimeoutLowSpeedTime. This patch adds code that takes this failure
into account (which happened only ONCE for me on Metropolis while flying
around and using trickle (not sure if that is relevant), so it's not
that likely to improvement anything in practise. Note that it is
detected by an assertion when it happens, so that we can safely assume
it normally never happened on SL).

* Generalized PUT / POST configuration by adding
  CurlEasyRequest::setPut, which now also supports keep-alive (which
  still isn't used).
* Upload content length is now stored in CurlEasyRequest::mContentLength
* CurlEasyRequest::has_stalled() now return false if it was possbile
  that the 'upload finished' detect failed AND calls upload_finished()
  itself in that case, so it is no longer 'const'.
* If low speed is detect exactly when the last bytes are being attempted
  to be sent (unlikely scenario), then the upload gets 4 more seconds
  after which is switches to CurlTimeoutReplyDelay.
* Added EDoesAuthentication and EAllowCompressedReply to replace
  booleans, for readability and type-safety, as did EKeepAlive. Note
  that this change inverts the meaning of the compression related parameter.
* Unrelated: removed an unnecessary #include "llurlrequest.h" from
  llxmlrpcresponder.h
2013-03-10 16:43:15 +01:00
Aleric Inglewood
96d302aa42 Be more verbose about internal (curl / timeout) errors.
Translates the CURLE_WRITE_ERROR into what it really means: that the low
speed check failed.
2013-03-09 05:26:52 +01:00
Aleric Inglewood
b9b5f13624 Run HTTPGetResponder in any thread.
This fixes a bug where unref() was called when a state machine was
aborted before it reached bs_initialized. Debug code was added to detect
errors related to that.

In order to run HTTPGetResponder in any thread, I needed direct access
to LLHTTPClient::request, so I had to move that to the header file,
and therefore had to move ERequestAction from LLURLRequest to
LLHTTPClient to avoid include problems.

With this, textures are fetched with no latency: call to
LLHTTPClient::request runs all the way till the state machine is idle
(AICurlEasyRequestStateMachine_waitAdded). There is small delay till the
curl thread wakes up, which then processes the request and opens the url
etc. When the transaction is finished, it calls
AIStateMachine::advance_state(AICurlEasyRequestStateMachine_removed_after_finished)
which subsequently doesn't return until the state machine is completely
finished (bs_killed). The LLURLRequest isn't deleted yet at that point
because the AITimer of the LLURLRequest runs in the main thread: it is
aborted, but only the next time the main thread state engines run that
is deleted and the timer keeps an LLPointer to it's parent, the
LLURLRequest, so only then the LLURLRequest object is destructed. This
however has nothing to do with the texture-bandwidth loop.
2013-03-07 01:52:21 +01:00
Aleric Inglewood
4851cc174e Revert "Work in progress"
This reverts commit ef35aa7954
because it contained too much wrong things that I won't be
using. I'll re-commit stuff from it after that that I do
want to keep.
2013-02-23 20:00:13 +01:00
Aleric Inglewood
ef35aa7954 Work in progress
This work extends AIStateMachine to run multiplex() in the thread
that calls run(), cont() or set_state(). Note that all three
eventually call locked_cont(), so thats where multiplex() is called
from. Calling multiplex() means "running the state machine", as in
"calling multiplex_impl".

Currently only LLURLRequest uses this feature, and then only
for the HTTPGetResponder, and well only for the initializing,
start up and normal finish states.

A current/remaining problem is that we run into a situation where
the curl thread runs a statemachine to it's finish and kills it,
while the main thread is also 'running' it and tries to call
multiplex while the statemachine isn't running anymore.
2013-02-20 23:29:38 +01:00
Aleric Inglewood
1c8027b1e6 Add statemachine parent callback support to LLHTTPClient::post 2013-01-27 22:02:19 +01:00
Aleric Inglewood
024c62aed4 Fix the "map/set iterators incompatible" bug.
cookies is only valid when AIHTTPReceivedHeaders::getValues return true.
2013-01-12 04:24:21 +01:00
Aleric Inglewood
f9738cb611 Add getName() to every non-base class Responder object. 2013-01-11 04:15:55 +01:00
Aleric Inglewood
32614d3539 Compile bug fix 2012-12-27 17:38:28 +01:00
Aleric Inglewood
b22832ba54 Fix cookie handling.
Cookies are now collected during redirects, one the last cookie
of a given name is kept. Cookies are then set by looking for
the right cookie name (instead of what viewer 3 does: just
use the last cookie that was set).

This fixes the merchant outbox.
2012-12-24 19:58:54 +01:00
Aleric Inglewood
fac3fc67b6 Add filtering for curl debug output.
Add CURLTR debug channel for libcurl API calls,
and use CURLIO only for libcurl debug output.
Note: need to set gDebugCurlTerse to true for
filtering to take effect, then pass 'debug_on'
to the LLHttpClient methods that require debugging.
2012-12-24 02:54:36 +01:00
Aleric Inglewood
8095d6c48c Large snapshot update (part 3) 2012-12-22 19:07:08 +01:00
Aleric Inglewood
f44de434c2 Always use followRedir() to determine if redirections should be followed.
Before every HEAD and GET request allowed redirection by default,
without setting a limit on the number of redirections. This caused
an infinite redirect loop when connecting to marketplace, in combination
with the bug that we did not allow cookies.
2012-11-18 02:07:19 +01:00
Aleric Inglewood
6f8ea87c46 Add ResponderHeadersOnly.
ResponderHeadersOnly is a base class for responders that use
HTTPClient::head or HTTPClient::getHeaderOnly. It already
has a needsHeaders() that return true and only allows for
completedHeaders to be overridden.

I removed the CURLOPT_HEADER option for these cases, because
that only causes the headers to be send to the writeCallback
as if they are part of the body, in addition to the headerCallback;
That gave raise to some confusion for the existing code (ie,
unexpected errors when trying to decode the body as LLSD and
duplicated 'low speed' information for the Timeout policy code.
2012-11-13 21:46:35 +01:00
Aleric Inglewood
ab91525e7a Add missing needHeaders
The AIBufferedCurlEasyRequestEvents are not triggered unless
the derived class return true for needsHeaders().
That means, every class that implements received_HTTP_header(),
received_header() or completed_headers(), or implement
the virtual function completedHeaders(), or use the protected
member mReceivedHeaders directly.
This commits adds missing needsHeaders() for LLAvatarNameCache
(thanks Siana) and XMLRPCResponder. The former now uses
mReceivedHeaders directly instead of making a copy.
2012-11-11 17:36:43 +01:00
Aleric Inglewood
a1f5e6ba43 Rename AICurlResponderBufferEvents to AIBufferedCurlEasyRequestEvents
Since we changed CurlResponderBuffer to be derived from CurlEasyRequest
and therefore changed it's name to BufferedCurlEasyRequest, we should
also rename AICurlResponderBufferEvents to
AIBufferedCurlEasyRequestEvents.
This commit also fixes C++ comment in several places to reflex the
previous name change.
2012-11-07 01:49:45 +01:00
Aleric Inglewood
72bde5234a Rename CurlResponderBuffer to BufferedCurlEasyRequest and derive it from CurlEasyRequest
Every curl transaction is a AICurlEasyRequestStateMachine which has a
AICurlEasyRequest as member, which is a reference counting pointer to
a ThreadSafeBufferedCurlEasyRequest. And now BufferedCurlEasyRequest is
derived from CurlEasyRequest which is derived from CurlEasyHandle, but
neither are used separatedly.
2012-11-02 18:41:23 +01:00
Aleric Inglewood
c0ac428179 Code cleanup
* Moved Responder stuff to LLHTTPClient.
* Renamed LLHTTPClient::Responder to LLHTTPClient::ResponderWithResult.
* Deleted LLHTTPClientAdapter and LLHTTPClientInterface.
* Renamed AICurlInterface::TransferInfo to AITransferInfo and moved it
  to llhttpclient.h
* Removed 'CURLcode code' argument from completed_headers.
2012-10-31 23:11:42 +01:00
Aleric Inglewood
0b265320a9 Code clean up.
* Removed LLCurlRequest and replaced it's last usage with LLHTTPClient API calls.
* Deleted dead code.
* Renamed all the get4/post4/put4/getByteRange4 etc, back to their
  original name without the '4'.
2012-10-31 05:01:24 +01:00
Aleric Inglewood
65e012c540 More curl fixes and changes.
* Moved LegacyPolledResponder::mCode to ResponderBase::mCode.
* Added a parameter to ResponderBase::finished (and pubError*) to set mCode.
* Renamed ResponderBase::decode_body to decode_llsd_body and added ResponderBase::decode_raw_body.
* Use LegacyPolledResponder::finished instead of LegacyPolledResponder::completed_headers
  to set remaining cached values.
* Fixed assertion in case of -DCWDEBUG and upload finish detection failure in case of HEAD
  method (mDebugIsGetMethod -> mDebugIsHeadOrGetMethod).
* Add XmlTreeInjector : support for LLXmlTree.
* Split BlockingResponder into BlockingLLSDResponder and BlockingRawResponder.
* Final blocking responders are now: BlockingLLSDPostResponder, BlockingLLSDGetResponder
  and BlockingRawGetResponder.
* Added LLHTTPClient::blockingGetRaw
* Got rid of hipporestrequest.* -- and fixed hippogridmanager.cpp to use
  LLHTTPClient::blockingGetRaw instead, and fixed llviewermessage.cpp to use
  AICurlInterface::ResponderWithCompleted and decode_raw_body instead of
  HippoRestHandlerRaw and LLHTTPClient::get4 instead of HippoRestRequest::get5.
2012-10-28 17:38:25 +01:00
Aleric Inglewood
2a88f7d7c4 ResponderAdapter stuff
Renamed AICurlInterface::Responder to AICurlInterface::ResponderBase,
but without the virtual 'event' methods.
Derived from that: Responder and ReponderWithCompleted, where the
first defines result = 0, ErrorWithContent and error, and the latter
completedRaw and completed.
Added HttpClient::IgnoreBody, derived from Responder and implementing
'result' doing nothing; HttpClient::Ignore is now derived from
IgnoreBody and defines the still pure virtual getHTTPTimeoutPolicy.

Added ResponderBase::decode_body, which is now the sole place
where the code makes the decision wether some response data might be
LLSD or not based on the http status result. Before it just tried
to decode everything as LLSD, which seems a bit nonsense.

ResponderWithCompleted::completed no longer does anything, since
classes derived from ResponderWithCompleted are expected to override it,
or never call it by overriding completedRaw.

Entry point is now ResponderBase::finished = 0, instead of
completedRaw, where ResponderWithCompleted implements finished by
called completedRaw, but Responder doesn't: that directly calls
result/errorWithContent/error. Or, for the hack ResponderAdapter,
the entry points are pubResult/pubErrorWithContent.
Those are now the ONLY public methods, so more confusion.
mFinished is now set in all cases.

As a result of all that, it is no longer possible to accidently
pass a responder to ResponderAdapter that would break because it
expects completed() and completedRaw() to be called.

Added LLBufferArray::writeChannelTo.

Fixed bug for BlockingResponder::body (returned reference to temporary).

LLSDMessage::ResponderAdapter now allows a "timeoutpolicy" name
to be passed (not doing so results in the default timings), so
that the timeout policy of the used responder is retained.

Fixed llfasttimerview.cpp to test LLSDSerialize::fromXML() to return
a positive value instead of non-zero, because it may return -1 when the
parsing fails (three places).

Removed LLHTTPClient::Responder as base class from
LLFloaterRegionDebugConsole completely: it isn't a responder!

Several other responder classes were simplified a bit in order to
compile again with the above changes.
2012-10-26 04:13:29 +02:00
Aleric Inglewood
7f50b2ba7b Add XMLRPC support to LLHTTPClient and that instead of LLXMLRPCTransaction 2012-10-22 01:59:17 +02:00
Aleric Inglewood
3f1fb9a66e Add improved timeout handling for HTTP transactions.
Introduces AIHTTPTimeoutPolicy objects which do not just
specify a single "timeout" in seconds, but a plethora of
timings related to the life cycle of the average HTTP
transaction.

This knowledge is that moved to the Responder being
used instead of floating constants hardcoded in the
callers of http requests. This assumes that the same
timeout policy is wanted for each transaction that
uses the same Responder, which can be enforced is needed.

I added a AIHTTPTimeoutPolicy for EVERY responder,
only to make it easier later to tune timeout values
and/or to get feedback about which responder runs
into HTTP errors in debug output (especially time outs),
so that they can be tuned later. If we already understood
exactly what we were doing then most responders could
have been left alone and just return the default timeout
policy: by far most timeout policies are just a copy
of the default policy, currently.

This commit is not finished... It's a work in progress
(viewer runs fine with it though).
2012-10-05 15:53:29 +02:00
Aleric Inglewood
83b13f6a3f WIP: make everything use AICurlEasyRequestStateMachine 2012-08-20 21:18:19 +02:00
Aleric Inglewood
536cb6febd Merge branch 'curlthreading2' into curlthreading3
Conflicts:
	indra/CMakeLists.txt
	indra/llcommon/llstring.h
	indra/llmessage/CMakeLists.txt
	indra/llmessage/llhttpclient.cpp
	indra/llmessage/llhttpclient.h
	indra/llmessage/llurlrequest.cpp
	indra/llmessage/llurlrequest.h
	indra/newview/hipporestrequest.cpp
	indra/newview/llappviewer.cpp
2012-08-15 00:51:40 +02:00
Aleric Inglewood
19293601b3 Manual pick of stuff from 'shycurl' (68ad5411) that seemed to make sense. 2012-08-14 02:38:06 +02:00
Siana Gearz
36ff4dcd11 Don't feed empty, non-working callback to CURL
Cherry-Pick of 96a4e16a

Conflicts:
	indra/llmessage/llurlrequest.cpp
	indra/llmessage/llurlrequest.h
	indra/newview/hipporestrequest.cpp

Clear reasons for conflicts, resolved.
2012-08-13 23:33:49 +02:00
Aleric Inglewood
af4ac8fb5f WIP: work on rewriting LLURLRequest 2012-07-29 01:30:11 +02:00
Aleric Inglewood
69ca6cd5b2 WIP: Make curl thread code robust and flexible.
Conflicts:

	indra/llmessage/llcurl.cpp
	indra/llmessage/llcurl.h
	indra/newview/app_settings/settings.xml
	indra/newview/llappviewer.cpp
	indra/newview/llmeshrepository.cpp

Resolved:

	indra/llmessage/llcurl.cpp:

	  Basically removed (not used anyway)

	indra/llmessage/llcurl.h:

	  Basically removed (just includes aiculr.h now)

	indra/newview/app_settings/settings.xml:

	  CurlUseMultipleThreads was remvoved.
	  CurlMaximumNumberOfHandles and CurlRequestTimeOut
	  are still in there, but unused at the moment.

	indra/newview/llappviewer.cpp:

	  CurlMaximumNumberOfHandles and CurlRequestTimeOut
	  are unused at the moment.

	indra/newview/llmeshrepository.cpp:

	  Lock mSignal always (is unlocked inside wait()).
	  Use mSignal lock to see if we are waiting; remove mWaiting.
	  Return false from the MeshFetch functions iff we have to retry
	  a HTTP fetch. Catch the error exception thrown by getByteRange
	  instead of using it's return value (always returns true
	  anyway).
2012-06-28 01:30:46 +02:00
Siana Gearz
21170e1e18 Fix build on Windows 2012-03-12 00:35:47 +01:00
Siana Gearz
8b6f462d13 Wholesale update of llmessage to V3.2
Note that this removes message logger for now.
2012-03-06 07:31:15 +01:00
Siana Gearz
179f4ddabb The Octopus Feature
___
                     .-'   `'.
                    /         \
                    |         ;
                    |         |           ___.--,
           _.._     |0) ~ (0) |    _.---'`__.-( (_.
    __.--'`_.. '.__.\    '--. \_.-' ,.--'`     `""`
   ( ,.--'`   ',__ /./;   ;, '.__.'`    __
   _`) )  .---.__.' / |   |\   \__..--""  """--.,_
  `---' .'.''-._.-'`_./  /\ '.  \ _.-~~~````~~~-._`-.__.'
        | |  .' _.-' |  |  \  \  '.               `~---`
         \ \/ .'     \  \   '. '-._)
          \/ /        \  \    `=.__`~-.
     jgs  / /\         `) )    / / `"".`\
    , _.-'.'\ \        / /    ( (     / /
     `--~`   ) )    .-'.'      '.'.  | (
            (/`    ( (`          ) )  '-;
             `      '-;         (-'
2011-03-24 23:54:23 +01:00
Shyotl
f9937d7f8a V2 llmessage merge, incl. llcommon requisites.
Excluded llareslistener, as that appears to only be present for unit-testing
Excluded new SSL methods because, well, they don't work right reliably in v2 for me
2011-02-25 19:30:59 -06:00
Hazim Gazov
7a86d01598 Imported existing code 2010-04-02 02:48:44 -03:00