2015-05-03 19:32:37 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 11:12:37 +00:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2010-02-25 05:58:18 +00:00
|
|
|
|
2016-01-07 19:30:36 +00:00
|
|
|
#include "FormData.h"
|
2010-02-25 05:58:18 +00:00
|
|
|
#include "nsIVariant.h"
|
|
|
|
#include "nsIInputStream.h"
|
2014-10-08 16:15:23 +00:00
|
|
|
#include "mozilla/dom/File.h"
|
2013-06-19 14:24:37 +00:00
|
|
|
#include "mozilla/dom/HTMLFormElement.h"
|
2015-02-21 19:54:44 +00:00
|
|
|
|
2015-05-12 12:11:03 +00:00
|
|
|
#include "MultipartBlobImpl.h"
|
Bug 1127150 - Use File's name instead of explicit file name in form submission related classes. r=baku
Our nsFormSubmission and subclasses accepted a third filename argument to
explicitly specify the filename. Since switching from nsIDOMBlob to File in Bug
1085283, we can read out the filename directly from the File. This simplifies
the code, but introduces a change in the way Firefox submits form data to
servers.
Consider the code:
var fd = new FormData();
fd.append("blob1", new Blob(["hi"]), ""); // explicit empty filename as third arg
fd.append("file1", new File(["hi"], "")); // File's name is empty, no third arg.
xhr.send(fd);
Previously, the request body had filename="" in the first case, and filename="blob" in the second.
This patch will change it to both cases result in filename=""
This behaviour isn't exactly specced anywhere, nor in the HTML spec [1], nor in
RFC 2388. In addition Blink (at least Chromium v40) has the same behaviour
introduced by this patch. So shipping it seems ok to me.
[1]: http://www.w3.org/html/wg/drafts/html/master/semantics.html#multipart/form-data-encoding-algorithm
--HG--
extra : rebase_source : 6631e6900fe1a9b991c397b76e5be6b913715c5a
2015-02-21 19:54:44 +00:00
|
|
|
|
2012-12-11 18:09:56 +00:00
|
|
|
using namespace mozilla;
|
|
|
|
using namespace mozilla::dom;
|
|
|
|
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::FormData(nsISupports* aOwner)
|
2016-06-16 07:24:16 +00:00
|
|
|
: HTMLFormSubmission(NS_LITERAL_CSTRING("UTF-8"), nullptr)
|
2012-12-11 18:09:56 +00:00
|
|
|
, mOwner(aOwner)
|
2010-02-25 05:58:18 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
Bug 1127150 - Use File's name instead of explicit file name in form submission related classes. r=baku
Our nsFormSubmission and subclasses accepted a third filename argument to
explicitly specify the filename. Since switching from nsIDOMBlob to File in Bug
1085283, we can read out the filename directly from the File. This simplifies
the code, but introduces a change in the way Firefox submits form data to
servers.
Consider the code:
var fd = new FormData();
fd.append("blob1", new Blob(["hi"]), ""); // explicit empty filename as third arg
fd.append("file1", new File(["hi"], "")); // File's name is empty, no third arg.
xhr.send(fd);
Previously, the request body had filename="" in the first case, and filename="blob" in the second.
This patch will change it to both cases result in filename=""
This behaviour isn't exactly specced anywhere, nor in the HTML spec [1], nor in
RFC 2388. In addition Blink (at least Chromium v40) has the same behaviour
introduced by this patch. So shipping it seems ok to me.
[1]: http://www.w3.org/html/wg/drafts/html/master/semantics.html#multipart/form-data-encoding-algorithm
--HG--
extra : rebase_source : 6631e6900fe1a9b991c397b76e5be6b913715c5a
2015-02-21 19:54:44 +00:00
|
|
|
namespace {
|
2015-05-12 12:09:51 +00:00
|
|
|
|
2016-02-17 14:56:19 +00:00
|
|
|
already_AddRefed<File>
|
|
|
|
GetOrCreateFileCalledBlob(Blob& aBlob, ErrorResult& aRv)
|
Bug 1127150 - Use File's name instead of explicit file name in form submission related classes. r=baku
Our nsFormSubmission and subclasses accepted a third filename argument to
explicitly specify the filename. Since switching from nsIDOMBlob to File in Bug
1085283, we can read out the filename directly from the File. This simplifies
the code, but introduces a change in the way Firefox submits form data to
servers.
Consider the code:
var fd = new FormData();
fd.append("blob1", new Blob(["hi"]), ""); // explicit empty filename as third arg
fd.append("file1", new File(["hi"], "")); // File's name is empty, no third arg.
xhr.send(fd);
Previously, the request body had filename="" in the first case, and filename="blob" in the second.
This patch will change it to both cases result in filename=""
This behaviour isn't exactly specced anywhere, nor in the HTML spec [1], nor in
RFC 2388. In addition Blink (at least Chromium v40) has the same behaviour
introduced by this patch. So shipping it seems ok to me.
[1]: http://www.w3.org/html/wg/drafts/html/master/semantics.html#multipart/form-data-encoding-algorithm
--HG--
extra : rebase_source : 6631e6900fe1a9b991c397b76e5be6b913715c5a
2015-02-21 19:54:44 +00:00
|
|
|
{
|
2016-02-17 14:56:19 +00:00
|
|
|
// If this is file, we can just use it
|
|
|
|
RefPtr<File> file = aBlob.ToFile();
|
|
|
|
if (file) {
|
|
|
|
return file.forget();
|
Bug 1127150 - Use File's name instead of explicit file name in form submission related classes. r=baku
Our nsFormSubmission and subclasses accepted a third filename argument to
explicitly specify the filename. Since switching from nsIDOMBlob to File in Bug
1085283, we can read out the filename directly from the File. This simplifies
the code, but introduces a change in the way Firefox submits form data to
servers.
Consider the code:
var fd = new FormData();
fd.append("blob1", new Blob(["hi"]), ""); // explicit empty filename as third arg
fd.append("file1", new File(["hi"], "")); // File's name is empty, no third arg.
xhr.send(fd);
Previously, the request body had filename="" in the first case, and filename="blob" in the second.
This patch will change it to both cases result in filename=""
This behaviour isn't exactly specced anywhere, nor in the HTML spec [1], nor in
RFC 2388. In addition Blink (at least Chromium v40) has the same behaviour
introduced by this patch. So shipping it seems ok to me.
[1]: http://www.w3.org/html/wg/drafts/html/master/semantics.html#multipart/form-data-encoding-algorithm
--HG--
extra : rebase_source : 6631e6900fe1a9b991c397b76e5be6b913715c5a
2015-02-21 19:54:44 +00:00
|
|
|
}
|
|
|
|
|
2016-02-17 14:56:19 +00:00
|
|
|
// Forcing 'blob' as filename
|
|
|
|
file = aBlob.ToFile(NS_LITERAL_STRING("blob"), aRv);
|
2015-12-04 21:15:46 +00:00
|
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return file.forget();
|
2015-05-11 21:54:02 +00:00
|
|
|
}
|
2015-05-12 12:09:51 +00:00
|
|
|
|
2016-02-17 14:56:19 +00:00
|
|
|
already_AddRefed<File>
|
|
|
|
GetBlobForFormDataStorage(Blob& aBlob, const Optional<nsAString>& aFilename,
|
|
|
|
ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
// Forcing a filename
|
|
|
|
if (aFilename.WasPassed()) {
|
|
|
|
RefPtr<File> file = aBlob.ToFile(aFilename.Value(), aRv);
|
|
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return file.forget();
|
|
|
|
}
|
|
|
|
|
|
|
|
return GetOrCreateFileCalledBlob(aBlob, aRv);
|
|
|
|
}
|
|
|
|
|
2015-07-13 15:25:42 +00:00
|
|
|
} // namespace
|
Bug 1127150 - Use File's name instead of explicit file name in form submission related classes. r=baku
Our nsFormSubmission and subclasses accepted a third filename argument to
explicitly specify the filename. Since switching from nsIDOMBlob to File in Bug
1085283, we can read out the filename directly from the File. This simplifies
the code, but introduces a change in the way Firefox submits form data to
servers.
Consider the code:
var fd = new FormData();
fd.append("blob1", new Blob(["hi"]), ""); // explicit empty filename as third arg
fd.append("file1", new File(["hi"], "")); // File's name is empty, no third arg.
xhr.send(fd);
Previously, the request body had filename="" in the first case, and filename="blob" in the second.
This patch will change it to both cases result in filename=""
This behaviour isn't exactly specced anywhere, nor in the HTML spec [1], nor in
RFC 2388. In addition Blink (at least Chromium v40) has the same behaviour
introduced by this patch. So shipping it seems ok to me.
[1]: http://www.w3.org/html/wg/drafts/html/master/semantics.html#multipart/form-data-encoding-algorithm
--HG--
extra : rebase_source : 6631e6900fe1a9b991c397b76e5be6b913715c5a
2015-02-21 19:54:44 +00:00
|
|
|
|
2010-02-25 05:58:18 +00:00
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
// nsISupports
|
|
|
|
|
2016-01-07 19:30:36 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(FormData)
|
2014-10-08 16:15:22 +00:00
|
|
|
|
2016-01-07 19:30:36 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FormData)
|
2014-10-08 16:15:22 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
|
|
|
|
|
|
|
|
for (uint32_t i = 0, len = tmp->mFormData.Length(); i < len; ++i) {
|
2015-10-20 02:06:00 +00:00
|
|
|
ImplCycleCollectionUnlink(tmp->mFormData[i].value);
|
2014-10-08 16:15:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
|
2016-01-07 19:30:36 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(FormData)
|
2014-10-08 16:15:22 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
|
|
|
|
|
|
|
|
for (uint32_t i = 0, len = tmp->mFormData.Length(); i < len; ++i) {
|
2015-10-20 02:06:00 +00:00
|
|
|
ImplCycleCollectionTraverse(cb, tmp->mFormData[i].value,
|
2016-01-20 17:25:03 +00:00
|
|
|
"mFormData[i].GetAsBlob()", 0);
|
2014-10-08 16:15:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
|
2016-01-07 19:30:36 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(FormData)
|
2014-10-08 16:15:22 +00:00
|
|
|
|
2016-01-07 19:30:36 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(FormData)
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(FormData)
|
2014-10-08 16:15:22 +00:00
|
|
|
|
2016-01-07 19:30:36 +00:00
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FormData)
|
2012-12-11 18:09:56 +00:00
|
|
|
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
2010-02-25 05:58:18 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIDOMFormData)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIXHRSendable)
|
|
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFormData)
|
|
|
|
NS_INTERFACE_MAP_END
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------
|
2016-06-16 07:24:16 +00:00
|
|
|
// HTMLFormSubmission
|
2010-02-25 05:58:18 +00:00
|
|
|
nsresult
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::GetEncodedSubmission(nsIURI* aURI,
|
|
|
|
nsIInputStream** aPostDataStream)
|
2010-02-25 05:58:18 +00:00
|
|
|
{
|
2016-01-07 19:30:36 +00:00
|
|
|
NS_NOTREACHED("Shouldn't call FormData::GetEncodedSubmission");
|
2010-02-25 05:58:18 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-12-11 18:09:56 +00:00
|
|
|
void
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::Append(const nsAString& aName, const nsAString& aValue,
|
|
|
|
ErrorResult& aRv)
|
2010-02-25 05:58:18 +00:00
|
|
|
{
|
2013-03-03 18:30:13 +00:00
|
|
|
AddNameValuePair(aName, aValue);
|
2010-02-25 05:58:18 +00:00
|
|
|
}
|
|
|
|
|
2012-12-11 18:09:56 +00:00
|
|
|
void
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::Append(const nsAString& aName, Blob& aBlob,
|
|
|
|
const Optional<nsAString>& aFilename,
|
2016-01-20 17:25:03 +00:00
|
|
|
ErrorResult& aRv)
|
2010-02-25 05:58:18 +00:00
|
|
|
{
|
2016-02-17 14:56:19 +00:00
|
|
|
RefPtr<File> file = GetBlobForFormDataStorage(aBlob, aFilename, aRv);
|
2015-12-04 21:15:46 +00:00
|
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-02-23 23:01:01 +00:00
|
|
|
AddNameBlobOrNullPair(aName, file);
|
2015-01-29 01:04:28 +00:00
|
|
|
}
|
|
|
|
|
2016-07-14 07:01:31 +00:00
|
|
|
void
|
|
|
|
FormData::Append(const nsAString& aName, Directory* aDirectory)
|
|
|
|
{
|
|
|
|
AddNameDirectoryPair(aName, aDirectory);
|
|
|
|
}
|
|
|
|
|
2015-01-29 01:04:28 +00:00
|
|
|
void
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::Delete(const nsAString& aName)
|
2015-01-29 01:04:28 +00:00
|
|
|
{
|
|
|
|
// We have to use this slightly awkward for loop since uint32_t >= 0 is an
|
|
|
|
// error for being always true.
|
|
|
|
for (uint32_t i = mFormData.Length(); i-- > 0; ) {
|
|
|
|
if (aName.Equals(mFormData[i].name)) {
|
|
|
|
mFormData.RemoveElementAt(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::Get(const nsAString& aName,
|
2016-07-14 07:01:31 +00:00
|
|
|
Nullable<OwningBlobOrDirectoryOrUSVString>& aOutValue)
|
2015-01-29 01:04:28 +00:00
|
|
|
{
|
|
|
|
for (uint32_t i = 0; i < mFormData.Length(); ++i) {
|
|
|
|
if (aName.Equals(mFormData[i].name)) {
|
2015-10-20 02:06:00 +00:00
|
|
|
aOutValue.SetValue() = mFormData[i].value;
|
2015-01-29 01:04:28 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
aOutValue.SetNull();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::GetAll(const nsAString& aName,
|
2016-07-14 07:01:31 +00:00
|
|
|
nsTArray<OwningBlobOrDirectoryOrUSVString>& aValues)
|
2015-01-29 01:04:28 +00:00
|
|
|
{
|
|
|
|
for (uint32_t i = 0; i < mFormData.Length(); ++i) {
|
|
|
|
if (aName.Equals(mFormData[i].name)) {
|
2016-07-14 07:01:31 +00:00
|
|
|
OwningBlobOrDirectoryOrUSVString* element = aValues.AppendElement();
|
2015-10-20 02:06:00 +00:00
|
|
|
*element = mFormData[i].value;
|
2015-01-29 01:04:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::Has(const nsAString& aName)
|
2015-01-29 01:04:28 +00:00
|
|
|
{
|
|
|
|
for (uint32_t i = 0; i < mFormData.Length(); ++i) {
|
|
|
|
if (aName.Equals(mFormData[i].name)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-05-12 12:09:51 +00:00
|
|
|
nsresult
|
2016-02-23 23:01:01 +00:00
|
|
|
FormData::AddNameBlobOrNullPair(const nsAString& aName, Blob* aBlob)
|
2015-05-12 12:09:51 +00:00
|
|
|
{
|
2016-02-23 23:01:01 +00:00
|
|
|
RefPtr<File> file;
|
|
|
|
|
|
|
|
if (!aBlob) {
|
|
|
|
FormDataTuple* data = mFormData.AppendElement();
|
|
|
|
SetNameValuePair(data, aName, EmptyString(), true /* aWasNullBlob */);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2016-01-08 08:35:30 +00:00
|
|
|
|
2016-02-17 14:56:19 +00:00
|
|
|
ErrorResult rv;
|
2016-02-23 23:01:01 +00:00
|
|
|
file = GetOrCreateFileCalledBlob(*aBlob, rv);
|
2016-02-17 14:56:19 +00:00
|
|
|
if (NS_WARN_IF(rv.Failed())) {
|
|
|
|
return rv.StealNSResult();
|
|
|
|
}
|
|
|
|
|
2015-05-12 12:09:51 +00:00
|
|
|
FormDataTuple* data = mFormData.AppendElement();
|
2016-02-17 14:56:19 +00:00
|
|
|
SetNameFilePair(data, aName, file);
|
2015-05-12 12:09:51 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2016-07-14 07:01:31 +00:00
|
|
|
nsresult
|
|
|
|
FormData::AddNameDirectoryPair(const nsAString& aName, Directory* aDirectory)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(aDirectory);
|
|
|
|
|
|
|
|
FormDataTuple* data = mFormData.AppendElement();
|
|
|
|
SetNameDirectoryPair(data, aName, aDirectory);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::FormDataTuple*
|
|
|
|
FormData::RemoveAllOthersAndGetFirstFormDataTuple(const nsAString& aName)
|
2015-01-29 01:04:28 +00:00
|
|
|
{
|
|
|
|
FormDataTuple* lastFoundTuple = nullptr;
|
|
|
|
uint32_t lastFoundIndex = mFormData.Length();
|
|
|
|
// We have to use this slightly awkward for loop since uint32_t >= 0 is an
|
|
|
|
// error for being always true.
|
|
|
|
for (uint32_t i = mFormData.Length(); i-- > 0; ) {
|
|
|
|
if (aName.Equals(mFormData[i].name)) {
|
|
|
|
if (lastFoundTuple) {
|
|
|
|
// The one we found earlier was not the first one, we can remove it.
|
|
|
|
mFormData.RemoveElementAt(lastFoundIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
lastFoundTuple = &mFormData[i];
|
|
|
|
lastFoundIndex = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return lastFoundTuple;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::Set(const nsAString& aName, Blob& aBlob,
|
|
|
|
const Optional<nsAString>& aFilename,
|
|
|
|
ErrorResult& aRv)
|
2015-01-29 01:04:28 +00:00
|
|
|
{
|
|
|
|
FormDataTuple* tuple = RemoveAllOthersAndGetFirstFormDataTuple(aName);
|
|
|
|
if (tuple) {
|
2016-02-17 14:56:19 +00:00
|
|
|
RefPtr<File> file = GetBlobForFormDataStorage(aBlob, aFilename, aRv);
|
2015-12-04 21:15:46 +00:00
|
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-02-17 14:56:19 +00:00
|
|
|
SetNameFilePair(tuple, aName, file);
|
2015-01-29 01:04:28 +00:00
|
|
|
} else {
|
2015-12-04 21:15:46 +00:00
|
|
|
Append(aName, aBlob, aFilename, aRv);
|
2015-01-29 01:04:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::Set(const nsAString& aName, const nsAString& aValue,
|
|
|
|
ErrorResult& aRv)
|
2015-01-29 01:04:28 +00:00
|
|
|
{
|
|
|
|
FormDataTuple* tuple = RemoveAllOthersAndGetFirstFormDataTuple(aName);
|
|
|
|
if (tuple) {
|
|
|
|
SetNameValuePair(tuple, aName, aValue);
|
|
|
|
} else {
|
2015-12-04 21:15:46 +00:00
|
|
|
Append(aName, aValue, aRv);
|
2015-01-29 01:04:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-20 02:06:00 +00:00
|
|
|
uint32_t
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::GetIterableLength() const
|
2015-10-20 02:06:00 +00:00
|
|
|
{
|
|
|
|
return mFormData.Length();
|
|
|
|
}
|
|
|
|
|
|
|
|
const nsAString&
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::GetKeyAtIndex(uint32_t aIndex) const
|
2015-10-20 02:06:00 +00:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(aIndex < mFormData.Length());
|
|
|
|
return mFormData[aIndex].name;
|
|
|
|
}
|
|
|
|
|
2016-07-14 07:01:31 +00:00
|
|
|
const OwningBlobOrDirectoryOrUSVString&
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::GetValueAtIndex(uint32_t aIndex) const
|
2015-10-20 02:06:00 +00:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(aIndex < mFormData.Length());
|
|
|
|
return mFormData[aIndex].value;
|
|
|
|
}
|
|
|
|
|
2016-01-07 09:54:00 +00:00
|
|
|
void
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::SetNameValuePair(FormDataTuple* aData,
|
|
|
|
const nsAString& aName,
|
2016-02-23 23:01:01 +00:00
|
|
|
const nsAString& aValue,
|
|
|
|
bool aWasNullBlob)
|
2016-01-07 09:54:00 +00:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(aData);
|
|
|
|
aData->name = aName;
|
2016-02-23 23:01:01 +00:00
|
|
|
aData->wasNullBlob = aWasNullBlob;
|
2016-01-07 09:54:00 +00:00
|
|
|
aData->value.SetAsUSVString() = aValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-02-17 14:56:19 +00:00
|
|
|
FormData::SetNameFilePair(FormDataTuple* aData,
|
2016-01-07 19:30:36 +00:00
|
|
|
const nsAString& aName,
|
2016-02-17 14:56:19 +00:00
|
|
|
File* aFile)
|
2016-01-07 09:54:00 +00:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(aData);
|
2016-02-17 14:56:19 +00:00
|
|
|
MOZ_ASSERT(aFile);
|
2016-01-08 08:35:30 +00:00
|
|
|
|
2016-01-07 09:54:00 +00:00
|
|
|
aData->name = aName;
|
2016-02-23 23:01:01 +00:00
|
|
|
aData->wasNullBlob = false;
|
2016-02-17 14:56:19 +00:00
|
|
|
aData->value.SetAsBlob() = aFile;
|
2016-01-07 09:54:00 +00:00
|
|
|
}
|
|
|
|
|
2016-07-14 07:01:31 +00:00
|
|
|
void
|
|
|
|
FormData::SetNameDirectoryPair(FormDataTuple* aData,
|
|
|
|
const nsAString& aName,
|
|
|
|
Directory* aDirectory)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(aData);
|
|
|
|
MOZ_ASSERT(aDirectory);
|
|
|
|
|
|
|
|
aData->name = aName;
|
|
|
|
aData->wasNullBlob = false;
|
|
|
|
aData->value.SetAsDirectory() = aDirectory;
|
|
|
|
}
|
|
|
|
|
2010-02-25 05:58:18 +00:00
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
// nsIDOMFormData
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::Append(const nsAString& aName, nsIVariant* aValue)
|
2010-02-25 05:58:18 +00:00
|
|
|
{
|
2012-08-22 15:56:38 +00:00
|
|
|
uint16_t dataType;
|
2010-02-25 05:58:18 +00:00
|
|
|
nsresult rv = aValue->GetDataType(&dataType);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (dataType == nsIDataType::VTYPE_INTERFACE ||
|
|
|
|
dataType == nsIDataType::VTYPE_INTERFACE_IS) {
|
|
|
|
nsCOMPtr<nsISupports> supports;
|
|
|
|
nsID *iid;
|
|
|
|
rv = aValue->GetAsInterface(&iid, getter_AddRefs(supports));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2015-03-27 00:01:12 +00:00
|
|
|
free(iid);
|
2010-02-25 05:58:18 +00:00
|
|
|
|
2010-10-13 23:25:33 +00:00
|
|
|
nsCOMPtr<nsIDOMBlob> domBlob = do_QueryInterface(supports);
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<Blob> blob = static_cast<Blob*>(domBlob.get());
|
2010-10-13 23:25:33 +00:00
|
|
|
if (domBlob) {
|
2013-03-03 20:34:47 +00:00
|
|
|
Optional<nsAString> temp;
|
2015-12-04 21:15:46 +00:00
|
|
|
ErrorResult rv;
|
|
|
|
Append(aName, *blob, temp, rv);
|
|
|
|
if (NS_WARN_IF(rv.Failed())) {
|
|
|
|
return rv.StealNSResult();
|
|
|
|
}
|
|
|
|
|
2012-12-11 18:09:56 +00:00
|
|
|
return NS_OK;
|
2010-02-25 05:58:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-04 15:02:17 +00:00
|
|
|
char16_t* stringData = nullptr;
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t stringLen = 0;
|
2010-02-25 05:58:18 +00:00
|
|
|
rv = aValue->GetAsWStringWithSize(&stringLen, &stringData);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsString valAsString;
|
|
|
|
valAsString.Adopt(stringData, stringLen);
|
|
|
|
|
2015-12-04 21:15:46 +00:00
|
|
|
ErrorResult error;
|
|
|
|
Append(aName, valAsString, error);
|
|
|
|
if (NS_WARN_IF(error.Failed())) {
|
|
|
|
return error.StealNSResult();
|
|
|
|
}
|
|
|
|
|
2012-12-11 18:09:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* virtual */ JSObject*
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
2012-12-11 18:09:56 +00:00
|
|
|
{
|
Bug 1117172 part 3. Change the wrappercached WrapObject methods to allow passing in aGivenProto. r=peterv
The only manual changes here are to BindingUtils.h, BindingUtils.cpp,
Codegen.py, Element.cpp, IDBFileRequest.cpp, IDBObjectStore.cpp,
dom/workers/Navigator.cpp, WorkerPrivate.cpp, DeviceStorageRequestChild.cpp,
Notification.cpp, nsGlobalWindow.cpp, MessagePort.cpp, nsJSEnvironment.cpp,
Sandbox.cpp, XPCConvert.cpp, ExportHelpers.cpp, and DataStoreService.cpp. The
rest of this diff was generated by running the following commands:
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObject\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(Binding(?:_workers)?::Wrap\((?:aCx|cx|aContext|aCtx|js), [^,)]+)\)/\1, aGivenProto)/g'
2015-03-19 14:13:33 +00:00
|
|
|
return FormDataBinding::Wrap(aCx, this, aGivenProto);
|
2012-12-11 18:09:56 +00:00
|
|
|
}
|
|
|
|
|
2016-01-07 19:30:36 +00:00
|
|
|
/* static */ already_AddRefed<FormData>
|
|
|
|
FormData::Constructor(const GlobalObject& aGlobal,
|
|
|
|
const Optional<NonNull<HTMLFormElement> >& aFormElement,
|
|
|
|
ErrorResult& aRv)
|
2012-12-11 18:09:56 +00:00
|
|
|
{
|
2016-01-07 19:30:36 +00:00
|
|
|
RefPtr<FormData> formData = new FormData(aGlobal.GetAsSupports());
|
2012-12-11 18:09:56 +00:00
|
|
|
if (aFormElement.WasPassed()) {
|
2013-06-19 18:48:43 +00:00
|
|
|
aRv = aFormElement.Value().WalkFormElements(formData);
|
2012-12-11 18:09:56 +00:00
|
|
|
}
|
|
|
|
return formData.forget();
|
2010-02-25 05:58:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------
|
2010-09-15 22:52:02 +00:00
|
|
|
// nsIXHRSendable
|
2010-02-25 05:58:18 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2016-01-07 19:30:36 +00:00
|
|
|
FormData::GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength,
|
|
|
|
nsACString& aContentType, nsACString& aCharset)
|
2010-02-25 05:58:18 +00:00
|
|
|
{
|
2016-06-16 07:26:34 +00:00
|
|
|
FSMultipartFormData fs(NS_LITERAL_CSTRING("UTF-8"), nullptr);
|
2013-03-03 18:30:13 +00:00
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
for (uint32_t i = 0; i < mFormData.Length(); ++i) {
|
2016-02-23 23:01:01 +00:00
|
|
|
if (mFormData[i].wasNullBlob) {
|
|
|
|
MOZ_ASSERT(mFormData[i].value.IsUSVString());
|
|
|
|
fs.AddNameBlobOrNullPair(mFormData[i].name, nullptr);
|
2015-10-20 02:06:00 +00:00
|
|
|
} else if (mFormData[i].value.IsUSVString()) {
|
|
|
|
fs.AddNameValuePair(mFormData[i].name,
|
|
|
|
mFormData[i].value.GetAsUSVString());
|
2016-07-14 07:01:31 +00:00
|
|
|
} else if (mFormData[i].value.IsBlob()) {
|
2016-02-23 23:01:01 +00:00
|
|
|
fs.AddNameBlobOrNullPair(mFormData[i].name,
|
|
|
|
mFormData[i].value.GetAsBlob());
|
2016-07-14 07:01:31 +00:00
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(mFormData[i].value.IsDirectory());
|
|
|
|
fs.AddNameDirectoryPair(mFormData[i].name,
|
|
|
|
mFormData[i].value.GetAsDirectory());
|
2010-02-25 05:58:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fs.GetContentType(aContentType);
|
|
|
|
aCharset.Truncate();
|
2012-09-19 22:15:32 +00:00
|
|
|
*aContentLength = 0;
|
|
|
|
NS_ADDREF(*aBody = fs.GetSubmissionBody(aContentLength));
|
2010-02-25 05:58:18 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|