/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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/. */
Request::Request(nsIGlobalObject* aOwner, SafeRefPtr<InternalRequest> aRequest,
AbortSignal* aSignal)
: FetchBody<Request>(aOwner), mRequest(std::move(aRequest)) {
MOZ_ASSERT(mRequest->Headers()->Guard() == HeadersGuardEnum::Immutable ||
mRequest->Headers()->Guard() == HeadersGuardEnum::Request ||
mRequest->Headers()->Guard() == HeadersGuardEnum::Request_no_cors); if (aSignal) { // If we don't have a signal as argument, we will create it when required by // content, otherwise the Request's signal must follow what has been passed.
AutoTArray<OwningNonNull<AbortSignal>, 1> array{OwningNonNull(*aSignal)};
mSignal = AbortSignal::Any(aOwner, mozilla::Span{array});
}
}
void GetRequestURL(nsIGlobalObject* aGlobal, const nsACString& aInput,
nsACString& aRequestURL, nsACString& aURLfragment,
ErrorResult& aRv) {
nsCOMPtr<nsIURI> resolvedURI = ParseURL(aGlobal, aInput, aRv); if (aRv.Failed()) { return;
} // This fails with URIs with weird protocols, even when they are valid, // so we ignore the failure
nsAutoCString credentials;
Unused << resolvedURI->GetUserPass(credentials); if (!credentials.IsEmpty()) {
aRv.ThrowTypeError<MSG_URL_HAS_CREDENTIALS>(aInput); return;
}
nsCOMPtr<nsIURI> resolvedURIClone;
aRv = NS_GetURIWithoutRef(resolvedURI, getter_AddRefs(resolvedURIClone)); if (NS_WARN_IF(aRv.Failed())) { return;
}
aRv = resolvedURIClone->GetSpec(aRequestURL); if (NS_WARN_IF(aRv.Failed())) { return;
}
// Get the fragment from nsIURI.
aRv = resolvedURI->GetRef(aURLfragment); if (NS_WARN_IF(aRv.Failed())) { return;
}
}
} // namespace
if (mode.isSome()) {
request->SetMode(mode.value());
}
if (credentials.isSome()) {
request->SetCredentialsMode(credentials.value());
}
if (cache.isSome()) { if (cache.value() == RequestCache::Only_if_cached &&
request->Mode() != RequestMode::Same_origin) {
aRv.ThrowTypeError<MSG_ONLY_IF_CACHED_WITHOUT_SAME_ORIGIN>(
GetEnumString(request->Mode())); return nullptr;
}
request->SetCacheMode(cache.value());
}
if (aInit.mRedirect.WasPassed()) {
request->SetRedirectMode(aInit.mRedirect.Value());
}
if (aInit.mIntegrity.WasPassed()) {
request->SetIntegrity(aInit.mIntegrity.Value());
}
if (aInit.mKeepalive.WasPassed()) {
request->SetKeepalive(aInit.mKeepalive.Value());
}
if (aInit.mMozErrors.WasPassed() && aInit.mMozErrors.Value()) {
request->SetMozErrors();
}
if (aInit.mTriggeringPrincipal.WasPassed() &&
aInit.mTriggeringPrincipal.Value()) {
request->SetTriggeringPrincipal(aInit.mTriggeringPrincipal.Value());
}
// Request constructor step 14. if (aInit.mMethod.WasPassed()) {
nsAutoCString method(aInit.mMethod.Value());
// Step 14.1. Disallow forbidden methods, and anything that is not a HTTP // token, since HTTP states that Method may be any of the defined values or // a token (extension method).
nsAutoCString outMethod;
nsresult rv = FetchUtil::GetValidRequestMethod(method, outMethod); if (NS_FAILED(rv)) {
aRv.ThrowTypeError<MSG_INVALID_REQUEST_METHOD>(method); return nullptr;
}
RefPtr<InternalHeaders> headers; if (aInit.mHeaders.WasPassed()) {
RefPtr<Headers> h = Headers::Create(aGlobal, aInit.mHeaders.Value(), aRv); if (aRv.Failed()) { return nullptr;
}
headers = h->GetInternalHeaders();
} else {
headers = new InternalHeaders(*requestHeaders);
}
requestHeaders->Clear(); // From "Let r be a new Request object associated with request and a new // Headers object whose guard is "request"."
requestHeaders->SetGuard(HeadersGuardEnum::Request, aRv);
MOZ_ASSERT(!aRv.Failed());
if (request->Mode() == RequestMode::No_cors) { if (!request->HasSimpleMethod()) {
nsAutoCString method;
request->GetMethod(method);
aRv.ThrowTypeError<MSG_INVALID_REQUEST_METHOD>(method); return nullptr;
}
requestHeaders->SetGuard(HeadersGuardEnum::Request_no_cors, aRv); if (aRv.Failed()) { return nullptr;
}
}
requestHeaders->Fill(*headers, aRv); if (aRv.Failed()) { return nullptr;
}
if ((aInit.mBody.WasPassed() && !aInit.mBody.Value().IsNull()) ||
hasCopiedBody) { // HEAD and GET are not allowed to have a body.
nsAutoCString method;
request->GetMethod(method); // method is guaranteed to be uppercase due to step 14.2 above. if (method.EqualsLiteral("HEAD") || method.EqualsLiteral("GET")) {
aRv.ThrowTypeError("HEAD or GET Request cannot have a body."); return nullptr;
}
}
if (aInit.mBody.WasPassed()) { const Nullable<fetch::OwningBodyInit>& bodyInitNullable =
aInit.mBody.Value(); if (!bodyInitNullable.IsNull()) { const fetch::OwningBodyInit& bodyInit = bodyInitNullable.Value();
nsCOMPtr<nsIInputStream> stream;
nsAutoCString contentTypeWithCharset;
uint64_t contentLength = 0;
aRv = ExtractByteStreamFromBody(bodyInit, getter_AddRefs(stream),
contentTypeWithCharset, contentLength); if (NS_WARN_IF(aRv.Failed())) { return nullptr;
}
nsCOMPtr<nsIInputStream> temporaryBody = stream;
if (!contentTypeWithCharset.IsVoid() &&
!requestHeaders->Has("Content-Type"_ns, aRv)) {
requestHeaders->Append("Content-Type"_ns, contentTypeWithCharset, aRv);
}
if (NS_WARN_IF(aRv.Failed())) { return nullptr;
}
if (hasCopiedBody) {
request->SetBody(nullptr, 0);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.