1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
9 #include "nsPIDOMWindow.h"
11 #include "mozilla/ErrorResult.h"
12 #include "mozilla/dom/Headers.h"
13 #include "mozilla/dom/Fetch.h"
14 #include "mozilla/dom/Promise.h"
15 #include "mozilla/dom/URL.h"
16 #include "mozilla/dom/workers/bindings/URL.h"
18 #include "WorkerPrivate.h"
23 NS_IMPL_CYCLE_COLLECTING_ADDREF(Request
)
24 NS_IMPL_CYCLE_COLLECTING_RELEASE(Request
)
25 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Request
, mOwner
, mHeaders
)
27 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Request
)
28 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
29 NS_INTERFACE_MAP_ENTRY(nsISupports
)
32 Request::Request(nsIGlobalObject
* aOwner
, InternalRequest
* aRequest
)
33 : FetchBody
<Request
>()
43 already_AddRefed
<InternalRequest
>
44 Request::GetInternalRequest()
46 nsRefPtr
<InternalRequest
> r
= mRequest
;
50 /*static*/ already_AddRefed
<Request
>
51 Request::Constructor(const GlobalObject
& aGlobal
,
52 const RequestOrUSVString
& aInput
,
53 const RequestInit
& aInit
, ErrorResult
& aRv
)
55 nsRefPtr
<InternalRequest
> request
;
57 nsCOMPtr
<nsIGlobalObject
> global
= do_QueryInterface(aGlobal
.GetAsSupports());
59 if (aInput
.IsRequest()) {
60 nsRefPtr
<Request
> inputReq
= &aInput
.GetAsRequest();
61 if (inputReq
->BodyUsed()) {
62 aRv
.ThrowTypeError(MSG_REQUEST_BODY_CONSUMED_ERROR
);
66 inputReq
->SetBodyUsed();
67 request
= inputReq
->GetInternalRequest();
69 request
= new InternalRequest();
72 request
= request
->GetRequestConstructorCopy(global
, aRv
);
73 if (NS_WARN_IF(aRv
.Failed())) {
77 RequestMode fallbackMode
= RequestMode::EndGuard_
;
78 RequestCredentials fallbackCredentials
= RequestCredentials::EndGuard_
;
79 if (aInput
.IsUSVString()) {
81 input
.Assign(aInput
.GetAsUSVString());
84 if (NS_IsMainThread()) {
85 nsCOMPtr
<nsPIDOMWindow
> window
= do_QueryInterface(global
);
87 nsCOMPtr
<nsIURI
> docURI
= window
->GetDocumentURI();
89 aRv
= docURI
->GetSpec(spec
);
90 if (NS_WARN_IF(aRv
.Failed())) {
94 nsRefPtr
<mozilla::dom::URL
> url
=
95 dom::URL::Constructor(aGlobal
, input
, NS_ConvertUTF8toUTF16(spec
), aRv
);
100 url
->Stringify(requestURL
, aRv
);
105 workers::WorkerPrivate
* worker
= workers::GetCurrentThreadWorkerPrivate();
107 worker
->AssertIsOnWorkerThread();
109 nsString baseURL
= NS_ConvertUTF8toUTF16(worker
->GetLocationInfo().mHref
);
110 nsRefPtr
<workers::URL
> url
=
111 workers::URL::Constructor(aGlobal
, input
, baseURL
, aRv
);
116 url
->Stringify(requestURL
, aRv
);
121 request
->SetURL(NS_ConvertUTF16toUTF8(requestURL
));
122 fallbackMode
= RequestMode::Cors
;
123 fallbackCredentials
= RequestCredentials::Omit
;
126 RequestMode mode
= aInit
.mMode
.WasPassed() ? aInit
.mMode
.Value() : fallbackMode
;
127 RequestCredentials credentials
=
128 aInit
.mCredentials
.WasPassed() ? aInit
.mCredentials
.Value()
129 : fallbackCredentials
;
131 if (mode
!= RequestMode::EndGuard_
) {
132 request
->SetMode(mode
);
135 if (credentials
!= RequestCredentials::EndGuard_
) {
136 request
->SetCredentialsMode(credentials
);
139 if (aInit
.mMethod
.WasPassed()) {
140 nsCString method
= aInit
.mMethod
.Value();
143 if (!method
.EqualsASCII("options") &&
144 !method
.EqualsASCII("get") &&
145 !method
.EqualsASCII("head") &&
146 !method
.EqualsASCII("post") &&
147 !method
.EqualsASCII("put") &&
148 !method
.EqualsASCII("delete")) {
149 NS_ConvertUTF8toUTF16
label(method
);
150 aRv
.ThrowTypeError(MSG_INVALID_REQUEST_METHOD
, &label
);
155 request
->SetMethod(method
);
158 nsRefPtr
<InternalHeaders
> requestHeaders
= request
->Headers();
160 nsRefPtr
<InternalHeaders
> headers
;
161 if (aInit
.mHeaders
.WasPassed()) {
162 nsRefPtr
<Headers
> h
= Headers::Constructor(aGlobal
, aInit
.mHeaders
.Value(), aRv
);
166 headers
= h
->GetInternalHeaders();
168 headers
= new InternalHeaders(*requestHeaders
);
171 requestHeaders
->Clear();
173 if (request
->Mode() == RequestMode::No_cors
) {
174 if (!request
->HasSimpleMethod()) {
175 nsAutoCString method
;
176 request
->GetMethod(method
);
177 NS_ConvertUTF8toUTF16
label(method
);
178 aRv
.ThrowTypeError(MSG_INVALID_REQUEST_METHOD
, &label
);
182 requestHeaders
->SetGuard(HeadersGuardEnum::Request_no_cors
, aRv
);
188 requestHeaders
->Fill(*headers
, aRv
);
193 if (aInit
.mBody
.WasPassed()) {
194 const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams
& bodyInit
= aInit
.mBody
.Value();
195 nsCOMPtr
<nsIInputStream
> stream
;
196 nsCString contentType
;
197 aRv
= ExtractByteStreamFromBody(bodyInit
,
198 getter_AddRefs(stream
), contentType
);
199 if (NS_WARN_IF(aRv
.Failed())) {
202 request
->SetBody(stream
);
204 if (!contentType
.IsVoid() &&
205 !requestHeaders
->Has(NS_LITERAL_CSTRING("Content-Type"), aRv
)) {
206 requestHeaders
->Append(NS_LITERAL_CSTRING("Content-Type"),
215 nsRefPtr
<Request
> domRequest
= new Request(global
, request
);
216 domRequest
->SetMimeType(aRv
);
217 return domRequest
.forget();
220 already_AddRefed
<Request
>
221 Request::Clone() const
223 // FIXME(nsm): Bug 1073231. This is incorrect, but the clone method isn't
225 nsRefPtr
<Request
> request
= new Request(mOwner
,
226 new InternalRequest(*mRequest
));
227 return request
.forget();
234 mHeaders
= new Headers(mOwner
, mRequest
->Headers());
241 } // namespace mozilla