diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
index 9ccebabab42f3916c2ceb9f41f0973bc0e8c150e..68c55eaf5491f0fc93f25ef5656c4bf9c6448d8e 100644
--- a/indra/llmessage/llcorehttputil.cpp
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -36,6 +36,7 @@
 #include "llsdjson.h"
 #include "llsdserialize.h"
 #include "reader.h" 
+#include "llvfile.h"
 
 #include "message.h" // for getting the port
 
@@ -621,6 +622,61 @@ LLSD HttpCoroutineAdapter::postRawAndYield(LLCoros::self & self, LLCore::HttpReq
     return postAndYield_(self, request, url, rawbody, options, headers, httpHandler);
 }
 
+// *TODO: This functionality could be moved into the LLCore::Http library itself 
+// by having the CURL layer read the file directly.
+LLSD HttpCoroutineAdapter::postFileAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t request,
+    const std::string & url, std::string fileName,
+    LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
+{
+    LLCore::BufferArray::ptr_t fileData(new LLCore::BufferArray, false);
+
+    // scoping for our streams so that they go away when we no longer need them.
+    {
+        LLCore::BufferArrayStream outs(fileData.get());
+        llifstream ins(fileName.c_str(), std::iostream::binary | std::iostream::out);
+
+        if (ins.is_open())
+        {
+
+            ins.seekg(0, std::ios::beg);
+            ins >> std::noskipws;
+
+            std::copy(std::istream_iterator<U8>(ins), std::istream_iterator<U8>(),
+                    std::ostream_iterator<U8>(outs));
+
+            ins.close();
+        }
+    }
+
+    return postAndYield(self, request, url, fileData, options, headers);
+}
+
+// *TODO: This functionality could be moved into the LLCore::Http library itself 
+// by having the CURL layer read the file directly.
+LLSD HttpCoroutineAdapter::postFileAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t request,
+    const std::string & url, LLUUID assetId, LLAssetType::EType assetType,
+    LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
+{
+    LLCore::BufferArray::ptr_t fileData(new LLCore::BufferArray, false);
+
+    // scoping for our streams so that they go away when we no longer need them.
+    {
+        LLCore::BufferArrayStream outs(fileData.get());
+        LLVFile vfile(gVFS, assetId, assetType, LLVFile::READ);
+
+        S32 fileSize = vfile.getSize();
+        U8* fileBuffer;
+        fileBuffer = new U8[fileSize];
+        vfile.read(fileBuffer, fileSize);
+        
+        outs.write((char*)fileBuffer, fileSize);
+        delete[] fileBuffer;
+    }
+
+    return postAndYield(self, request, url, fileData, options, headers);
+}
+
+
 LLSD HttpCoroutineAdapter::postAndYield_(LLCoros::self & self, LLCore::HttpRequest::ptr_t &request,
     const std::string & url, LLCore::BufferArray::ptr_t &rawbody,
     LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers,
diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h
index e98399c985ba7e0f92ed0b4795e730c275b7178a..71f95dd6e441e1b498f8ddd6e0fe57f969131f09 100644
--- a/indra/llmessage/llcorehttputil.h
+++ b/indra/llmessage/llcorehttputil.h
@@ -43,6 +43,8 @@
 #include "llevents.h"
 #include "llcoros.h"
 #include "lleventcoro.h"
+#include "llassettype.h"
+#include "lluuid.h"
 
 ///
 /// The base llcorehttp library implements many HTTP idioms
@@ -355,6 +357,34 @@ class HttpCoroutineAdapter
             LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false), headers);
     }
 
+    LLSD postFileAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t request,
+        const std::string & url, std::string fileName,
+        LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false),
+        LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false));
+
+    LLSD postFileAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t &request,
+        const std::string & url, std::string fileName,
+        LLCore::HttpHeaders::ptr_t &headers)
+    {
+        return postFileAndYield(self, request, url, fileName,
+            LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false), headers);
+    }
+
+
+    LLSD HttpCoroutineAdapter::postFileAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t request,
+        const std::string & url, LLUUID assetId, LLAssetType::EType assetType,
+        LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false),
+        LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false));
+
+    LLSD HttpCoroutineAdapter::postFileAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t request,
+        const std::string & url, LLUUID assetId, LLAssetType::EType assetType,
+        LLCore::HttpHeaders::ptr_t &headers)
+    {
+        return postFileAndYield(self, request, url, assetId, assetType,
+            LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false), headers);
+    }
+
+
     /// Execute a Put transaction on the supplied URL and yield execution of 
     /// the coroutine until a result is available.
     ///