diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 8ba965e7ed91134101c3a3b39641b98775fb07a8..f153c949115debbd53ffdce8430eb399e12d0ac9 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -1074,7 +1074,9 @@ void LLCurlRequest::get(const std::string& url, LLCurl::ResponderPtr responder)
 {
 	getByteRange(url, headers_t(), 0, -1, responder);
 }
-	
+
+// Note: (length==0) is interpreted as "the rest of the file", i.e. the whole file if (offset==0) or
+// the remainder of the file if not.
 bool LLCurlRequest::getByteRange(const std::string& url,
 								 const headers_t& headers,
 								 S32 offset, S32 length,
@@ -1092,6 +1094,11 @@ bool LLCurlRequest::getByteRange(const std::string& url,
 		std::string range = llformat("Range: bytes=%d-%d", offset,offset+length-1);
 		easy->slist_append(range.c_str());
 	}
+	else if (offset > 0)
+	{
+		std::string range = llformat("Range: bytes=%d-", offset);
+		easy->slist_append(range.c_str());
+	}
 	easy->setHeaders();
 	bool res = addEasy(easy);
 	return res;
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index a4c8993ae6b938603902d2de21000d50bc87192c..eac6abc1caee0ab779835d2a5e8925c619081c5c 100755
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -1222,6 +1222,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				// Will call callbackHttpGet when curl request completes
 				std::vector<std::string> headers;
 				headers.push_back("Accept: image/x-j2c");
+				// If we try to fetch the whole file, we set the size to 0 so that we generate the correct curl range request
+				// Note: it looks a bit hacky but we need to limit this (size==0) to mean "whole file" to HTTP only as it messes up UDP fetching
+				if ((offset+mRequestedSize) == MAX_IMAGE_DATA_SIZE)
+				{
+					mRequestedSize = 0;
+				}
 				res = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize,
 															  new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset, true));
 			}
@@ -1708,7 +1714,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
 			mBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size);
 			buffer->readAfter(channels.in(), NULL, mBuffer, data_size);
 			mBufferSize += data_size;
-			if (data_size < mRequestedSize && mRequestedDiscard == 0)
+			if (mRequestedSize == 0)
 			{
 				mHaveAllData = TRUE;
 			}
@@ -1949,6 +1955,8 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
 	}
 	else
 	{
+		// If the requester knows nothing about the file, we fetch the smallest
+		// amount of data at the lowest resolution (highest discard level) possible.
 		desired_size = TEXTURE_CACHE_ENTRY_SIZE;
 		desired_discard = MAX_DISCARD_LEVEL;
 	}
@@ -3746,7 +3754,7 @@ void LLTextureFetchDebugger::scanRefetchList()
 		if(iter->second.empty())
 		{
 			gTextureList.setDebugFetching(iter->first, -1);
-			iter = mRefetchList.erase(iter);
+			mRefetchList.erase(iter++);		// This is the correct method to "erase and move on" in an std::map
 		}
 		else
 		{