Merge remote-tracking branch 'singu/master'
Conflicts: indra/cmake/WebKitLibPlugin.cmake indra/llmessage/llurlrequest.cpp indra/plugins/webkit/media_plugin_webkit.cpp
This commit is contained in:
@@ -29,6 +29,10 @@
|
||||
#include "linden_common.h"
|
||||
#include "llurlrequest.h"
|
||||
|
||||
#ifdef CWDEBUG
|
||||
#include <libcwd/buf2str.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <openssl/x509_vfy.h>
|
||||
#include <openssl/ssl.h>
|
||||
@@ -48,13 +52,10 @@ static const U32 HTTP_STATUS_PIPE_ERROR = 499;
|
||||
/**
|
||||
* String constants
|
||||
*/
|
||||
const std::string CONTEXT_DEST_URI_SD_LABEL("dest_uri");
|
||||
const std::string CONTEXT_TRANSFERED_BYTES("transfered_bytes");
|
||||
|
||||
|
||||
static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user);
|
||||
|
||||
|
||||
static size_t headerCallback(char* data, size_t size, size_t nmemb, void* user);
|
||||
|
||||
/**
|
||||
* class LLURLRequestDetail
|
||||
@@ -65,33 +66,26 @@ public:
|
||||
LLURLRequestDetail();
|
||||
~LLURLRequestDetail();
|
||||
std::string mURL;
|
||||
LLCurlEasyRequest* mCurlRequest;
|
||||
LLBufferArray* mResponseBuffer;
|
||||
AICurlEasyRequest mCurlEasyRequest;
|
||||
LLIOPipe::buffer_ptr_t mResponseBuffer;
|
||||
LLChannelDescriptors mChannels;
|
||||
U8* mLastRead;
|
||||
U32 mBodyLimit;
|
||||
S32 mByteAccumulator;
|
||||
bool mIsBodyLimitSet;
|
||||
LLURLRequest::SSLCertVerifyCallback mSSLVerifyCallback;
|
||||
};
|
||||
|
||||
LLURLRequestDetail::LLURLRequestDetail() :
|
||||
mCurlRequest(NULL),
|
||||
mResponseBuffer(NULL),
|
||||
mCurlEasyRequest(false),
|
||||
mLastRead(NULL),
|
||||
mBodyLimit(0),
|
||||
mByteAccumulator(0),
|
||||
mIsBodyLimitSet(false)
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
mCurlRequest = new LLCurlEasyRequest();
|
||||
}
|
||||
|
||||
LLURLRequestDetail::~LLURLRequestDetail()
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
delete mCurlRequest;
|
||||
mResponseBuffer = NULL;
|
||||
mLastRead = NULL;
|
||||
}
|
||||
|
||||
@@ -123,6 +117,7 @@ LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action) :
|
||||
mAction(action)
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
// This might throw AICurlNoEasyHandle.
|
||||
initialize();
|
||||
}
|
||||
|
||||
@@ -132,6 +127,7 @@ LLURLRequest::LLURLRequest(
|
||||
mAction(action)
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
// This might throw AICurlNoEasyHandle.
|
||||
initialize();
|
||||
setURL(url);
|
||||
}
|
||||
@@ -139,13 +135,16 @@ LLURLRequest::LLURLRequest(
|
||||
LLURLRequest::~LLURLRequest()
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
{
|
||||
AICurlEasyRequest_wat curl_easy_request_w(*mDetail->mCurlEasyRequest);
|
||||
curl_easy_request_w->revokeCallbacks();
|
||||
curl_easy_request_w->send_events_to(NULL);
|
||||
}
|
||||
delete mDetail;
|
||||
mDetail = NULL ;
|
||||
}
|
||||
|
||||
void LLURLRequest::setURL(const std::string& url)
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
mDetail->mURL = url;
|
||||
}
|
||||
|
||||
@@ -153,19 +152,21 @@ std::string LLURLRequest::getURL() const
|
||||
{
|
||||
return mDetail->mURL;
|
||||
}
|
||||
|
||||
void LLURLRequest::addHeader(const char* header)
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
mDetail->mCurlRequest->slist_append(header);
|
||||
AICurlEasyRequest_wat curlEasyRequest_w(*mDetail->mCurlEasyRequest);
|
||||
curlEasyRequest_w->addHeader(header);
|
||||
}
|
||||
|
||||
void LLURLRequest::checkRootCertificate(bool check)
|
||||
{
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, (check? TRUE : FALSE));
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, "");
|
||||
AICurlEasyRequest_wat curlEasyRequest_w(*mDetail->mCurlEasyRequest);
|
||||
curlEasyRequest_w->setopt(CURLOPT_SSL_VERIFYPEER, check ? 1L : 0L);
|
||||
curlEasyRequest_w->setoptString(CURLOPT_ENCODING, "");
|
||||
}
|
||||
|
||||
|
||||
void LLURLRequest::setBodyLimit(U32 size)
|
||||
{
|
||||
mDetail->mBodyLimit = size;
|
||||
@@ -176,7 +177,8 @@ void LLURLRequest::setCallback(LLURLRequestComplete* callback)
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
mCompletionCallback = callback;
|
||||
mDetail->mCurlRequest->setHeaderCallback(&headerCallback, (void*)callback);
|
||||
AICurlEasyRequest_wat curlEasyRequest_w(*mDetail->mCurlEasyRequest);
|
||||
curlEasyRequest_w->setHeaderCallback(&headerCallback, (void*)callback);
|
||||
}
|
||||
|
||||
// Added to mitigate the effect of libcurl looking
|
||||
@@ -210,26 +212,41 @@ void LLURLRequest::useProxy(bool use_proxy)
|
||||
}
|
||||
}
|
||||
|
||||
LL_DEBUGS("Proxy") << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (!env_proxy.empty() ? env_proxy : "(null)") << LL_ENDL;
|
||||
LL_DEBUGS("Proxy") << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (!env_proxy.empty() ? env_proxy : "(null)") << LL_ENDL;
|
||||
|
||||
if (use_proxy && !env_proxy.empty())
|
||||
{
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy);
|
||||
}
|
||||
else
|
||||
{
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, "");
|
||||
}
|
||||
AICurlEasyRequest_wat curlEasyRequest_w(*mDetail->mCurlEasyRequest);
|
||||
curlEasyRequest_w->setoptString(CURLOPT_PROXY, (use_proxy && !env_proxy.empty()) ? env_proxy : std::string(""));
|
||||
}
|
||||
|
||||
void LLURLRequest::useProxy(const std::string &proxy)
|
||||
{
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, proxy);
|
||||
AICurlEasyRequest_wat curlEasyRequest_w(*mDetail->mCurlEasyRequest);
|
||||
curlEasyRequest_w->setoptString(CURLOPT_PROXY, proxy);
|
||||
}
|
||||
|
||||
void LLURLRequest::allowCookies()
|
||||
{
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_COOKIEFILE, "");
|
||||
AICurlEasyRequest_wat curlEasyRequest_w(*mDetail->mCurlEasyRequest);
|
||||
curlEasyRequest_w->setoptString(CURLOPT_COOKIEFILE, "");
|
||||
}
|
||||
|
||||
//virtual
|
||||
bool LLURLRequest::hasExpiration(void) const
|
||||
{
|
||||
// Currently, this ALWAYS returns false -- because only AICurlEasyRequestStateMachine uses buffered
|
||||
// AICurlEasyRequest objects, and LLURLRequest uses (unbuffered) AICurlEasyRequest directly, which
|
||||
// have no expiration facility.
|
||||
return mDetail->mCurlEasyRequest.isBuffered();
|
||||
}
|
||||
|
||||
//virtual
|
||||
bool LLURLRequest::hasNotExpired(void) const
|
||||
{
|
||||
if (!mDetail->mCurlEasyRequest.isBuffered())
|
||||
return true;
|
||||
AICurlEasyRequest_wat buffered_easy_request_w(*mDetail->mCurlEasyRequest);
|
||||
AICurlResponderBuffer_wat buffer_w(*mDetail->mCurlEasyRequest);
|
||||
return buffer_w->isValid();
|
||||
}
|
||||
|
||||
// virtual
|
||||
@@ -237,7 +254,27 @@ LLIOPipe::EStatus LLURLRequest::handleError(
|
||||
LLIOPipe::EStatus status,
|
||||
LLPumpIO* pump)
|
||||
{
|
||||
DoutEntering(dc::curl, "LLURLRequest::handleError(" << LLIOPipe::lookupStatusString(status) << ", " << (void*)pump << ")");
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
|
||||
if (LL_LIKELY(!mDetail->mCurlEasyRequest.isBuffered())) // Currently always true.
|
||||
{
|
||||
// The last reference will be deleted when the pump that this chain belongs to
|
||||
// is removed from the running chains vector, upon returning from this function.
|
||||
// This keeps the CurlEasyRequest object alive until the curl thread cleanly removed it.
|
||||
Dout(dc::curl, "Calling mDetail->mCurlEasyRequest.removeRequest()");
|
||||
mDetail->mCurlEasyRequest.removeRequest();
|
||||
}
|
||||
else if (!hasNotExpired())
|
||||
{
|
||||
// The buffered version has it's own time out handling, and that already expired,
|
||||
// so we can ignore the expiration of this timer (currently never happens).
|
||||
// I left it here because it's what LL did (in the form if (!isValid() ...),
|
||||
// and it would be relevant if this characteristic of mDetail->mCurlEasyRequest
|
||||
// would change. --Aleric
|
||||
return STATUS_EXPIRED ;
|
||||
}
|
||||
|
||||
if(mCompletionCallback && pump)
|
||||
{
|
||||
LLURLRequestComplete* complete = NULL;
|
||||
@@ -252,9 +289,21 @@ LLIOPipe::EStatus LLURLRequest::handleError(
|
||||
return status;
|
||||
}
|
||||
|
||||
void LLURLRequest::added_to_multi_handle(AICurlEasyRequest_wat&)
|
||||
{
|
||||
}
|
||||
|
||||
void LLURLRequest::finished(AICurlEasyRequest_wat&)
|
||||
{
|
||||
}
|
||||
|
||||
void LLURLRequest::removed_from_multi_handle(AICurlEasyRequest_wat&)
|
||||
{
|
||||
mRemoved = true;
|
||||
}
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST("URL Request");
|
||||
static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST_GET_RESULT("Get Result");
|
||||
static LLFastTimer::DeclareTimer FTM_URL_PERFORM("Perform");
|
||||
|
||||
// virtual
|
||||
LLIOPipe::EStatus LLURLRequest::process_impl(
|
||||
@@ -269,9 +318,10 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
//llinfos << "LLURLRequest::process_impl()" << llendl;
|
||||
if (!buffer) return STATUS_ERROR;
|
||||
|
||||
if (!mDetail) return STATUS_ERROR; //Seems to happen on occasion. Need to hunt down why.
|
||||
|
||||
// we're still waiting or prcessing, check how many
|
||||
// we're still waiting or processing, check how many
|
||||
// bytes we have accumulated.
|
||||
const S32 MIN_ACCUMULATION = 100000;
|
||||
if(pump && (mDetail->mByteAccumulator > MIN_ACCUMULATION))
|
||||
@@ -309,44 +359,42 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
|
||||
|
||||
// *FIX: bit of a hack, but it should work. The configure and
|
||||
// callback method expect this information to be ready.
|
||||
mDetail->mResponseBuffer = buffer.get();
|
||||
mDetail->mResponseBuffer = buffer;
|
||||
mDetail->mChannels = channels;
|
||||
if(!configure())
|
||||
{
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
mRemoved = false;
|
||||
mState = STATE_WAITING_FOR_RESPONSE;
|
||||
mDetail->mCurlEasyRequest.addRequest(); // Add easy handle to multi handle.
|
||||
|
||||
// *FIX: Maybe we should just go to the next state now...
|
||||
return STATUS_BREAK;
|
||||
}
|
||||
case STATE_WAITING_FOR_RESPONSE:
|
||||
case STATE_PROCESSING_RESPONSE:
|
||||
{
|
||||
PUMP_DEBUG;
|
||||
LLIOPipe::EStatus status = STATUS_BREAK;
|
||||
if (!mRemoved) // Not removed from multi handle yet?
|
||||
{
|
||||
LLFastTimer t(FTM_URL_PERFORM);
|
||||
mDetail->mCurlRequest->perform();
|
||||
// Easy handle is still being processed.
|
||||
return STATUS_BREAK;
|
||||
}
|
||||
// Curl thread finished with this easy handle.
|
||||
mState = STATE_CURL_FINISHED;
|
||||
}
|
||||
case STATE_CURL_FINISHED:
|
||||
{
|
||||
PUMP_DEBUG;
|
||||
LLIOPipe::EStatus status = STATUS_NO_CONNECTION; // Catch-all failure code.
|
||||
|
||||
while(1)
|
||||
// Left braces in order not to change indentation.
|
||||
{
|
||||
CURLcode result;
|
||||
|
||||
bool newmsg = false;
|
||||
{
|
||||
LLFastTimer t(FTM_PROCESS_URL_REQUEST_GET_RESULT);
|
||||
newmsg = mDetail->mCurlRequest->getResult(&result);
|
||||
}
|
||||
|
||||
if(!newmsg)
|
||||
{
|
||||
// keep processing
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
AICurlEasyRequest_wat(*mDetail->mCurlEasyRequest)->getResult(&result);
|
||||
|
||||
mState = STATE_HAVE_RESPONSE;
|
||||
context[CONTEXT_REQUEST][CONTEXT_TRANSFERED_BYTES] = mRequestTransferedBytes;
|
||||
context[CONTEXT_RESPONSE][CONTEXT_TRANSFERED_BYTES] = mResponseTransferedBytes;
|
||||
@@ -378,6 +426,7 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
|
||||
}
|
||||
mCompletionCallback = NULL;
|
||||
}
|
||||
status = STATUS_BREAK; // This is what the old code returned. Does it make sense?
|
||||
break;
|
||||
case CURLE_FAILED_INIT:
|
||||
case CURLE_COULDNT_CONNECT:
|
||||
@@ -419,10 +468,15 @@ void LLURLRequest::initialize()
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
mState = STATE_INITIALIZED;
|
||||
// This might throw AICurlNoEasyHandle.
|
||||
mDetail = new LLURLRequestDetail;
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);
|
||||
mDetail->mCurlRequest->setWriteCallback(&downCallback, (void*)this);
|
||||
mDetail->mCurlRequest->setReadCallback(&upCallback, (void*)this);
|
||||
|
||||
{
|
||||
AICurlEasyRequest_wat curlEasyRequest_w(*mDetail->mCurlEasyRequest);
|
||||
curlEasyRequest_w->setWriteCallback(&downCallback, (void*)this);
|
||||
curlEasyRequest_w->setReadCallback(&upCallback, (void*)this);
|
||||
}
|
||||
|
||||
mRequestTransferedBytes = 0;
|
||||
mResponseTransferedBytes = 0;
|
||||
}
|
||||
@@ -437,70 +491,66 @@ bool LLURLRequest::configure()
|
||||
S32 bytes = mDetail->mResponseBuffer->countAfter(
|
||||
mDetail->mChannels.in(),
|
||||
NULL);
|
||||
switch(mAction)
|
||||
{
|
||||
case HTTP_HEAD:
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_HEADER, 1);
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_NOBODY, 1);
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1);
|
||||
rv = true;
|
||||
break;
|
||||
case HTTP_GET:
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_HTTPGET, 1);
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1);
|
||||
AICurlEasyRequest_wat curlEasyRequest_w(*mDetail->mCurlEasyRequest);
|
||||
switch(mAction)
|
||||
{
|
||||
case HTTP_HEAD:
|
||||
curlEasyRequest_w->setopt(CURLOPT_HEADER, 1);
|
||||
curlEasyRequest_w->setopt(CURLOPT_NOBODY, 1);
|
||||
curlEasyRequest_w->setopt(CURLOPT_FOLLOWLOCATION, 1);
|
||||
rv = true;
|
||||
break;
|
||||
|
||||
// Set Accept-Encoding to allow response compression
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, "");
|
||||
rv = true;
|
||||
break;
|
||||
case HTTP_GET:
|
||||
curlEasyRequest_w->setopt(CURLOPT_HTTPGET, 1);
|
||||
curlEasyRequest_w->setopt(CURLOPT_FOLLOWLOCATION, 1);
|
||||
|
||||
case HTTP_PUT:
|
||||
// Disable the expect http 1.1 extension. POST and PUT default
|
||||
// to turning this on, and I am not too sure what it means.
|
||||
addHeader("Expect:");
|
||||
// Set Accept-Encoding to allow response compression
|
||||
curlEasyRequest_w->setoptString(CURLOPT_ENCODING, "");
|
||||
rv = true;
|
||||
break;
|
||||
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_UPLOAD, 1);
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_INFILESIZE, bytes);
|
||||
rv = true;
|
||||
break;
|
||||
case HTTP_PUT:
|
||||
// Disable the expect http 1.1 extension. POST and PUT default
|
||||
// to turning this on, and I am not too sure what it means.
|
||||
curlEasyRequest_w->addHeader("Expect:");
|
||||
curlEasyRequest_w->setopt(CURLOPT_UPLOAD, 1);
|
||||
curlEasyRequest_w->setopt(CURLOPT_INFILESIZE, bytes);
|
||||
rv = true;
|
||||
break;
|
||||
|
||||
case HTTP_POST:
|
||||
// Disable the expect http 1.1 extension. POST and PUT default
|
||||
// to turning this on, and I am not too sure what it means.
|
||||
addHeader("Expect:");
|
||||
case HTTP_POST:
|
||||
// Set the handle for an http post
|
||||
curlEasyRequest_w->setPost(bytes);
|
||||
|
||||
// Disable the content type http header.
|
||||
// *FIX: what should it be?
|
||||
addHeader("Content-Type:");
|
||||
// Set Accept-Encoding to allow response compression
|
||||
curlEasyRequest_w->setoptString(CURLOPT_ENCODING, "");
|
||||
rv = true;
|
||||
break;
|
||||
|
||||
// Set the handle for an http post
|
||||
mDetail->mCurlRequest->setPost(NULL, bytes);
|
||||
case HTTP_DELETE:
|
||||
// Set the handle for an http post
|
||||
curlEasyRequest_w->setoptString(CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||
rv = true;
|
||||
break;
|
||||
|
||||
// Set Accept-Encoding to allow response compression
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, "");
|
||||
rv = true;
|
||||
break;
|
||||
case HTTP_MOVE:
|
||||
// Set the handle for an http post
|
||||
curlEasyRequest_w->setoptString(CURLOPT_CUSTOMREQUEST, "MOVE");
|
||||
// *NOTE: should we check for the Destination header?
|
||||
rv = true;
|
||||
break;
|
||||
|
||||
case HTTP_DELETE:
|
||||
// Set the handle for an http post
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||
rv = true;
|
||||
break;
|
||||
|
||||
case HTTP_MOVE:
|
||||
// Set the handle for an http post
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_CUSTOMREQUEST, "MOVE");
|
||||
// *NOTE: should we check for the Destination header?
|
||||
rv = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
llwarns << "Unhandled URLRequest action: " << mAction << llendl;
|
||||
break;
|
||||
}
|
||||
if(rv)
|
||||
{
|
||||
mDetail->mCurlRequest->sendRequest(mDetail->mURL);
|
||||
default:
|
||||
llwarns << "Unhandled URLRequest action: " << mAction << llendl;
|
||||
break;
|
||||
}
|
||||
if(rv)
|
||||
{
|
||||
curlEasyRequest_w->finalizeRequest(mDetail->mURL);
|
||||
curlEasyRequest_w->send_events_to(this);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@@ -564,9 +614,8 @@ size_t LLURLRequest::upCallback(
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user)
|
||||
static size_t headerCallback(char* header_line, size_t size, size_t nmemb, void* user)
|
||||
{
|
||||
const char* header_line = (const char*)data;
|
||||
size_t header_len = size * nmemb;
|
||||
LLURLRequestComplete* complete = (LLURLRequestComplete*)user;
|
||||
|
||||
@@ -632,42 +681,6 @@ static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user)
|
||||
return header_len;
|
||||
}
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_PROCESS_URL_EXTRACTOR("URL Extractor");
|
||||
/**
|
||||
* LLContextURLExtractor
|
||||
*/
|
||||
// virtual
|
||||
LLIOPipe::EStatus LLContextURLExtractor::process_impl(
|
||||
const LLChannelDescriptors& channels,
|
||||
buffer_ptr_t& buffer,
|
||||
bool& eos,
|
||||
LLSD& context,
|
||||
LLPumpIO* pump)
|
||||
{
|
||||
LLFastTimer t(FTM_PROCESS_URL_EXTRACTOR);
|
||||
PUMP_DEBUG;
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
// The destination host is in the context.
|
||||
if(context.isUndefined() || !mRequest)
|
||||
{
|
||||
return STATUS_PRECONDITION_NOT_MET;
|
||||
}
|
||||
|
||||
// copy in to out, since this just extract the URL and does not
|
||||
// actually change the data.
|
||||
LLChangeChannel change(channels.in(), channels.out());
|
||||
std::for_each(buffer->beginSegment(), buffer->endSegment(), change);
|
||||
|
||||
// find the context url
|
||||
if(context.has(CONTEXT_DEST_URI_SD_LABEL))
|
||||
{
|
||||
mRequest->setURL(context[CONTEXT_DEST_URI_SD_LABEL].asString());
|
||||
return STATUS_DONE;
|
||||
}
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* LLURLRequestComplete
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user