Commit 64c233c8 authored by Matin Movassate's avatar Matin Movassate
Browse files

Resolving bug 491201. Added ability for XMLHttpRequest.send() to accept an...

Resolving bug 491201. Added ability for XMLHttpRequest.send() to accept an nsIDOMFile. r+sr=jonas@sicking.cc, r=cbiesinger@gmail.com
parent 05cab632
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ XPIDLSRCS = \
		nsIContentPolicy.idl        \
		nsIDocumentEncoder.idl      \
		nsIDOMFile.idl \
		nsIDOMFileInternal.idl \
		nsIDOMFileList.idl \
		nsIDOMFileException.idl \
		nsIDOMParser.idl \
+3 −0
Original line number Diff line number Diff line
@@ -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)
+46 −0
Original line number Diff line number Diff line
/* -*- 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;
};
+15 −0
Original line number Diff line number Diff line
@@ -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)
{
+53 −6
Original line number Diff line number Diff line
@@ -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);
    }
  }

Loading