зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1109751 - Request and Response constructors should set mime type. r=baku
--HG-- extra : rebase_source : 8efaf2edd3f3c5d1cd7c49615ac735805a4f4e84
This commit is contained in:
Родитель
9b5f6b134f
Коммит
c9908ee8be
|
@ -1525,7 +1525,17 @@ FetchBody<Derived>::ContinueConsumeBody(nsresult aStatus, uint32_t aResultLength
|
|||
data.Adopt(reinterpret_cast<char*>(aResult), aResultLength);
|
||||
autoFree.Reset();
|
||||
|
||||
if (StringBeginsWith(mMimeType, NS_LITERAL_CSTRING("multipart/form-data"))) {
|
||||
NS_NAMED_LITERAL_CSTRING(formDataMimeType, NS_LITERAL_CSTRING("multipart/form-data"));
|
||||
|
||||
// Allow semicolon separated boundary/encoding suffix like multipart/form-data; boundary=
|
||||
// but disallow multipart/form-datafoobar.
|
||||
bool isValidFormDataMimeType = StringBeginsWith(mMimeType, formDataMimeType);
|
||||
|
||||
if (isValidFormDataMimeType && mMimeType.Length() > formDataMimeType.Length()) {
|
||||
isValidFormDataMimeType = mMimeType[formDataMimeType.Length()] == ';';
|
||||
}
|
||||
|
||||
if (isValidFormDataMimeType) {
|
||||
FormDataParser parser(mMimeType, data, DerivedClass()->GetParentObject());
|
||||
if (!parser.Parse()) {
|
||||
ErrorResult result;
|
||||
|
@ -1537,18 +1547,26 @@ FetchBody<Derived>::ContinueConsumeBody(nsresult aStatus, uint32_t aResultLength
|
|||
nsRefPtr<nsFormData> fd = parser.FormData();
|
||||
MOZ_ASSERT(fd);
|
||||
localPromise->MaybeResolve(fd);
|
||||
} else if (StringBeginsWith(mMimeType,
|
||||
NS_LITERAL_CSTRING("application/x-www-form-urlencoded"))) {
|
||||
nsRefPtr<URLSearchParams> params = new URLSearchParams();
|
||||
params->ParseInput(data, /* aObserver */ nullptr);
|
||||
|
||||
nsRefPtr<nsFormData> fd = new nsFormData(DerivedClass()->GetParentObject());
|
||||
params->ForEach(FillFormData, static_cast<void*>(fd));
|
||||
localPromise->MaybeResolve(fd);
|
||||
} else {
|
||||
ErrorResult result;
|
||||
result.ThrowTypeError(MSG_BAD_FORMDATA);
|
||||
localPromise->MaybeReject(result);
|
||||
NS_NAMED_LITERAL_CSTRING(urlDataMimeType, NS_LITERAL_CSTRING("application/x-www-form-urlencoded"));
|
||||
bool isValidUrlEncodedMimeType = StringBeginsWith(mMimeType, urlDataMimeType);
|
||||
|
||||
if (isValidUrlEncodedMimeType && mMimeType.Length() > urlDataMimeType.Length()) {
|
||||
isValidUrlEncodedMimeType = mMimeType[urlDataMimeType.Length()] == ';';
|
||||
}
|
||||
|
||||
if (isValidUrlEncodedMimeType) {
|
||||
nsRefPtr<URLSearchParams> params = new URLSearchParams();
|
||||
params->ParseInput(data, /* aObserver */ nullptr);
|
||||
|
||||
nsRefPtr<nsFormData> fd = new nsFormData(DerivedClass()->GetParentObject());
|
||||
params->ForEach(FillFormData, static_cast<void*>(fd));
|
||||
localPromise->MaybeResolve(fd);
|
||||
} else {
|
||||
ErrorResult result;
|
||||
result.ThrowTypeError(MSG_BAD_FORMDATA);
|
||||
localPromise->MaybeReject(result);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1626,15 +1644,15 @@ FetchBody<Response>::ConsumeBody(ConsumeType aType, ErrorResult& aRv);
|
|||
|
||||
template <class Derived>
|
||||
void
|
||||
FetchBody<Derived>::SetMimeType(ErrorResult& aRv)
|
||||
FetchBody<Derived>::SetMimeType()
|
||||
{
|
||||
// Extract mime type.
|
||||
ErrorResult result;
|
||||
nsTArray<nsCString> contentTypeValues;
|
||||
MOZ_ASSERT(DerivedClass()->GetInternalHeaders());
|
||||
DerivedClass()->GetInternalHeaders()->GetAll(NS_LITERAL_CSTRING("Content-Type"), contentTypeValues, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
DerivedClass()->GetInternalHeaders()->GetAll(NS_LITERAL_CSTRING("Content-Type"),
|
||||
contentTypeValues, result);
|
||||
MOZ_ALWAYS_TRUE(!result.Failed());
|
||||
|
||||
// HTTP ABNF states Content-Type may have only one value.
|
||||
// This is from the "parse a header value" of the fetch spec.
|
||||
|
@ -1646,10 +1664,10 @@ FetchBody<Derived>::SetMimeType(ErrorResult& aRv)
|
|||
|
||||
template
|
||||
void
|
||||
FetchBody<Request>::SetMimeType(ErrorResult& aRv);
|
||||
FetchBody<Request>::SetMimeType();
|
||||
|
||||
template
|
||||
void
|
||||
FetchBody<Response>::SetMimeType(ErrorResult& aRv);
|
||||
FetchBody<Response>::SetMimeType();
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -160,7 +160,7 @@ protected:
|
|||
virtual ~FetchBody();
|
||||
|
||||
void
|
||||
SetMimeType(ErrorResult& aRv);
|
||||
SetMimeType();
|
||||
private:
|
||||
enum ConsumeType
|
||||
{
|
||||
|
|
|
@ -34,6 +34,7 @@ Request::Request(nsIGlobalObject* aOwner, InternalRequest* aRequest)
|
|||
, mOwner(aOwner)
|
||||
, mRequest(aRequest)
|
||||
{
|
||||
SetMimeType();
|
||||
}
|
||||
|
||||
Request::~Request()
|
||||
|
@ -264,7 +265,7 @@ Request::Constructor(const GlobalObject& aGlobal,
|
|||
}
|
||||
|
||||
nsRefPtr<Request> domRequest = new Request(global, request);
|
||||
domRequest->SetMimeType(aRv);
|
||||
domRequest->SetMimeType();
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ Response::Response(nsIGlobalObject* aGlobal, InternalResponse* aInternalResponse
|
|||
, mOwner(aGlobal)
|
||||
, mInternalResponse(aInternalResponse)
|
||||
{
|
||||
SetMimeType();
|
||||
}
|
||||
|
||||
Response::~Response()
|
||||
|
@ -188,7 +189,7 @@ Response::Constructor(const GlobalObject& aGlobal,
|
|||
}
|
||||
}
|
||||
|
||||
r->SetMimeType(aRv);
|
||||
r->SetMimeType();
|
||||
return r.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -337,8 +337,8 @@ function testFormDataBodyExtraction() {
|
|||
|
||||
var req = new Request("", { method: 'POST', body: params });
|
||||
var p1 = req.formData().then(function(fd) {
|
||||
ok(fd.has("item"));
|
||||
ok(fd.has("feature"));
|
||||
ok(fd.has("item"), "Has entry 'item'.");
|
||||
ok(fd.has("feature"), "Has entry 'feature'.");
|
||||
var entries = fd.getAll("quantity");
|
||||
is(entries.length, 2, "Entries with same name are correctly handled.");
|
||||
is(entries[0], "700", "Entries with same name are correctly handled.");
|
||||
|
@ -351,9 +351,9 @@ function testFormDataBodyExtraction() {
|
|||
f1.append("blob", new Blob([text]));
|
||||
var r2 = new Request("", { method: 'post', body: f1 });
|
||||
var p2 = r2.formData().then(function(fd) {
|
||||
ok(fd.has("key"));
|
||||
ok(fd.has("foo"));
|
||||
ok(fd.has("blob"));
|
||||
ok(fd.has("key"), "Has entry 'key'.");
|
||||
ok(fd.has("foo"), "Has entry 'foo'.");
|
||||
ok(fd.has("blob"), "Has entry 'blob'.");
|
||||
var entries = fd.getAll("blob");
|
||||
is(entries.length, 1, "getAll returns all items.");
|
||||
is(entries[0].name, "blob", "Filename should be blob.");
|
||||
|
@ -363,13 +363,13 @@ function testFormDataBodyExtraction() {
|
|||
f1.set("key", new File([ws], 'file name has spaces.txt', { type: 'new/lines' }));
|
||||
var r3 = new Request("", { method: 'post', body: f1 });
|
||||
var p3 = r3.formData().then(function(fd) {
|
||||
ok(fd.has("foo"));
|
||||
ok(fd.has("blob"));
|
||||
ok(fd.has("foo"), "Has entry 'foo'.");
|
||||
ok(fd.has("blob"), "Has entry 'blob'.");
|
||||
var entries = fd.getAll("blob");
|
||||
is(entries.length, 1, "getAll returns all items.");
|
||||
is(entries[0].name, "blob", "Filename should be blob.");
|
||||
|
||||
ok(fd.has("key"));
|
||||
ok(fd.has("key"), "Has entry 'key'.");
|
||||
var f = fd.get("key");
|
||||
ok(f instanceof File, "entry should be a File.");
|
||||
is(f.name, "file name has spaces.txt", "File name should match.");
|
||||
|
@ -380,7 +380,30 @@ function testFormDataBodyExtraction() {
|
|||
});
|
||||
});
|
||||
|
||||
return Promise.all([p1, p2, p3]);
|
||||
// Override header and ensure parse fails.
|
||||
var boundary = "1234567891011121314151617";
|
||||
var body = boundary +
|
||||
'\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
|
||||
boundary + '-';
|
||||
|
||||
var r4 = new Request("", { method: 'post', body: body, headers: {
|
||||
"Content-Type": "multipart/form-datafoobar; boundary="+boundary,
|
||||
}});
|
||||
var p4 = r4.formData().then(function() {
|
||||
ok(false, "Invalid mimetype should fail.");
|
||||
}, function() {
|
||||
ok(true, "Invalid mimetype should fail.");
|
||||
});
|
||||
|
||||
var r5 = new Request("", { method: 'POST', body: params, headers: {
|
||||
"Content-Type": "application/x-www-form-urlencodedfoobar",
|
||||
}});
|
||||
var p5 = r5.formData().then(function() {
|
||||
ok(false, "Invalid mimetype should fail.");
|
||||
}, function() {
|
||||
ok(true, "Invalid mimetype should fail.");
|
||||
});
|
||||
return Promise.all([p1, p2, p3, p4]);
|
||||
}
|
||||
|
||||
// mode cannot be set to "CORS-with-forced-preflight" from javascript.
|
||||
|
|
Загрузка…
Ссылка в новой задаче