FIRE-20026: Increase timeout for Flickr upload to 5 minutes

master
Ansariel 2016-09-23 09:38:15 +02:00
parent 79aca1f0ed
commit 620db1dd1e
4 changed files with 43 additions and 38 deletions

View File

@ -29,17 +29,20 @@
namespace FSCoreHttpUtil
{
void trivialPostCoroRaw(std::string url, LLCore::HttpRequest::policy_t policyId, LLCore::BufferArray::ptr_t postData, LLCore::HttpHeaders::ptr_t aHeader, completionCallback_t success, completionCallback_t failure)
void trivialPostCoroRaw(std::string url, LLCore::HttpRequest::policy_t policyId, LLCore::BufferArray::ptr_t postData, LLCore::HttpHeaders::ptr_t aHeader, LLCore::HttpOptions::ptr_t options, completionCallback_t success, completionCallback_t failure)
{
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoroRaw", policyId));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
httpOpts->setWantHeaders(true);
if (!options)
{
options.reset(new LLCore::HttpOptions);
options->setWantHeaders(true);
}
LL_INFOS("HttpCoroutineAdapter", "genericPostCoroRaw") << "Generic POST for " << url << LL_ENDL;
LLSD result = httpAdapter->postRawAndSuspend(httpRequest, url, postData, httpOpts, aHeader );
LLSD result = httpAdapter->postRawAndSuspend(httpRequest, url, postData, options, aHeader );
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
@ -62,34 +65,37 @@ namespace FSCoreHttpUtil
}
}
void callbackHttpPostRaw(const std::string &url, std::string postData, completionCallback_t success, completionCallback_t failure, LLCore::HttpHeaders::ptr_t aHeader )
void callbackHttpPostRaw(const std::string &url, std::string postData, completionCallback_t success, completionCallback_t failure, LLCore::HttpHeaders::ptr_t aHeader, LLCore::HttpOptions::ptr_t options)
{
LLCore::BufferArray::ptr_t postDataBuffer( new LLCore::BufferArray() );
postDataBuffer->append( postData.c_str(), postData.size() );
LLCoros::instance().launch("HttpCoroutineAdapter::genericPostCoroRaw",
boost::bind(trivialPostCoroRaw, url, LLCore::HttpRequest::DEFAULT_POLICY_ID, postDataBuffer, aHeader, success, failure));
boost::bind(trivialPostCoroRaw, url, LLCore::HttpRequest::DEFAULT_POLICY_ID, postDataBuffer, aHeader, options, success, failure));
}
void trivialGetCoroRaw(std::string url, LLCore::HttpRequest::policy_t policyId, LLCore::HttpHeaders::ptr_t aHeader, completionCallback_t success, completionCallback_t failure)
void trivialGetCoroRaw(std::string url, LLCore::HttpRequest::policy_t policyId, LLCore::HttpHeaders::ptr_t aHeader, LLCore::HttpOptions::ptr_t options, completionCallback_t success, completionCallback_t failure)
{
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericGetCoro", policyId));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
httpOpts->setWantHeaders(true);
if (!options)
{
options.reset(new LLCore::HttpOptions);
options->setWantHeaders(true);
}
LL_INFOS("HttpCoroutineAdapter", "genericGetCoroRaw") << "Generic GET for " << url << LL_ENDL;
LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, httpOpts, aHeader );
LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, options, aHeader);
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (!status)
{
{
if (failure)
{
failure(httpResults);
@ -104,10 +110,10 @@ namespace FSCoreHttpUtil
}
}
void callbackHttpGetRaw(const std::string &url, completionCallback_t success, completionCallback_t failure, LLCore::HttpHeaders::ptr_t aHeader )
void callbackHttpGetRaw(const std::string &url, completionCallback_t success, completionCallback_t failure, LLCore::HttpHeaders::ptr_t aHeader, LLCore::HttpOptions::ptr_t options)
{
LLCoros::instance().launch("HttpCoroutineAdapter::genericGetCoroRaw",
boost::bind(trivialGetCoroRaw, url, LLCore::HttpRequest::DEFAULT_POLICY_ID, aHeader, success, failure));
boost::bind(trivialGetCoroRaw, url, LLCore::HttpRequest::DEFAULT_POLICY_ID, aHeader, options, success, failure));
}
LLCore::HttpHeaders::ptr_t createModifiedSinceHeader( time_t aTime )

View File

@ -32,15 +32,15 @@
namespace FSCoreHttpUtil
{
typedef boost::function<void(const LLSD &)> completionCallback_t;
typedef boost::function<void(const LLSD &)> completionCallback_t;
void callbackHttpPostRaw(const std::string &url, std::string postData, completionCallback_t success = NULL, completionCallback_t failure = NULL,
LLCore::HttpHeaders::ptr_t aHeader = LLCore::HttpHeaders::ptr_t() );
void callbackHttpGetRaw(const std::string &url, completionCallback_t success = NULL, completionCallback_t failure = NULL,
LLCore::HttpHeaders::ptr_t aHeader = LLCore::HttpHeaders::ptr_t() );
LLCore::HttpHeaders::ptr_t aHeader = LLCore::HttpHeaders::ptr_t(), LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t());
void callbackHttpGetRaw(const std::string &url, completionCallback_t success = NULL, completionCallback_t failure = NULL,
LLCore::HttpHeaders::ptr_t aHeader = LLCore::HttpHeaders::ptr_t(), LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t());
void trivialGetCoroRaw(std::string url, LLCore::HttpRequest::policy_t policyId, LLCore::HttpHeaders::ptr_t aHeader, completionCallback_t success, completionCallback_t failure);
void trivialPostCoroRaw(std::string url, LLCore::HttpRequest::policy_t policyId, LLCore::BufferArray::ptr_t postData, LLCore::HttpHeaders::ptr_t aHeader,
void trivialGetCoroRaw(std::string url, LLCore::HttpRequest::policy_t policyId, LLCore::HttpHeaders::ptr_t aHeader, LLCore::HttpOptions::ptr_t options, completionCallback_t success, completionCallback_t failure);
void trivialPostCoroRaw(std::string url, LLCore::HttpRequest::policy_t policyId, LLCore::BufferArray::ptr_t postData, LLCore::HttpHeaders::ptr_t aHeader, LLCore::HttpOptions::ptr_t options,
completionCallback_t success, completionCallback_t failure);
}

