Bug 1143857 - Add FormData serialize support to Fetch API. r=ehsan

--HG--
extra : rebase_source : e971be3409e5c8de982e8ffcfcc87dcebb4c3867
This commit is contained in:
Nikhil Marathe 2015-03-17 08:32:04 -07:00
parent 9bd0f5b094
commit ac84e104df
8 changed files with 84 additions and 13 deletions

View File

@ -74,6 +74,7 @@ EXPORTS += [
'nsDOMNavigationTiming.h',
'nsDOMString.h',
'nsFocusManager.h',
'nsFormData.h',
'nsFrameMessageManager.h',
'nsGenericDOMDataNode.h',
'nsGkAtomList.h',

View File

@ -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());

View File

@ -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);

View File

@ -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,

View File

@ -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) {

View File

@ -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

View File

@ -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.
}

View File

@ -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 {