summaryrefslogtreecommitdiff
path: root/indra/llmessage/llhttpassetstorage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmessage/llhttpassetstorage.cpp')
-rw-r--r--indra/llmessage/llhttpassetstorage.cpp119
1 files changed, 59 insertions, 60 deletions
diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp
index 2179064807..9ea2ff4153 100644
--- a/indra/llmessage/llhttpassetstorage.cpp
+++ b/indra/llmessage/llhttpassetstorage.cpp
@@ -3,30 +3,25 @@
* @brief Subclass capable of loading asset data to/from an external
* source. Currently, a web server accessed via curl
*
- * $LicenseInfo:firstyear=2003&license=viewergpl$
- *
- * Copyright (c) 2003-2007, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2003&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -81,8 +76,8 @@ class LLHTTPAssetRequest : public LLAssetRequest
{
public:
LLHTTPAssetRequest(LLHTTPAssetStorage *asp, const LLUUID &uuid,
- LLAssetType::EType type, LLAssetStorage::ERequestType rt,
- const char *url, CURLM *curl_multi);
+ LLAssetType::EType type, LLAssetStorage::ERequestType rt,
+ const std::string& url, CURLM *curl_multi);
virtual ~LLHTTPAssetRequest();
void setupCurlHandle();
@@ -103,7 +98,7 @@ public:
CURL *mCurlHandle;
CURLM *mCurlMultiHandle;
- char *mURLBuffer;
+ std::string mURLBuffer;
struct curl_slist *mHTTPHeaders;
LLVFile *mVFile;
LLUUID mTmpUUID;
@@ -122,11 +117,12 @@ LLHTTPAssetRequest::LLHTTPAssetRequest(LLHTTPAssetStorage *asp,
const LLUUID &uuid,
LLAssetType::EType type,
LLAssetStorage::ERequestType rt,
- const char *url,
+ const std::string& url,
CURLM *curl_multi)
: LLAssetRequest(uuid, type),
- mZInitialized(false)
+ mZInitialized(false)
{
+ memset(&mZStream, 0, sizeof(mZStream)); // we'll initialize this later, but for now zero the whole C-style struct to avoid debug/coverity noise
mAssetStoragep = asp;
mCurlHandle = NULL;
mCurlMultiHandle = curl_multi;
@@ -137,11 +133,7 @@ LLHTTPAssetRequest::LLHTTPAssetRequest(LLHTTPAssetStorage *asp,
mZInputBuffer = NULL;
mZInputExhausted = false;
- mURLBuffer = new char[strlen(url) + 1]; /*Flawfinder: ignore*/
- if (mURLBuffer)
- {
- strcpy(mURLBuffer, url); /*Flawfinder: ignore*/
- }
+ mURLBuffer = url;
}
LLHTTPAssetRequest::~LLHTTPAssetRequest()
@@ -156,7 +148,6 @@ LLHTTPAssetRequest::~LLHTTPAssetRequest()
{
curl_slist_free_all(mHTTPHeaders);
}
- delete[] mURLBuffer;
delete mVFile;
finishCompressedUpload();
}
@@ -239,10 +230,11 @@ LLSD LLHTTPAssetRequest::getFullDetails() const
void LLHTTPAssetRequest::setupCurlHandle()
{
+ // *NOTE: Similar code exists in mapserver/llcurlutil.cpp JC
mCurlHandle = curl_easy_init();
curl_easy_setopt(mCurlHandle, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(mCurlHandle, CURLOPT_NOPROGRESS, 1);
- curl_easy_setopt(mCurlHandle, CURLOPT_URL, mURLBuffer);
+ curl_easy_setopt(mCurlHandle, CURLOPT_URL, mURLBuffer.c_str());
curl_easy_setopt(mCurlHandle, CURLOPT_PRIVATE, this);
if (LLAssetStorage::RT_DOWNLOAD == mRequestType)
{
@@ -261,6 +253,10 @@ void LLHTTPAssetRequest::setupCurlHandle()
// disable use of proxy, which can't handle chunked transfers
}
mHTTPHeaders = curl_slist_append(mHTTPHeaders, "Pragma:");
+
+ // bug in curl causes DNS to be cached for too long a time, 0 sets it to never cache DNS results internally (to curl)
+ curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0);
+
// resist the temptation to explicitly add the Transfer-Encoding: chunked
// header here - invokes a libCURL bug
curl_easy_setopt(mCurlHandle, CURLOPT_HTTPHEADER, mHTTPHeaders);
@@ -334,6 +330,8 @@ void LLHTTPAssetRequest::finishCompressedUpload()
size_t LLHTTPAssetRequest::readCompressedData(void* data, size_t size)
{
+ llassert(mZInitialized);
+
mZStream.next_out = (Bytef*)data;
mZStream.avail_out = size;
@@ -397,26 +395,28 @@ size_t LLHTTPAssetRequest::curlCompressedUploadCallback(
LLHTTPAssetStorage::LLHTTPAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
- LLVFS *vfs, const LLHost &upstream_host,
- const char *web_host,
- const char *local_web_host,
- const char *host_name)
- : LLAssetStorage(msg, xfer, vfs, upstream_host)
+ LLVFS *vfs, LLVFS *static_vfs,
+ const LLHost &upstream_host,
+ const std::string& web_host,
+ const std::string& local_web_host,
+ const std::string& host_name)
+ : LLAssetStorage(msg, xfer, vfs, static_vfs, upstream_host)
{
_init(web_host, local_web_host, host_name);
}
LLHTTPAssetStorage::LLHTTPAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
LLVFS *vfs,
- const char *web_host,
- const char *local_web_host,
- const char *host_name)
- : LLAssetStorage(msg, xfer, vfs)
+ LLVFS *static_vfs,
+ const std::string& web_host,
+ const std::string& local_web_host,
+ const std::string& host_name)
+ : LLAssetStorage(msg, xfer, vfs, static_vfs)
{
_init(web_host, local_web_host, host_name);
}
-void LLHTTPAssetStorage::_init(const char *web_host, const char *local_web_host, const char* host_name)
+void LLHTTPAssetStorage::_init(const std::string& web_host, const std::string& local_web_host, const std::string& host_name)
{
mBaseURL = web_host;
mLocalBaseURL = local_web_host;
@@ -468,7 +468,7 @@ void LLHTTPAssetStorage::storeAssetData(
{
message = "Added to upload queue";
}
- reportMetric( uuid, type, NULL, requesting_agent_id, size, MR_OKAY, __FILE__, __LINE__, message );
+ reportMetric( uuid, type, LLStringUtil::null, requesting_agent_id, size, MR_OKAY, __FILE__, __LINE__, message );
// this will get picked up and transmitted in checkForTimeouts
if(store_local)
@@ -490,7 +490,7 @@ void LLHTTPAssetStorage::storeAssetData(
if (callback)
{
// LLAssetStorage metric: Zero size VFS
- reportMetric( uuid, type, NULL, requesting_agent_id, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" );
+ reportMetric( uuid, type, LLStringUtil::null, requesting_agent_id, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" );
callback(uuid, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_NONEXISTENT_FILE);
}
}
@@ -498,7 +498,7 @@ void LLHTTPAssetStorage::storeAssetData(
// virtual
void LLHTTPAssetStorage::storeAssetData(
- const char* filename,
+ const std::string& filename,
const LLUUID& asset_id,
LLAssetType::EType asset_type,
LLStoreAssetCallback callback,
@@ -595,7 +595,7 @@ LLSD LLHTTPAssetStorage::getPendingDetails(LLAssetStorage::ERequestType rt,
LLSD& pending = sd["requests"][i];
// See if this pending request is running.
const LLAssetRequest* req = findRequest(running,
- LLAssetType::lookup(pending["type"].asString().c_str()),
+ LLAssetType::lookup(pending["type"].asString()),
pending["asset_id"]);
if (req)
{
@@ -623,7 +623,7 @@ LLSD LLHTTPAssetStorage::getPendingRequest(LLAssetStorage::ERequestType rt,
const request_list_t* running = getRunningList(rt);
if (running)
{
- LLSD sd = LLAssetStorage::getPendingRequest(running, asset_type, asset_id);
+ LLSD sd = LLAssetStorage::getPendingRequestImpl(running, asset_type, asset_id);
if (sd)
{
sd["is_running"] = true;
@@ -766,11 +766,11 @@ void LLHTTPAssetStorage::checkForTimeouts()
// Setup this curl download request
// We need to generate a new request here
// since the one in the list could go away
- char tmp_url[MAX_STRING]; /*Flawfinder: ignore*/
- char uuid_str[UUID_STR_LENGTH]; /*Flawfinder: ignore*/
+ std::string tmp_url;
+ std::string uuid_str;
req->getUUID().toString(uuid_str);
std::string base_url = getBaseURL(req->getUUID(), req->getType());
- snprintf(tmp_url, sizeof(tmp_url), "%s/%36s.%s", base_url.c_str() , uuid_str, LLAssetType::lookup(req->getType())); /* Flawfinder: ignore */
+ tmp_url = llformat("%s/%36s.%s", base_url.c_str() , uuid_str.c_str(), LLAssetType::lookup(req->getType()));
LLHTTPAssetRequest *new_req = new LLHTTPAssetRequest(this, req->getUUID(),
req->getType(), RT_DOWNLOAD, tmp_url, mCurlMultiHandle);
@@ -803,12 +803,11 @@ void LLHTTPAssetStorage::checkForTimeouts()
bool do_compress = req->getType() == LLAssetType::AT_OBJECT;
- char tmp_url[MAX_STRING];/*Flawfinder: ignore*/
- char uuid_str[UUID_STR_LENGTH];/*Flawfinder: ignore*/
+ std::string tmp_url;
+ std::string uuid_str;
req->getUUID().toString(uuid_str);
- snprintf(tmp_url, sizeof(tmp_url), /* Flawfinder: ignore */
- do_compress ? "%s/%s.%s.gz" : "%s/%s.%s",
- mBaseURL.c_str(), uuid_str, LLAssetType::lookup(req->getType()));
+ tmp_url = mBaseURL + "/" + uuid_str + "." + LLAssetType::lookup(req->getType());
+ if (do_compress) tmp_url += ".gz";
LLHTTPAssetRequest *new_req = new LLHTTPAssetRequest(this, req->getUUID(),
req->getType(), RT_UPLOAD, tmp_url, mCurlMultiHandle);
@@ -874,12 +873,12 @@ void LLHTTPAssetStorage::checkForTimeouts()
// setup this curl upload request
LLVFile file(mVFS, req->getUUID(), req->getType());
- char tmp_url[MAX_STRING]; /*Flawfinder: ignore*/
- char uuid_str[UUID_STR_LENGTH]; /*Flawfinder: ignore*/
+ std::string tmp_url;
+ std::string uuid_str;
req->getUUID().toString(uuid_str);
// KLW - All temporary uploads are saved locally "http://localhost:12041/asset"
- snprintf(tmp_url, sizeof(tmp_url), "%s/%36s.%s", mLocalBaseURL.c_str(), uuid_str, LLAssetType::lookup(req->getType())); /* Flawfinder: ignore */
+ tmp_url = llformat("%s/%36s.%s", mLocalBaseURL.c_str(), uuid_str.c_str(), LLAssetType::lookup(req->getType()));
LLHTTPAssetRequest *new_req = new LLHTTPAssetRequest(this, req->getUUID(),
req->getType(), RT_LOCALUPLOAD, tmp_url, mCurlMultiHandle);
@@ -1158,7 +1157,7 @@ size_t LLHTTPAssetStorage::nullOutputCallback(void *data, size_t size, size_t nm
// blocking asset fetch which bypasses the VFS
// this is a very limited function for use by the simstate loader and other one-offs
-S32 LLHTTPAssetStorage::getURLToFile(const LLUUID& uuid, LLAssetType::EType asset_type, const LLString &url, const char *filename, progress_callback callback, void *userdata)
+S32 LLHTTPAssetStorage::getURLToFile(const LLUUID& uuid, LLAssetType::EType asset_type, const std::string &url, const std::string& filename, progress_callback callback, void *userdata)
{
// *NOTE: There is no guarantee that the uuid and the asset_type match
// - not that it matters. - Doug
@@ -1172,7 +1171,7 @@ S32 LLHTTPAssetStorage::getURLToFile(const LLUUID& uuid, LLAssetType::EType asse
}
// make sure we use the normal curl setup, even though we don't really need a request object
- LLHTTPAssetRequest req(this, uuid, asset_type, RT_DOWNLOAD, url.c_str(), mCurlMultiHandle);
+ LLHTTPAssetRequest req(this, uuid, asset_type, RT_DOWNLOAD, url, mCurlMultiHandle);
req.mFP = fp;
req.setupCurlHandle();