diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index bd40d8e69..ac2438c4b 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -243,7 +243,9 @@ bool LLHTTPClient::getByteRange(std::string const& url, AIHTTPHeaders& headers, { if (offset > 0 || bytes > 0) { - headers.addHeader("Range", llformat("bytes=%d-%d", offset, offset + bytes - 1)); + int const range_end = offset + bytes - 1; + char const* const range_format = (range_end >= HTTP_REQUESTS_RANGE_END_MAX) ? "bytes=%d-" : "bytes=%d-%d"; + headers.addHeader("Range", llformat(range_format, offset, range_end)); } request(url, HTTP_GET, NULL, responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug)); } diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h index 3bb60b04f..dbbf729ac 100644 --- a/indra/llmessage/llhttpclient.h +++ b/indra/llmessage/llhttpclient.h @@ -55,6 +55,17 @@ typedef struct _xmlrpc_request* XMLRPC_REQUEST; typedef struct _xmlrpc_value* XMLRPC_VALUE; extern AIEngine gMainThreadEngine; +// In Viewer 3 this definition is in indra/newview/lltexturefetch.cpp, +// but we need it in two .cpp files, so it's moved here. +// +// BUG-3323/SH-4375 +// *NOTE: This is a heuristic value. Texture fetches have a habit of using a +// value of 32MB to indicate 'get the rest of the image'. Certain ISPs and +// network equipment get confused when they see this in a Range: header. So, +// if the request end is beyond this value, we issue an open-ended Range: +// request (e.g. 'Range: -') which seems to fix the problem. +static const S32 HTTP_REQUESTS_RANGE_END_MAX = 20000000; + // Output parameter of AICurlPrivate::CurlEasyRequest::getResult. // Used in XMLRPCResponder. struct AITransferInfo { diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 2079180fd..7df177ad0 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1416,7 +1416,9 @@ bool LLTextureFetchWorker::doWork(S32 param) // Call LLHTTPClient::request directly instead of LLHTTPClient::getByteRange, because we want to pass a NULL AIEngine. if (mRequestedOffset > 0 || mRequestedSize > 0) { - headers.addHeader("Range", llformat("bytes=%d-%d", mRequestedOffset, mRequestedOffset + mRequestedSize - 1)); + int const range_end = mRequestedOffset + mRequestedSize - 1; + char const* const range_format = (range_end >= HTTP_REQUESTS_RANGE_END_MAX) ? "bytes=%d-" : "bytes=%d-%d"; + headers.addHeader("Range", llformat(range_format, mRequestedOffset, range_end)); } LLHTTPClient::request(mUrl, LLHTTPClient::HTTP_GET, NULL, new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, mRequestedOffset),