mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Bug 1143857 - Add FormData serialize support to Fetch API. r=ehsan
--HG-- extra : rebase_source : e971be3409e5c8de982e8ffcfcc87dcebb4c3867
This commit is contained in:
parent
9bd0f5b094
commit
ac84e104df
@ -74,6 +74,7 @@ EXPORTS += [
|
||||
'nsDOMNavigationTiming.h',
|
||||
'nsDOMString.h',
|
||||
'nsFocusManager.h',
|
||||
'nsFormData.h',
|
||||
'nsFrameMessageManager.h',
|
||||
'nsGenericDOMDataNode.h',
|
||||
'nsGkAtomList.h',
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "InternalRequest.h"
|
||||
#include "InternalResponse.h"
|
||||
|
||||
#include "nsFormData.h"
|
||||
#include "WorkerPrivate.h"
|
||||
#include "WorkerRunnable.h"
|
||||
#include "WorkerScope.h"
|
||||
@ -452,6 +453,16 @@ ExtractFromBlob(const File& aFile, nsIInputStream** aStream,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
ExtractFromFormData(nsFormData& aFormData, nsIInputStream** aStream,
|
||||
nsCString& aContentType)
|
||||
{
|
||||
uint64_t unusedContentLength;
|
||||
nsAutoCString unusedCharset;
|
||||
return aFormData.GetSendInfo(aStream, &unusedContentLength,
|
||||
aContentType, unusedCharset);
|
||||
}
|
||||
|
||||
nsresult
|
||||
ExtractFromUSVString(const nsString& aStr,
|
||||
nsIInputStream** aStream,
|
||||
@ -502,7 +513,7 @@ ExtractFromURLSearchParams(const URLSearchParams& aParams,
|
||||
} // anonymous namespace
|
||||
|
||||
nsresult
|
||||
ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams& aBodyInit,
|
||||
ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit,
|
||||
nsIInputStream** aStream,
|
||||
nsCString& aContentType)
|
||||
{
|
||||
@ -517,6 +528,9 @@ ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStr
|
||||
} else if (aBodyInit.IsBlob()) {
|
||||
const File& blob = aBodyInit.GetAsBlob();
|
||||
return ExtractFromBlob(blob, aStream, aContentType);
|
||||
} else if (aBodyInit.IsFormData()) {
|
||||
nsFormData& form = aBodyInit.GetAsFormData();
|
||||
return ExtractFromFormData(form, aStream, aContentType);
|
||||
} else if (aBodyInit.IsUSVString()) {
|
||||
nsAutoString str;
|
||||
str.Assign(aBodyInit.GetAsUSVString());
|
||||
@ -531,7 +545,7 @@ ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStr
|
||||
}
|
||||
|
||||
nsresult
|
||||
ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams& aBodyInit,
|
||||
ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit,
|
||||
nsIInputStream** aStream,
|
||||
nsCString& aContentType)
|
||||
{
|
||||
@ -546,6 +560,9 @@ ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrU
|
||||
} else if (aBodyInit.IsBlob()) {
|
||||
const File& blob = aBodyInit.GetAsBlob();
|
||||
return ExtractFromBlob(blob, aStream, aContentType);
|
||||
} else if (aBodyInit.IsFormData()) {
|
||||
nsFormData& form = aBodyInit.GetAsFormData();
|
||||
return ExtractFromFormData(form, aStream, aContentType);
|
||||
} else if (aBodyInit.IsUSVString()) {
|
||||
nsAutoString str;
|
||||
str.Assign(aBodyInit.GetAsUSVString());
|
||||
|
@ -26,9 +26,9 @@ class nsIGlobalObject;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams;
|
||||
class ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams;
|
||||
class InternalRequest;
|
||||
class OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams;
|
||||
class OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams;
|
||||
class RequestOrUSVString;
|
||||
|
||||
namespace workers {
|
||||
@ -48,7 +48,7 @@ UpdateRequestReferrer(nsIGlobalObject* aGlobal, InternalRequest* aRequest);
|
||||
* Stores content type in out param aContentType.
|
||||
*/
|
||||
nsresult
|
||||
ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams& aBodyInit,
|
||||
ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit,
|
||||
nsIInputStream** aStream,
|
||||
nsCString& aContentType);
|
||||
|
||||
@ -56,7 +56,7 @@ ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStr
|
||||
* Non-owning version.
|
||||
*/
|
||||
nsresult
|
||||
ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams& aBodyInit,
|
||||
ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit,
|
||||
nsIInputStream** aStream,
|
||||
nsCString& aContentType);
|
||||
|
||||
|
@ -228,7 +228,7 @@ Request::Constructor(const GlobalObject& aGlobal,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams& bodyInit = aInit.mBody.Value();
|
||||
const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& bodyInit = aInit.mBody.Value();
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
nsCString contentType;
|
||||
aRv = ExtractByteStreamFromBody(bodyInit,
|
||||
|
@ -99,7 +99,7 @@ Response::Redirect(const GlobalObject& aGlobal, const nsAString& aUrl,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Optional<ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams> body;
|
||||
Optional<ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams> body;
|
||||
ResponseInit init;
|
||||
init.mStatus = aStatus;
|
||||
nsRefPtr<Response> r = Response::Constructor(aGlobal, body, init, aRv);
|
||||
@ -120,7 +120,7 @@ Response::Redirect(const GlobalObject& aGlobal, const nsAString& aUrl,
|
||||
|
||||
/*static*/ already_AddRefed<Response>
|
||||
Response::Constructor(const GlobalObject& aGlobal,
|
||||
const Optional<ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams>& aBody,
|
||||
const Optional<ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams>& aBody,
|
||||
const ResponseInit& aInit, ErrorResult& aRv)
|
||||
{
|
||||
if (aInit.mStatus < 200 || aInit.mStatus > 599) {
|
||||
|
@ -103,7 +103,7 @@ public:
|
||||
|
||||
static already_AddRefed<Response>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
const Optional<ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams>& aBody,
|
||||
const Optional<ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams>& aBody,
|
||||
const ResponseInit& aInit, ErrorResult& rv);
|
||||
|
||||
nsIGlobalObject* GetParentObject() const
|
||||
|
@ -134,6 +134,60 @@ function testBlob() {
|
||||
});
|
||||
}
|
||||
|
||||
// This test is a copy of dom/html/test/formData_test.js testSend() modified to
|
||||
// use the fetch API. Please change this if you change that.
|
||||
function testFormDataSend() {
|
||||
var file, blob = new Blob(['hey'], {type: 'text/plain'});
|
||||
|
||||
var fd = new FormData();
|
||||
fd.append("string", "hey");
|
||||
fd.append("empty", blob);
|
||||
fd.append("explicit", blob, "explicit-file-name");
|
||||
fd.append("explicit-empty", blob, "");
|
||||
file = new File([blob], 'testname', {type: 'text/plain'});
|
||||
fd.append("file-name", file);
|
||||
file = new File([blob], '', {type: 'text/plain'});
|
||||
fd.append("empty-file-name", file);
|
||||
file = new File([blob], 'testname', {type: 'text/plain'});
|
||||
fd.append("file-name-overwrite", file, "overwrite");
|
||||
|
||||
var req = new Request("/tests/dom/html/test/form_submit_server.sjs", {
|
||||
method: 'POST',
|
||||
body: fd,
|
||||
});
|
||||
|
||||
return fetch(req).then((r) => {
|
||||
ok(r.status, 200, "status should match");
|
||||
return r.json().then((response) => {
|
||||
for (var entry of response) {
|
||||
if (entry.headers['Content-Disposition'] != 'form-data; name="string"') {
|
||||
is(entry.headers['Content-Type'], 'text/plain');
|
||||
}
|
||||
|
||||
is(entry.body, 'hey');
|
||||
}
|
||||
|
||||
is(response[1].headers['Content-Disposition'],
|
||||
'form-data; name="empty"; filename="blob"');
|
||||
|
||||
is(response[2].headers['Content-Disposition'],
|
||||
'form-data; name="explicit"; filename="explicit-file-name"');
|
||||
|
||||
is(response[3].headers['Content-Disposition'],
|
||||
'form-data; name="explicit-empty"; filename=""');
|
||||
|
||||
is(response[4].headers['Content-Disposition'],
|
||||
'form-data; name="file-name"; filename="testname"');
|
||||
|
||||
is(response[5].headers['Content-Disposition'],
|
||||
'form-data; name="empty-file-name"; filename=""');
|
||||
|
||||
is(response[6].headers['Content-Disposition'],
|
||||
'form-data; name="file-name-overwrite"; filename="overwrite"');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
return Promise.resolve()
|
||||
.then(testURL)
|
||||
@ -141,5 +195,6 @@ function runTest() {
|
||||
.then(testRequestGET)
|
||||
.then(testResponses)
|
||||
.then(testBlob)
|
||||
.then(testFormDataSend)
|
||||
// Put more promise based tests here.
|
||||
}
|
||||
|
@ -8,9 +8,7 @@
|
||||
*/
|
||||
|
||||
typedef object JSON;
|
||||
// FIXME(nsm): Bug 739173: FormData is not available in workers.
|
||||
// typedef (ArrayBuffer or ArrayBufferView or Blob or FormData or USVString or URLSearchParams) BodyInit;
|
||||
typedef (ArrayBuffer or ArrayBufferView or Blob or USVString or URLSearchParams) BodyInit;
|
||||
typedef (ArrayBuffer or ArrayBufferView or Blob or FormData or USVString or URLSearchParams) BodyInit;
|
||||
|
||||
[NoInterfaceObject, Exposed=(Window,Worker)]
|
||||
interface Body {
|
||||
|
Loading…
Reference in New Issue
Block a user