View File

@ -41,22 +41,24 @@
#include "exoflickr.h"
const std::string UPLOAD_URL = "https://up.flickr.com/services/upload/";
const std::string API_URL = "https://api.flickr.com/services/rest/";
void exoFlickrUploadResponse( LLSD const &aData, exoFlickr::response_callback_t aCallback )
{
LLSD header = aData[ LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS ][ LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD( aData[ LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS ] );
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD( aData[ LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS ] );
LL_INFOS() << "Status " << status.getType() << " aData " << ll_pretty_print_sd( aData ) << LL_ENDL;
LL_INFOS("FlickrAPI") << "Status " << status.getType() << " aData " << ll_pretty_print_sd( aData ) << LL_ENDL;
if( !aData.has( LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW ) )
{
LL_WARNS() << "No content data included in response" << LL_ENDL;
LL_WARNS("FlickrAPI") << "No content data included in response" << LL_ENDL;
aCallback(false, LLSD());
return;
}
const LLSD::Binary &rawData = aData[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
const LLSD::Binary &rawData = aData[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
std::string result;
result.assign( rawData.begin(), rawData.end() );
@ -189,9 +191,9 @@ void exoFlickr::request(const std::string& method, const LLSD& args, response_ca
params["format"] = "json";
params["method"] = method;
params["nojsoncallback"] = 1;
signRequest(params, "GET", "https://api.flickr.com/services/rest/");
signRequest(params, "GET", API_URL);
std::string url = LLURI::buildHTTP( "https://api.flickr.com/services/rest/", LLSD::emptyArray(), params ).asString();
std::string url = LLURI::buildHTTP( API_URL, LLSD::emptyArray(), params ).asString();
FSCoreHttpUtil::callbackHttpGetRaw( url, boost::bind( exoFlickrResponse, _1, callback ) );
}
@ -215,7 +217,7 @@ void exoFlickr::signRequest(LLSD& params, std::string method, std::string url)
void exoFlickr::uploadPhoto(const LLSD& args, LLImageFormatted *image, response_callback_t callback)
{
LLSD params(args);
signRequest(params, "POST", "https://up.flickr.com/services/upload/");
signRequest(params, "POST", UPLOAD_URL);
// It would be nice if there was an easy way to do multipart form data. Oh well.
const std::string boundary = "------------abcdefgh012345";
@ -256,17 +258,13 @@ void exoFlickr::uploadPhoto(const LLSD& args, LLImageFormatted *image, response_
post_data.append( post_tail.c_str(), post_tail.size() );
// We have a post body! Now we can go about building the actual request...
// <FS:TS> Patch from Exodus:
// The default timeout (one minute) isn't enough for a large picture.
// 10 minutes is arbitrary, but should be long enough.
LLCore::HttpHeaders::ptr_t pHeader( new LLCore::HttpHeaders() );
LLCore::HttpOptions::ptr_t options(new LLCore::HttpOptions());
pHeader->append( "Content-Type", "multipart/form-data; boundary=" + boundary );
FSCoreHttpUtil::callbackHttpPostRaw( "https://up.flickr.com/services/upload/", post_data, boost::bind( exoFlickrUploadResponse, _1, callback ), boost::bind( exoFlickrUploadResponse, _1, callback ), pHeader );
// </FS:TS>
// The HTTP client takes ownership of our post_data array,
// and will delete it when it's done.
options->setWantHeaders(true);
options->setRetries(0);
options->setTimeout(300);
FSCoreHttpUtil::callbackHttpPostRaw(UPLOAD_URL, post_data, boost::bind( exoFlickrUploadResponse, _1, callback ), boost::bind( exoFlickrUploadResponse, _1, callback ), pHeader, options );
}
//static
@ -300,5 +298,3 @@ std::string exoFlickr::getSignatureForCall(const LLSD& parameters, std::string u
std::string signature = LLBase64::encode((U8*)data, length);
return signature;
}

View File

@ -190,7 +190,10 @@ void LLFlickrConnect::flickrShareImageCoro(LLPointer<LLImageFormatted> image, st
httpOpts->setWantHeaders(true);
httpOpts->setFollowRedirects(false);
httpOpts->setRetries(0); // <FS:Ansariel> FIRE-20026: Pictures might get uploaded multiple times after a timeout occurs
// <FS:Ansariel> FIRE-20026: Pictures might get uploaded multiple times after a timeout occurs
httpOpts->setRetries(0);
httpOpts->setTimeout(300);
// </FS:Ansariel>
std::string imageFormat;
if (dynamic_cast<LLImagePNG*>(image.get()))