зеркало из https://github.com/mozilla/pjs.git
Fixing bug 491201. Adding ability for XMLHttpRequest.send() to accept a File object. r+sr=jonas@sicking.cc, r=cbiesinger@gmail.com
This commit is contained in:
Родитель
2122c22619
Коммит
9648a313b0
|
@ -93,6 +93,7 @@ XPIDLSRCS = \
|
|||
nsIContentPolicy.idl \
|
||||
nsIDocumentEncoder.idl \
|
||||
nsIDOMFile.idl \
|
||||
nsIDOMFileInternal.idl \
|
||||
nsIDOMFileList.idl \
|
||||
nsIDOMFileException.idl \
|
||||
nsIDOMParser.idl \
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include "nsICharsetDetectionObserver.h"
|
||||
#include "nsIDOMFile.h"
|
||||
#include "nsIDOMFileInternal.h"
|
||||
#include "nsIDOMFileList.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsCOMArray.h"
|
||||
|
@ -52,11 +53,13 @@ class nsIFile;
|
|||
class nsIInputStream;
|
||||
|
||||
class nsDOMFile : public nsIDOMFile,
|
||||
public nsIDOMFileInternal,
|
||||
public nsICharsetDetectionObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMFILE
|
||||
NS_DECL_NSIDOMFILEINTERNAL
|
||||
|
||||
nsDOMFile(nsIFile *aFile)
|
||||
: mFile(aFile)
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "domstubs.idl"
|
||||
|
||||
interface nsIFile;
|
||||
|
||||
[scriptable, uuid(047CA6C4-52B3-46F1-8976-E198B724F72F)]
|
||||
interface nsIDOMFileInternal : nsISupports
|
||||
{
|
||||
attribute nsIFile internalFile;
|
||||
};
|
|
@ -68,6 +68,7 @@
|
|||
NS_INTERFACE_MAP_BEGIN(nsDOMFile)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFile)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMFile)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMFileInternal)
|
||||
NS_INTERFACE_MAP_ENTRY(nsICharsetDetectionObserver)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(File)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
@ -146,6 +147,20 @@ nsDOMFile::GetAsText(const nsAString &aCharset, nsAString &aResult)
|
|||
return ConvertStream(stream, charset.get(), aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFile::GetInternalFile(nsIFile **aFile)
|
||||
{
|
||||
NS_IF_ADDREF(*aFile = mFile);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFile::SetInternalFile(nsIFile *aFile)
|
||||
{
|
||||
mFile = aFile;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFile::GetAsDataURL(nsAString &aResult)
|
||||
{
|
||||
|
|
|
@ -45,8 +45,10 @@
|
|||
#include "nsIURI.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIUploadChannel.h"
|
||||
#include "nsIUploadChannel2.h"
|
||||
#include "nsIDOMSerializer.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
@ -62,7 +64,10 @@
|
|||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIDOMClassInfo.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMFileInternal.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsCExternalHandlerService.h"
|
||||
#include "nsIVariant.h"
|
||||
#include "nsVariant.h"
|
||||
#include "nsIParser.h"
|
||||
|
@ -2358,6 +2363,37 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
|
|||
postDataStream = stream;
|
||||
charset.Truncate();
|
||||
}
|
||||
else {
|
||||
// nsIDOMFile?
|
||||
nsCOMPtr<nsIDOMFileInternal> file(do_QueryInterface(supports));
|
||||
|
||||
if (file) {
|
||||
nsCOMPtr<nsIFile> internalFile;
|
||||
rv = file->GetInternalFile(getter_AddRefs(internalFile));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), internalFile);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Feed local file input stream into our upload channel
|
||||
if (stream) {
|
||||
postDataStream = stream;
|
||||
charset.Truncate();
|
||||
defaultContentType.Truncate();
|
||||
|
||||
nsCOMPtr<nsIMIMEService> mimeService =
|
||||
do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString mediaType;
|
||||
rv = mimeService->GetTypeFromFile(internalFile, mediaType);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
defaultContentType = mediaType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2388,7 +2424,7 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
|
|||
}
|
||||
|
||||
if (postDataStream) {
|
||||
nsCOMPtr<nsIUploadChannel> uploadChannel(do_QueryInterface(httpChannel));
|
||||
nsCOMPtr<nsIUploadChannel2> uploadChannel(do_QueryInterface(httpChannel));
|
||||
NS_ASSERTION(uploadChannel, "http must support nsIUploadChannel");
|
||||
|
||||
// If no content type header was set by the client, we set it to
|
||||
|
@ -2427,15 +2463,26 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
|
|||
}
|
||||
}
|
||||
|
||||
// If necessary, wrap the stream in a buffered stream so as to guarantee
|
||||
// support for our upload when calling ExplicitSetUploadStream.
|
||||
if (!NS_InputStreamIsBuffered(postDataStream)) {
|
||||
nsCOMPtr<nsIInputStream> bufferedStream;
|
||||
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
|
||||
postDataStream,
|
||||
4096);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
postDataStream = bufferedStream;
|
||||
}
|
||||
|
||||
mUploadComplete = PR_FALSE;
|
||||
PRUint32 uploadTotal = 0;
|
||||
postDataStream->Available(&uploadTotal);
|
||||
mUploadTotal = uploadTotal;
|
||||
rv = uploadChannel->SetUploadStream(postDataStream, contentType, -1);
|
||||
// Reset the method to its original value
|
||||
if (httpChannel) {
|
||||
httpChannel->SetRequestMethod(method);
|
||||
}
|
||||
|
||||
// We want to use a newer version of the upload channel that won't
|
||||
// ignore the necessary headers for an empty Content-Type.
|
||||
rv = uploadChannel->ExplicitSetUploadStream(postDataStream, contentType, -1, method, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,5 +18,13 @@ function handleRequest(request, response)
|
|||
Array.prototype.push.apply(bytes, body.readByteArray(avail));
|
||||
|
||||
var data = String.fromCharCode.apply(null, bytes);
|
||||
response.write(data);
|
||||
}
|
||||
response.setHeader("Result-Content-Length", "" + data.length);
|
||||
if (data.indexOf("TEST_REDIRECT_STR") >= 0) {
|
||||
var newURL = "http://" + data.split("&url=")[1];
|
||||
response.setStatusLine(null, 307, "redirect");
|
||||
response.setHeader("Location", newURL, false);
|
||||
}
|
||||
else {
|
||||
response.write(data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=464848
|
|||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=464848">Mozilla Bug 464848</a>
|
||||
<p id="display">
|
||||
<input id="fileList" type="file"></input>
|
||||
</p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
|
@ -32,6 +33,32 @@ testDoc2.appendChild(testDoc2.createElement("res"));
|
|||
testDoc2.documentElement.appendChild(testDoc2.createTextNode("text"));
|
||||
is(testDoc2.inputEncoding, null, "wrong encoding");
|
||||
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
var testData = "blahblahblahblahblahblahblaaaaaaaah. blah.";
|
||||
testFileTxt = createFileWithDataExt(testData, ".txt");
|
||||
testFilePng = createFileWithDataExt(testData, ".png");
|
||||
testFileJpg = createFileWithDataExt(testData, ".jpg");
|
||||
testFileGif = createFileWithDataExt(testData, ".gif");
|
||||
testFilePdf = createFileWithDataExt(testData, ".pdf");
|
||||
testFileXml = createFileWithDataExt(testData, ".xml");
|
||||
testFileUnknown = createFileWithDataExt(testData, "noext");
|
||||
|
||||
function createFileWithDataExt(fileData, extension) {
|
||||
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
|
||||
var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
|
||||
testFile.append("testfile" + extension);
|
||||
var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
|
||||
outStream.init(testFile, 0x02 | 0x08 | 0x20, 0666, 0);
|
||||
outStream.write(fileData, fileData.length);
|
||||
outStream.close();
|
||||
|
||||
var fileList = document.getElementById('fileList');
|
||||
fileList.value = testFile.path;
|
||||
|
||||
return fileList.files[0];
|
||||
}
|
||||
|
||||
tests = [{ body: null,
|
||||
resBody: "",
|
||||
},
|
||||
|
@ -109,30 +136,105 @@ tests = [{ body: null,
|
|||
resBody: "<!-- doc 2 -->\n<res>text</res>",
|
||||
resContentType: "foo/bar; charset=uTf-8",
|
||||
},
|
||||
{ body: testFileTxt,
|
||||
resBody: testData,
|
||||
resContentType: testFileTxt.mediaType,
|
||||
resContentLength: testData.length,
|
||||
},
|
||||
{ body: testFilePng,
|
||||
resBody: testData,
|
||||
resContentType: testFilePng.mediaType,
|
||||
resContentLength: testData.length,
|
||||
},
|
||||
{ body: testFileJpg,
|
||||
resBody: testData,
|
||||
resContentType: testFileJpg.mediaType,
|
||||
resContentLength: testData.length,
|
||||
},
|
||||
{ body: testFileGif,
|
||||
resBody: testData,
|
||||
resContentType: testFileGif.mediaType,
|
||||
resContentLength: testData.length,
|
||||
},
|
||||
{ body: testFilePdf,
|
||||
resBody: testData,
|
||||
resContentType: testFilePdf.mediaType,
|
||||
resContentLength: testData.length,
|
||||
},
|
||||
{ body: testFileXml,
|
||||
resBody: testData,
|
||||
resContentType: testFileXml.mediaType,
|
||||
resContentLength: testData.length,
|
||||
},
|
||||
{ body: testFileUnknown,
|
||||
resBody: testData,
|
||||
resContentType: "",
|
||||
resContentLength: testData.length,
|
||||
},
|
||||
{ //will trigger a redirect test server-side
|
||||
body: ("TEST_REDIRECT_STR&url=" + window.location.host + window.location.pathname),
|
||||
redirect: true,
|
||||
},
|
||||
];
|
||||
|
||||
for each(test in tests) {
|
||||
xhr = new XMLHttpRequest;
|
||||
xhr.open("POST", "file_XHRSendData.sjs", false);
|
||||
if (test.contentType)
|
||||
xhr.setRequestHeader("Content-Type", test.contentType);
|
||||
xhr.send(test.body);
|
||||
try {
|
||||
for each(test in tests) {
|
||||
xhr = new XMLHttpRequest;
|
||||
xhr.open("POST", "file_XHRSendData.sjs", false);
|
||||
if (test.contentType)
|
||||
xhr.setRequestHeader("Content-Type", test.contentType);
|
||||
xhr.send(test.body);
|
||||
|
||||
if (test.resContentType) {
|
||||
is(xhr.getResponseHeader("Result-Content-Type"), test.resContentType,
|
||||
"Wrong Content-Type sent");
|
||||
}
|
||||
else {
|
||||
is(xhr.getResponseHeader("Result-Content-Type"), null);
|
||||
}
|
||||
if (test.resContentType) {
|
||||
is(xhr.getResponseHeader("Result-Content-Type"), test.resContentType,
|
||||
"Wrong Content-Type sent");
|
||||
}
|
||||
else {
|
||||
is(xhr.getResponseHeader("Result-Content-Type"), null);
|
||||
}
|
||||
|
||||
if (test.body instanceof Document) {
|
||||
is(xhr.responseText.replace("\r\n", "\n"), test.resBody, "Wrong body");
|
||||
}
|
||||
else {
|
||||
is(xhr.responseText, test.resBody, "Wrong body");
|
||||
if (test.resContentLength) {
|
||||
is(xhr.getResponseHeader("Result-Content-Length"), test.resContentLength, "Wrong Content-Length sent");
|
||||
}
|
||||
|
||||
if (test.body instanceof Document) {
|
||||
is(xhr.responseText.replace("\r\n", "\n"), test.resBody, "Wrong body");
|
||||
}
|
||||
else if (!test.redirect) {
|
||||
is(xhr.responseText, test.resBody, "Wrong body");
|
||||
}
|
||||
else {
|
||||
// If we're testing redirect, determine whether the body is
|
||||
// this document by looking for the relevant bug url
|
||||
is(xhr.responseText.indexOf("https://bugzilla.mozilla.org/show_bug.cgi?id=464848") >= 0, true,
|
||||
"Wrong page for redirect");
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
cleanUpData();
|
||||
}
|
||||
|
||||
function cleanUpData() {
|
||||
removeFileWithExt(".txt");
|
||||
removeFileWithExt(".png");
|
||||
removeFileWithExt(".jpg");
|
||||
removeFileWithExt(".gif");
|
||||
removeFileWithExt(".pdf");
|
||||
removeFileWithExt(".xml");
|
||||
removeFileWithExt("noext");
|
||||
}
|
||||
|
||||
function removeFileWithExt(extension)
|
||||
{
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
|
||||
var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
|
||||
|
||||
testFile.append("testfile" + extension);
|
||||
testFile.remove(false);
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
|
|
@ -111,6 +111,7 @@ XPIDLSRCS = \
|
|||
nsISyncStreamListener.idl \
|
||||
nsISystemProxySettings.idl \
|
||||
nsIUnicharStreamLoader.idl \
|
||||
nsIUploadChannel2.idl \
|
||||
nsIStandardURL.idl \
|
||||
nsINestedURI.idl \
|
||||
nsIURLParser.idl \
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIInputStream;
|
||||
|
||||
[scriptable, uuid(8821E259-7252-4464-B874-A55D8EF6B222)]
|
||||
interface nsIUploadChannel2 : nsISupports
|
||||
{
|
||||
/**
|
||||
* Sets a stream to be uploaded by this channel with the specified
|
||||
* Content-Type and Content-Length header values.
|
||||
*
|
||||
* Most implementations of this interface require that the stream:
|
||||
* (1) implement threadsafe addRef and release
|
||||
* (2) implement nsIInputStream::readSegments
|
||||
* (3) implement nsISeekableStream::seek
|
||||
*
|
||||
* @param aStream
|
||||
* The stream to be uploaded by this channel.
|
||||
* @param aContentType
|
||||
* This value will replace any existing Content-Type
|
||||
* header on the HTTP request, regardless of whether
|
||||
* or not its empty.
|
||||
* @param aContentLength
|
||||
* A value of -1 indicates that the length of the stream should be
|
||||
* determined by calling the stream's |available| method.
|
||||
* @param aMethod
|
||||
* The HTTP request method to set on the stream.
|
||||
* @param aStreamHasHeaders
|
||||
* True if the stream already contains headers for the HTTP request.
|
||||
*/
|
||||
void explicitSetUploadStream(in nsIInputStream aStream,
|
||||
in ACString aContentType,
|
||||
in long long aContentLength,
|
||||
in ACString aMethod,
|
||||
in boolean aStreamHasHeaders);
|
||||
};
|
|
@ -2771,7 +2771,7 @@ nsHttpChannel::SetupReplacementChannel(nsIURI *newURI,
|
|||
return NS_OK; // no other options to set
|
||||
|
||||
if (preserveMethod) {
|
||||
nsCOMPtr<nsIUploadChannel> uploadChannel = do_QueryInterface(httpChannel);
|
||||
nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(httpChannel);
|
||||
if (mUploadStream && uploadChannel) {
|
||||
// rewind upload stream
|
||||
nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream);
|
||||
|
@ -2779,19 +2779,23 @@ nsHttpChannel::SetupReplacementChannel(nsIURI *newURI,
|
|||
seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
|
||||
|
||||
// replicate original call to SetUploadStream...
|
||||
if (mUploadStreamHasHeaders)
|
||||
uploadChannel->SetUploadStream(mUploadStream, EmptyCString(), -1);
|
||||
else {
|
||||
const char *ctype = mRequestHead.PeekHeader(nsHttp::Content_Type);
|
||||
const char *clen = mRequestHead.PeekHeader(nsHttp::Content_Length);
|
||||
if (ctype && clen)
|
||||
uploadChannel->SetUploadStream(mUploadStream,
|
||||
nsDependentCString(ctype),
|
||||
atoi(clen));
|
||||
}
|
||||
const char *ctype = mRequestHead.PeekHeader(nsHttp::Content_Type);
|
||||
if (!ctype)
|
||||
ctype = "";
|
||||
const char *clen = mRequestHead.PeekHeader(nsHttp::Content_Length);
|
||||
if (clen)
|
||||
uploadChannel->ExplicitSetUploadStream(
|
||||
mUploadStream,
|
||||
nsDependentCString(ctype),
|
||||
nsCRT::atoll(clen),
|
||||
nsDependentCString(mRequestHead.Method()),
|
||||
mUploadStreamHasHeaders);
|
||||
}
|
||||
// must happen after setting upload stream since SetUploadStream
|
||||
// may change the request method.
|
||||
// since preserveMethod is true, we need to ensure that the appropriate
|
||||
// request method gets set on the channel, regardless of whether or not
|
||||
// we set the upload stream above. This means SetRequestMethod() will
|
||||
// be called twice if ExplicitSetUploadStream() gets called above.
|
||||
|
||||
httpChannel->SetRequestMethod(nsDependentCString(mRequestHead.Method()));
|
||||
}
|
||||
// convey the referrer if one was used for this channel to the next one
|
||||
|
@ -4078,6 +4082,7 @@ NS_INTERFACE_MAP_BEGIN(nsHttpChannel)
|
|||
NS_INTERFACE_MAP_ENTRY(nsIHttpChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsICachingChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIUploadChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIUploadChannel2)
|
||||
NS_INTERFACE_MAP_ENTRY(nsICacheListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIEncodedChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIHttpChannelInternal)
|
||||
|
@ -4685,7 +4690,9 @@ nsHttpChannel::GetUploadStream(nsIInputStream **stream)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpChannel::SetUploadStream(nsIInputStream *stream, const nsACString &contentType, PRInt32 contentLength)
|
||||
nsHttpChannel::SetUploadStream(nsIInputStream *stream,
|
||||
const nsACString &contentType,
|
||||
PRInt32 contentLength)
|
||||
{
|
||||
// NOTE: for backwards compatibility and for compatibility with old style
|
||||
// plugins, |stream| may include headers, specifically Content-Type and
|
||||
|
@ -4703,7 +4710,8 @@ nsHttpChannel::SetUploadStream(nsIInputStream *stream, const nsACString &content
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
mRequestHead.SetHeader(nsHttp::Content_Length, nsPrintfCString("%d", contentLength));
|
||||
mRequestHead.SetHeader(nsHttp::Content_Length,
|
||||
nsPrintfCString("%d", contentLength));
|
||||
mRequestHead.SetHeader(nsHttp::Content_Type, contentType);
|
||||
mUploadStreamHasHeaders = PR_FALSE;
|
||||
mRequestHead.SetMethod(nsHttp::Put); // PUT request
|
||||
|
@ -4721,6 +4729,37 @@ nsHttpChannel::SetUploadStream(nsIInputStream *stream, const nsACString &content
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpChannel::ExplicitSetUploadStream(nsIInputStream *aStream,
|
||||
const nsACString &aContentType,
|
||||
PRInt64 aContentLength,
|
||||
const nsACString &aMethod,
|
||||
PRBool aStreamHasHeaders)
|
||||
{
|
||||
// Ensure stream is set and method is valid
|
||||
NS_ENSURE_TRUE(aStream, NS_ERROR_FAILURE);
|
||||
|
||||
if (aContentLength < 0) {
|
||||
PRUint32 streamLength;
|
||||
aStream->Available(&streamLength);
|
||||
aContentLength = streamLength;
|
||||
if (aContentLength < 0) {
|
||||
NS_ERROR("unable to determine content length");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = SetRequestMethod(aMethod);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mRequestHead.SetHeader(nsHttp::Content_Length, nsPrintfCString("%lld", aContentLength));
|
||||
mRequestHead.SetHeader(nsHttp::Content_Type, aContentType);
|
||||
|
||||
mUploadStreamHasHeaders = aStreamHasHeaders;
|
||||
mUploadStream = aStream;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpChannel::GetResponseStatus(PRUint32 *value)
|
||||
{
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
#include "nsIEncodedChannel.h"
|
||||
#include "nsITransport.h"
|
||||
#include "nsIUploadChannel.h"
|
||||
#include "nsIUploadChannel2.h"
|
||||
#include "nsIStringEnumerator.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIAsyncInputStream.h"
|
||||
|
@ -101,6 +102,7 @@ class nsHttpChannel : public nsHashPropertyBag
|
|||
, public nsIStreamListener
|
||||
, public nsICachingChannel
|
||||
, public nsIUploadChannel
|
||||
, public nsIUploadChannel2
|
||||
, public nsICacheListener
|
||||
, public nsIEncodedChannel
|
||||
, public nsITransportEventSink
|
||||
|
@ -121,6 +123,7 @@ public:
|
|||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSICACHINGCHANNEL
|
||||
NS_DECL_NSIUPLOADCHANNEL
|
||||
NS_DECL_NSIUPLOADCHANNEL2
|
||||
NS_DECL_NSICACHELISTENER
|
||||
NS_DECL_NSIENCODEDCHANNEL
|
||||
NS_DECL_NSIHTTPCHANNELINTERNAL
|
||||
|
|
Загрузка…
Ссылка в новой задаче