mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-25 03:05:34 +00:00
f51e8c8dbd
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
157 lines
4.7 KiB
C++
157 lines
4.7 KiB
C++
/* 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/. */
|
|
|
|
#ifndef nsFormData_h__
|
|
#define nsFormData_h__
|
|
|
|
#include "mozilla/Attributes.h"
|
|
#include "nsIDOMFormData.h"
|
|
#include "nsIXMLHttpRequest.h"
|
|
#include "nsFormSubmission.h"
|
|
#include "nsWrapperCache.h"
|
|
#include "nsTArray.h"
|
|
#include "mozilla/ErrorResult.h"
|
|
#include "mozilla/dom/BindingDeclarations.h"
|
|
#include "mozilla/dom/FormDataBinding.h"
|
|
|
|
namespace mozilla {
|
|
class ErrorResult;
|
|
|
|
namespace dom {
|
|
class File;
|
|
class HTMLFormElement;
|
|
class GlobalObject;
|
|
} // namespace dom
|
|
} // namespace mozilla
|
|
|
|
class nsFormData MOZ_FINAL : public nsIDOMFormData,
|
|
public nsIXHRSendable,
|
|
public nsFormSubmission,
|
|
public nsWrapperCache
|
|
{
|
|
private:
|
|
~nsFormData() {}
|
|
|
|
typedef mozilla::dom::File File;
|
|
struct FormDataTuple
|
|
{
|
|
nsString name;
|
|
nsString stringValue;
|
|
nsRefPtr<File> fileValue;
|
|
bool valueIsFile;
|
|
};
|
|
|
|
// Returns the FormDataTuple to modify. This may be null, in which case
|
|
// no element with aName was found.
|
|
FormDataTuple*
|
|
RemoveAllOthersAndGetFirstFormDataTuple(const nsAString& aName);
|
|
|
|
void SetNameValuePair(FormDataTuple* aData,
|
|
const nsAString& aName,
|
|
const nsAString& aValue)
|
|
{
|
|
MOZ_ASSERT(aData);
|
|
aData->name = aName;
|
|
aData->stringValue = aValue;
|
|
aData->valueIsFile = false;
|
|
}
|
|
|
|
void SetNameFilePair(FormDataTuple* aData,
|
|
const nsAString& aName,
|
|
File* aBlob)
|
|
{
|
|
MOZ_ASSERT(aData);
|
|
aData->name = aName;
|
|
aData->fileValue = aBlob;
|
|
aData->valueIsFile = true;
|
|
}
|
|
|
|
void ExtractValue(const FormDataTuple& aTuple,
|
|
mozilla::dom::OwningFileOrUSVString* aOutValue);
|
|
public:
|
|
explicit nsFormData(nsISupports* aOwner = nullptr);
|
|
|
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsFormData,
|
|
nsIDOMFormData)
|
|
|
|
NS_DECL_NSIDOMFORMDATA
|
|
NS_DECL_NSIXHRSENDABLE
|
|
|
|
// nsWrapperCache
|
|
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
|
|
|
// WebIDL
|
|
nsISupports*
|
|
GetParentObject() const
|
|
{
|
|
return mOwner;
|
|
}
|
|
static already_AddRefed<nsFormData>
|
|
Constructor(const mozilla::dom::GlobalObject& aGlobal,
|
|
const mozilla::dom::Optional<mozilla::dom::NonNull<mozilla::dom::HTMLFormElement> >& aFormElement,
|
|
mozilla::ErrorResult& aRv);
|
|
void Append(const nsAString& aName, const nsAString& aValue);
|
|
void Append(const nsAString& aName, File& aBlob,
|
|
const mozilla::dom::Optional<nsAString>& aFilename);
|
|
void Delete(const nsAString& aName);
|
|
void Get(const nsAString& aName, mozilla::dom::Nullable<mozilla::dom::OwningFileOrUSVString>& aOutValue);
|
|
void GetAll(const nsAString& aName, nsTArray<mozilla::dom::OwningFileOrUSVString>& aValues);
|
|
bool Has(const nsAString& aName);
|
|
void Set(const nsAString& aName, File& aBlob,
|
|
const mozilla::dom::Optional<nsAString>& aFilename);
|
|
void Set(const nsAString& aName, const nsAString& aValue);
|
|
|
|
// nsFormSubmission
|
|
virtual nsresult GetEncodedSubmission(nsIURI* aURI,
|
|
nsIInputStream** aPostDataStream) MOZ_OVERRIDE;
|
|
virtual nsresult AddNameValuePair(const nsAString& aName,
|
|
const nsAString& aValue) MOZ_OVERRIDE
|
|
{
|
|
FormDataTuple* data = mFormData.AppendElement();
|
|
SetNameValuePair(data, aName, aValue);
|
|
return NS_OK;
|
|
}
|
|
virtual nsresult AddNameFilePair(const nsAString& aName,
|
|
File* aBlob) MOZ_OVERRIDE
|
|
{
|
|
FormDataTuple* data = mFormData.AppendElement();
|
|
SetNameFilePair(data, aName, aBlob);
|
|
return NS_OK;
|
|
}
|
|
|
|
typedef bool (*FormDataEntryCallback)(const nsString& aName, bool aIsFile,
|
|
const nsString& aValue,
|
|
File* aFile, void* aClosure);
|
|
|
|
uint32_t
|
|
Length() const
|
|
{
|
|
return mFormData.Length();
|
|
}
|
|
|
|
// Stops iteration and returns false if any invocation of callback returns
|
|
// false. Returns true otherwise.
|
|
bool
|
|
ForEach(FormDataEntryCallback aFunc, void* aClosure)
|
|
{
|
|
for (uint32_t i = 0; i < mFormData.Length(); ++i) {
|
|
FormDataTuple& tuple = mFormData[i];
|
|
if (!aFunc(tuple.name, tuple.valueIsFile, tuple.stringValue,
|
|
tuple.fileValue, aClosure)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
nsCOMPtr<nsISupports> mOwner;
|
|
|
|
nsTArray<FormDataTuple> mFormData;
|
|
};
|
|
|
|
#endif // nsFormData_h__
|