mirror of
https://github.com/classilla/tenfourfox.git
synced 2025-08-15 05:27:49 +00:00
#612 (from OlgaTPark/14) M1250987 M1309358 M1394399
This commit is contained in:
@@ -1317,7 +1317,10 @@ nsXMLHttpRequest::IsSafeHeader(const nsACString& header, nsIHttpChannel* httpCha
|
|||||||
if (!NS_IsValidHTTPToken(token)) {
|
if (!NS_IsValidHTTPToken(token)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (header.Equals(token, nsCaseInsensitiveCStringComparator())) {
|
|
||||||
|
if (token.EqualsLiteral("*")) {
|
||||||
|
isSafe = true;
|
||||||
|
} else if (header.Equals(token, nsCaseInsensitiveCStringComparator())) {
|
||||||
isSafe = true;
|
isSafe = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -491,7 +491,8 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
|
|||||||
nsAutoCString statusText;
|
nsAutoCString statusText;
|
||||||
httpChannel->GetResponseStatusText(statusText);
|
httpChannel->GetResponseStatusText(statusText);
|
||||||
|
|
||||||
response = new InternalResponse(responseStatus, statusText);
|
response = new InternalResponse(responseStatus, statusText,
|
||||||
|
mRequest->GetCredentialsMode());
|
||||||
|
|
||||||
RefPtr<FillResponseHeaders> visitor = new FillResponseHeaders(response);
|
RefPtr<FillResponseHeaders> visitor = new FillResponseHeaders(response);
|
||||||
rv = httpChannel->VisitResponseHeaders(visitor);
|
rv = httpChannel->VisitResponseHeaders(visitor);
|
||||||
@@ -511,7 +512,8 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
|
|||||||
result);
|
result);
|
||||||
MOZ_ASSERT(!result.Failed());
|
MOZ_ASSERT(!result.Failed());
|
||||||
} else {
|
} else {
|
||||||
response = new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
|
response = new InternalResponse(200, NS_LITERAL_CSTRING("OK"),
|
||||||
|
mRequest->GetCredentialsMode());
|
||||||
|
|
||||||
ErrorResult result;
|
ErrorResult result;
|
||||||
nsAutoCString contentType;
|
nsAutoCString contentType;
|
||||||
|
@@ -300,7 +300,8 @@ InternalHeaders::BasicHeaders(InternalHeaders* aHeaders)
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
already_AddRefed<InternalHeaders>
|
already_AddRefed<InternalHeaders>
|
||||||
InternalHeaders::CORSHeaders(InternalHeaders* aHeaders)
|
InternalHeaders::CORSHeaders(InternalHeaders* aHeaders,
|
||||||
|
RequestCredentials aCredentialsMode)
|
||||||
{
|
{
|
||||||
RefPtr<InternalHeaders> cors = new InternalHeaders(aHeaders->mGuard);
|
RefPtr<InternalHeaders> cors = new InternalHeaders(aHeaders->mGuard);
|
||||||
ErrorResult result;
|
ErrorResult result;
|
||||||
@@ -309,6 +310,7 @@ InternalHeaders::CORSHeaders(InternalHeaders* aHeaders)
|
|||||||
aHeaders->Get(NS_LITERAL_CSTRING("Access-Control-Expose-Headers"), acExposedNames, result);
|
aHeaders->Get(NS_LITERAL_CSTRING("Access-Control-Expose-Headers"), acExposedNames, result);
|
||||||
MOZ_ASSERT(!result.Failed());
|
MOZ_ASSERT(!result.Failed());
|
||||||
|
|
||||||
|
bool allowAllHeaders = false;
|
||||||
nsAutoTArray<nsCString, 5> exposeNamesArray;
|
nsAutoTArray<nsCString, 5> exposeNamesArray;
|
||||||
nsCCharSeparatedTokenizer exposeTokens(acExposedNames, ',');
|
nsCCharSeparatedTokenizer exposeTokens(acExposedNames, ',');
|
||||||
while (exposeTokens.hasMoreTokens()) {
|
while (exposeTokens.hasMoreTokens()) {
|
||||||
@@ -324,19 +326,27 @@ InternalHeaders::CORSHeaders(InternalHeaders* aHeaders)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (token.EqualsLiteral("*") &&
|
||||||
|
aCredentialsMode != RequestCredentials::Include) {
|
||||||
|
allowAllHeaders = true;
|
||||||
|
}
|
||||||
|
|
||||||
exposeNamesArray.AppendElement(token);
|
exposeNamesArray.AppendElement(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCaseInsensitiveCStringArrayComparator comp;
|
nsCaseInsensitiveCStringArrayComparator comp;
|
||||||
for (uint32_t i = 0; i < aHeaders->mList.Length(); ++i) {
|
for (uint32_t i = 0; i < aHeaders->mList.Length(); ++i) {
|
||||||
const Entry& entry = aHeaders->mList[i];
|
const Entry& entry = aHeaders->mList[i];
|
||||||
if (entry.mName.EqualsASCII("cache-control") ||
|
if (allowAllHeaders) {
|
||||||
entry.mName.EqualsASCII("content-language") ||
|
cors->Append(entry.mName, entry.mValue, result);
|
||||||
entry.mName.EqualsASCII("content-type") ||
|
MOZ_ASSERT(!result.Failed());
|
||||||
entry.mName.EqualsASCII("expires") ||
|
} else if (entry.mName.EqualsASCII("cache-control") ||
|
||||||
entry.mName.EqualsASCII("last-modified") ||
|
entry.mName.EqualsASCII("content-language") ||
|
||||||
entry.mName.EqualsASCII("pragma") ||
|
entry.mName.EqualsASCII("content-type") ||
|
||||||
exposeNamesArray.Contains(entry.mName, comp)) {
|
entry.mName.EqualsASCII("expires") ||
|
||||||
|
entry.mName.EqualsASCII("last-modified") ||
|
||||||
|
entry.mName.EqualsASCII("pragma") ||
|
||||||
|
exposeNamesArray.Contains(entry.mName, comp)) {
|
||||||
cors->Append(entry.mName, entry.mValue, result);
|
cors->Append(entry.mName, entry.mValue, result);
|
||||||
MOZ_ASSERT(!result.Failed());
|
MOZ_ASSERT(!result.Failed());
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
// needed for HeadersGuardEnum.
|
// needed for HeadersGuardEnum.
|
||||||
#include "mozilla/dom/HeadersBinding.h"
|
#include "mozilla/dom/HeadersBinding.h"
|
||||||
|
#include "mozilla/dom/RequestBinding.h"
|
||||||
#include "mozilla/dom/UnionTypes.h"
|
#include "mozilla/dom/UnionTypes.h"
|
||||||
|
|
||||||
#include "nsClassHashtable.h"
|
#include "nsClassHashtable.h"
|
||||||
@@ -103,7 +104,8 @@ public:
|
|||||||
BasicHeaders(InternalHeaders* aHeaders);
|
BasicHeaders(InternalHeaders* aHeaders);
|
||||||
|
|
||||||
static already_AddRefed<InternalHeaders>
|
static already_AddRefed<InternalHeaders>
|
||||||
CORSHeaders(InternalHeaders* aHeaders);
|
CORSHeaders(InternalHeaders* aHeaders,
|
||||||
|
RequestCredentials mCredentialsMode = RequestCredentials::Omit);
|
||||||
|
|
||||||
void
|
void
|
||||||
GetEntries(nsTArray<InternalHeaders::Entry>& aEntries) const;
|
GetEntries(nsTArray<InternalHeaders::Entry>& aEntries) const;
|
||||||
|
@@ -16,11 +16,14 @@
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
InternalResponse::InternalResponse(uint16_t aStatus, const nsACString& aStatusText)
|
InternalResponse::InternalResponse(uint16_t aStatus,
|
||||||
|
const nsACString& aStatusText,
|
||||||
|
RequestCredentials aCredentialsMode)
|
||||||
: mType(ResponseType::Default)
|
: mType(ResponseType::Default)
|
||||||
, mStatus(aStatus)
|
, mStatus(aStatus)
|
||||||
, mStatusText(aStatusText)
|
, mStatusText(aStatusText)
|
||||||
, mHeaders(new InternalHeaders(HeadersGuardEnum::Response))
|
, mHeaders(new InternalHeaders(HeadersGuardEnum::Response))
|
||||||
|
, mCredentialsMode(aCredentialsMode)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +79,7 @@ InternalResponse::CORSResponse()
|
|||||||
MOZ_ASSERT(!mWrappedResponse, "Can't CORSResponse a already wrapped response");
|
MOZ_ASSERT(!mWrappedResponse, "Can't CORSResponse a already wrapped response");
|
||||||
RefPtr<InternalResponse> cors = CreateIncompleteCopy();
|
RefPtr<InternalResponse> cors = CreateIncompleteCopy();
|
||||||
cors->mType = ResponseType::Cors;
|
cors->mType = ResponseType::Cors;
|
||||||
cors->mHeaders = InternalHeaders::CORSHeaders(Headers());
|
cors->mHeaders = InternalHeaders::CORSHeaders(Headers(), mCredentialsMode);
|
||||||
cors->mWrappedResponse = this;
|
cors->mWrappedResponse = this;
|
||||||
return cors.forget();
|
return cors.forget();
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,9 @@
|
|||||||
#include "nsIInputStream.h"
|
#include "nsIInputStream.h"
|
||||||
#include "nsISupportsImpl.h"
|
#include "nsISupportsImpl.h"
|
||||||
|
|
||||||
|
#include "mozilla/dom/InternalHeaders.h"
|
||||||
#include "mozilla/dom/ResponseBinding.h"
|
#include "mozilla/dom/ResponseBinding.h"
|
||||||
|
#include "mozilla/dom/RequestBinding.h"
|
||||||
#include "mozilla/dom/ChannelInfo.h"
|
#include "mozilla/dom/ChannelInfo.h"
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
|
|
||||||
@@ -30,7 +32,8 @@ class InternalResponse final
|
|||||||
public:
|
public:
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalResponse)
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalResponse)
|
||||||
|
|
||||||
InternalResponse(uint16_t aStatus, const nsACString& aStatusText);
|
InternalResponse(uint16_t aStatus, const nsACString& aStatusText,
|
||||||
|
RequestCredentials aCredentialsMode = RequestCredentials::Omit);
|
||||||
|
|
||||||
already_AddRefed<InternalResponse> Clone();
|
already_AddRefed<InternalResponse> Clone();
|
||||||
|
|
||||||
@@ -241,6 +244,7 @@ private:
|
|||||||
nsCOMPtr<nsIInputStream> mBody;
|
nsCOMPtr<nsIInputStream> mBody;
|
||||||
ChannelInfo mChannelInfo;
|
ChannelInfo mChannelInfo;
|
||||||
UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
|
UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
|
||||||
|
RequestCredentials mCredentialsMode;
|
||||||
|
|
||||||
// For filtered responses.
|
// For filtered responses.
|
||||||
// Cache, and SW interception should always serialize/access the underlying
|
// Cache, and SW interception should always serialize/access the underlying
|
||||||
|
@@ -275,7 +275,7 @@ Request::Constructor(const GlobalObject& aGlobal,
|
|||||||
|
|
||||||
request->SetURL(NS_ConvertUTF16toUTF8(requestURL));
|
request->SetURL(NS_ConvertUTF16toUTF8(requestURL));
|
||||||
fallbackMode = RequestMode::Cors;
|
fallbackMode = RequestMode::Cors;
|
||||||
fallbackCredentials = RequestCredentials::Omit;
|
fallbackCredentials = RequestCredentials::Same_origin;
|
||||||
fallbackCache = RequestCache::Default;
|
fallbackCache = RequestCache::Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,7 +365,8 @@ Request::Constructor(const GlobalObject& aGlobal,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aInit.mBody.WasPassed() || temporaryBody) {
|
if ((aInit.mBody.WasPassed() && !aInit.mBody.Value().IsNull()) ||
|
||||||
|
temporaryBody) {
|
||||||
// HEAD and GET are not allowed to have a body.
|
// HEAD and GET are not allowed to have a body.
|
||||||
nsAutoCString method;
|
nsAutoCString method;
|
||||||
request->GetMethod(method);
|
request->GetMethod(method);
|
||||||
@@ -377,29 +378,34 @@ Request::Constructor(const GlobalObject& aGlobal,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (aInit.mBody.WasPassed()) {
|
if (aInit.mBody.WasPassed()) {
|
||||||
const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& bodyInit = aInit.mBody.Value();
|
const Nullable<OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams>& bodyInitNullable =
|
||||||
nsCOMPtr<nsIInputStream> stream;
|
aInit.mBody.Value();
|
||||||
nsAutoCString contentType;
|
if (!bodyInitNullable.IsNull()) {
|
||||||
aRv = ExtractByteStreamFromBody(bodyInit,
|
const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& bodyInit =
|
||||||
getter_AddRefs(stream), contentType);
|
bodyInitNullable.Value();
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
nsCOMPtr<nsIInputStream> stream;
|
||||||
return nullptr;
|
nsAutoCString contentType;
|
||||||
|
aRv = ExtractByteStreamFromBody(bodyInit,
|
||||||
|
getter_AddRefs(stream), contentType);
|
||||||
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
temporaryBody = stream;
|
||||||
|
|
||||||
|
if (!contentType.IsVoid() &&
|
||||||
|
!requestHeaders->Has(NS_LITERAL_CSTRING("Content-Type"), aRv)) {
|
||||||
|
requestHeaders->Append(NS_LITERAL_CSTRING("Content-Type"),
|
||||||
|
contentType, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
request->ClearCreatedByFetchEvent();
|
||||||
|
request->SetBody(temporaryBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
temporaryBody = stream;
|
|
||||||
|
|
||||||
if (!contentType.IsVoid() &&
|
|
||||||
!requestHeaders->Has(NS_LITERAL_CSTRING("Content-Type"), aRv)) {
|
|
||||||
requestHeaders->Append(NS_LITERAL_CSTRING("Content-Type"),
|
|
||||||
contentType, aRv);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
request->ClearCreatedByFetchEvent();
|
|
||||||
request->SetBody(temporaryBody);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Request> domRequest = new Request(global, request);
|
RefPtr<Request> domRequest = new Request(global, request);
|
||||||
|
@@ -38,7 +38,7 @@ Request implements Body;
|
|||||||
dictionary RequestInit {
|
dictionary RequestInit {
|
||||||
ByteString method;
|
ByteString method;
|
||||||
HeadersInit headers;
|
HeadersInit headers;
|
||||||
BodyInit body;
|
BodyInit? body;
|
||||||
RequestMode mode;
|
RequestMode mode;
|
||||||
RequestCredentials credentials;
|
RequestCredentials credentials;
|
||||||
RequestCache cache;
|
RequestCache cache;
|
||||||
|
@@ -1272,7 +1272,11 @@ nsCORSPreflightListener::CheckPreflightRequestApproved(nsIRequest* aRequest)
|
|||||||
NS_ConvertUTF8toUTF16(method).get());
|
NS_ConvertUTF8toUTF16(method).get());
|
||||||
return NS_ERROR_DOM_BAD_URI;
|
return NS_ERROR_DOM_BAD_URI;
|
||||||
}
|
}
|
||||||
foundMethod |= mPreflightMethod.Equals(method);
|
if (method.EqualsLiteral("*") && !mWithCredentials) {
|
||||||
|
foundMethod = true;
|
||||||
|
} else {
|
||||||
|
foundMethod |= mPreflightMethod.Equals(method);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!foundMethod) {
|
if (!foundMethod) {
|
||||||
LogBlockedRequest(aRequest, "CORSMethodNotFound", nullptr);
|
LogBlockedRequest(aRequest, "CORSMethodNotFound", nullptr);
|
||||||
|
Reference in New Issue
Block a user