diff --git a/content/base/public/Makefile.in b/content/base/public/Makefile.in index 1f3fcd722f2..4e935dd7e9a 100644 --- a/content/base/public/Makefile.in +++ b/content/base/public/Makefile.in @@ -93,6 +93,7 @@ XPIDLSRCS = \ nsIContentPolicy.idl \ nsIDocumentEncoder.idl \ nsIDOMFile.idl \ + nsIDOMFileInternal.idl \ nsIDOMFileList.idl \ nsIDOMFileException.idl \ nsIDOMParser.idl \ diff --git a/content/base/public/nsDOMFile.h b/content/base/public/nsDOMFile.h index 2b022d16120..ba1d77b0a39 100644 --- a/content/base/public/nsDOMFile.h +++ b/content/base/public/nsDOMFile.h @@ -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) diff --git a/content/base/public/nsIDOMFileInternal.idl b/content/base/public/nsIDOMFileInternal.idl new file mode 100644 index 00000000000..a4e5dd6d461 --- /dev/null +++ b/content/base/public/nsIDOMFileInternal.idl @@ -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; +}; diff --git a/content/base/src/nsDOMFile.cpp b/content/base/src/nsDOMFile.cpp index 1e1a4edf4e4..169d7857712 100644 --- a/content/base/src/nsDOMFile.cpp +++ b/content/base/src/nsDOMFile.cpp @@ -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) { diff --git a/content/base/src/nsXMLHttpRequest.cpp b/content/base/src/nsXMLHttpRequest.cpp index 0cd8c5d60e9..7723efaac58 100644 --- a/content/base/src/nsXMLHttpRequest.cpp +++ b/content/base/src/nsXMLHttpRequest.cpp @@ -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 file(do_QueryInterface(supports)); + + if (file) { + nsCOMPtr internalFile; + rv = file->GetInternalFile(getter_AddRefs(internalFile)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr 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 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 uploadChannel(do_QueryInterface(httpChannel)); + nsCOMPtr 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 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); } } diff --git a/content/base/test/file_XHRSendData.sjs b/content/base/test/file_XHRSendData.sjs index 96677fbab29..0ccbe8a457a 100644 --- a/content/base/test/file_XHRSendData.sjs +++ b/content/base/test/file_XHRSendData.sjs @@ -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); -} \ No newline at end of file + 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); + } +} diff --git a/content/base/test/test_XHRSendData.html b/content/base/test/test_XHRSendData.html index 8e2013742ba..2cf24079d42 100644 --- a/content/base/test/test_XHRSendData.html +++ b/content/base/test/test_XHRSendData.html @@ -13,6 +13,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=464848 Mozilla Bug 464848

+