Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: Source/modules/serviceworkers/Request.cpp

Issue 795323003: Move Fetch API releted code to modules/fetch. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/modules/serviceworkers/Request.h ('k') | Source/modules/serviceworkers/Request.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "Request.h"
7
8 #include "bindings/core/v8/Dictionary.h"
9 #include "core/dom/Document.h"
10 #include "core/dom/ExecutionContext.h"
11 #include "core/fetch/FetchUtils.h"
12 #include "core/fetch/ResourceLoaderOptions.h"
13 #include "core/loader/ThreadableLoader.h"
14 #include "modules/serviceworkers/FetchManager.h"
15 #include "modules/serviceworkers/RequestInit.h"
16 #include "platform/network/HTTPParsers.h"
17 #include "platform/network/ResourceRequest.h"
18 #include "platform/weborigin/Referrer.h"
19 #include "public/platform/WebServiceWorkerRequest.h"
20 #include "public/platform/WebURLRequest.h"
21
22 namespace blink {
23
24 FetchRequestData* createCopyOfFetchRequestDataForFetch(ExecutionContext* context , const FetchRequestData* original)
25 {
26 FetchRequestData* request = FetchRequestData::create();
27 request->setURL(original->url());
28 request->setMethod(original->method());
29 request->setHeaderList(original->headerList()->createCopy());
30 request->setUnsafeRequestFlag(true);
31 request->setBlobDataHandle(original->blobDataHandle());
32 // FIXME: Set client.
33 request->setOrigin(SecurityOrigin::create(context->url()));
34 // FIXME: Set ForceOriginHeaderFlag.
35 request->setSameOriginDataURLFlag(true);
36 request->mutableReferrer()->setClient();
37 request->setContext(WebURLRequest::RequestContextFetch);
38 request->setMode(original->mode());
39 request->setCredentials(original->credentials());
40 // FIXME: Set cache mode.
41 return request;
42 }
43
44 Request* Request::createRequestWithRequestOrString(ExecutionContext* context, Re quest* inputRequest, const String& inputString, const RequestInit& init, Excepti onState& exceptionState)
45 {
46 // "1. If input is a Request object, run these substeps:"
47 if (inputRequest) {
48 // "1. If input's used flag is set, throw a TypeError."
49 if (inputRequest->bodyUsed()) {
50 exceptionState.throwTypeError("Cannot construct a Request with a Req uest object that has already been used.");
51 return 0;
52 }
53 // "2. Set input's used flag."
54 inputRequest->setBodyUsed();
55 }
56
57 // "2. Let |request| be |input|'s associated request, if |input| is a
58 // Request object, and a new request otherwise."
59 // "3. Set |request| to a new request whose url is |request|'s url, method
60 // is |request|'s method, header list is a copy of |request|'s header list,
61 // unsafe request flag is set, body is |request|'s body, client is entry
62 // settings object, origin is entry settings object's origin, force Origin
63 // header flag is set, same-origin data URL flag is set, referrer is client,
64 // context is fetch, mode is |request|'s mode, credentials mode is
65 // |request|'s credentials mode, and cache mode is |request|'s cache mode."
66 FetchRequestData* request = createCopyOfFetchRequestDataForFetch(context, in putRequest ? inputRequest->request() : FetchRequestData::create());
67
68 // "4. Let |fallbackMode| be null."
69 // "5. Let |fallbackCredentials| be null."
70 // "6. Let |fallbackCache| be null."
71 // We don't use fallback values. We set these flags directly in below.
72
73 // "7. If |input| is a string, run these substeps:"
74 if (!inputRequest) {
75 // "1. Let |parsedURL| be the result of parsing |input| with entry
76 // settings object's API base URL."
77 KURL parsedURL = context->completeURL(inputString);
78 // "2. If |parsedURL| is failure, throw a TypeError."
79 if (!parsedURL.isValid()) {
80 exceptionState.throwTypeError("Failed to parse URL from " + inputStr ing);
81 return 0;
82 }
83 // "3. Set |request|'s url to |parsedURL|."
84 request->setURL(parsedURL);
85 // "4. Set |fallbackMode| to CORS."
86 // "5. Set |fallbackCredentials| to omit."
87 // "6. Set |fallbackCache| to default."
88 // We don't use fallback values. We set these flags directly in below.
89 }
90
91 // "8. Let |mode| be |init|'s mode member if it is present, and
92 // |fallbackMode| otherwise."
93 // "9. If |mode| is non-null, set |request|'s mode to |mode|."
94 if (init.mode == "same-origin") {
95 request->setMode(WebURLRequest::FetchRequestModeSameOrigin);
96 } else if (init.mode == "no-cors") {
97 request->setMode(WebURLRequest::FetchRequestModeNoCORS);
98 } else if (init.mode == "cors") {
99 request->setMode(WebURLRequest::FetchRequestModeCORS);
100 } else {
101 if (!inputRequest)
102 request->setMode(WebURLRequest::FetchRequestModeCORS);
103 }
104
105 // "10. Let |credentials| be |init|'s credentials member if it is present,
106 // and |fallbackCredentials| otherwise."
107 // "11. If |credentials| is non-null, set |request|'s credentials mode to
108 // |credentials|.
109 if (init.credentials == "omit") {
110 request->setCredentials(WebURLRequest::FetchCredentialsModeOmit);
111 } else if (init.credentials == "same-origin") {
112 request->setCredentials(WebURLRequest::FetchCredentialsModeSameOrigin);
113 } else if (init.credentials == "include") {
114 request->setCredentials(WebURLRequest::FetchCredentialsModeInclude);
115 } else {
116 if (!inputRequest)
117 request->setCredentials(WebURLRequest::FetchCredentialsModeOmit);
118 }
119
120 // FIXME: "12. Let |cache| be |init|'s cache member if it is present, and
121 // |fallbackCache| otherwise."
122 // FIXME: "13. If |cache| is non-null, set |request|'s cache mode to
123 // |cache|."
124
125 // "14. If |init|'s method member is present, let |method| be it and run
126 // these substeps:"
127 if (!init.method.isEmpty()) {
128 // "1. If |method| is not a method or method is a forbidden method,
129 // throw a TypeError."
130 if (!isValidHTTPToken(init.method)) {
131 exceptionState.throwTypeError("'" + init.method + "' is not a valid HTTP method.");
132 return 0;
133 }
134 if (FetchUtils::isForbiddenMethod(init.method)) {
135 exceptionState.throwTypeError("'" + init.method + "' HTTP method is unsupported.");
136 return 0;
137 }
138 // "2. Normalize |method|."
139 // "3. Set |request|'s method to |method|."
140 request->setMethod(FetchUtils::normalizeMethod(AtomicString(init.method) ));
141 }
142 // "15. Let |r| be a new Request object associated with |request|, and a new
143 // Headers object."
144 Request* r = Request::create(context, request);
145 // "16. Let |headers| be a copy of |r|'s Headers object."
146 // "17. If |init|'s headers member is present, set |headers| to |init|'s
147 // headers member."
148 // We don't create a copy of r's Headers object when init's headers member
149 // is present.
150 Headers* headers = 0;
151 if (!init.headers && init.headersDictionary.isUndefinedOrNull()) {
152 headers = r->headers()->createCopy();
153 }
154 // "18. Empty |r|'s request's header list."
155 r->clearHeaderList();
156 // "19. If |r|'s request's mode is no CORS, run these substeps:
157 if (r->request()->mode() == WebURLRequest::FetchRequestModeNoCORS) {
158 // "1. If |r|'s request's method is not a simple method, throw a
159 // TypeError."
160 if (!FetchUtils::isSimpleMethod(r->request()->method())) {
161 exceptionState.throwTypeError("'" + r->request()->method() + "' is u nsupported in no-cors mode.");
162 return 0;
163 }
164 // "Set |r|'s Headers object's guard to |request-no-CORS|.
165 r->headers()->setGuard(Headers::RequestNoCORSGuard);
166 }
167 // "20. Fill |r|'s Headers object with |headers|. Rethrow any exceptions."
168 if (init.headers) {
169 ASSERT(init.headersDictionary.isUndefinedOrNull());
170 r->headers()->fillWith(init.headers.get(), exceptionState);
171 } else if (!init.headersDictionary.isUndefinedOrNull()) {
172 r->headers()->fillWith(init.headersDictionary, exceptionState);
173 } else {
174 ASSERT(headers);
175 r->headers()->fillWith(headers, exceptionState);
176 }
177 if (exceptionState.hadException())
178 return 0;
179
180 // "21. If |init|'s body member is present, run these substeps:"
181 if (init.bodyBlobHandle) {
182 // "1. Let |stream| and |Content-Type| be the result of extracting
183 // |init|'s body member."
184 // "2. Set |r|'s request's body to |stream|."
185 // "3.If |Content-Type| is non-null and |r|'s request's header list
186 // contains no header named `Content-Type`, append
187 // `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any
188 // exception."
189 r->setBodyBlobHandle(init.bodyBlobHandle);
190 if (!init.bodyBlobHandle->type().isEmpty() && !r->headers()->has("Conten t-Type", exceptionState)) {
191 r->headers()->append("Content-Type", init.bodyBlobHandle->type(), ex ceptionState);
192 }
193 if (exceptionState.hadException())
194 return 0;
195 }
196 // "22. Set |r|'s MIME type to the result of extracting a MIME type from
197 // |r|'s request's header list."
198 // FIXME: We don't have MIME type in Request object yet.
199
200 // "23. Return |r|."
201 return r;
202 }
203
204 Request* Request::create(ExecutionContext* context, const RequestInfo& input, co nst Dictionary& init, ExceptionState& exceptionState)
205 {
206 ASSERT(!input.isNull());
207 if (input.isUSVString())
208 return create(context, input.getAsUSVString(), init, exceptionState);
209 return create(context, input.getAsRequest(), init, exceptionState);
210 }
211
212 Request* Request::create(ExecutionContext* context, const String& input, Excepti onState& exceptionState)
213 {
214 return create(context, input, Dictionary(), exceptionState);
215 }
216
217 Request* Request::create(ExecutionContext* context, const String& input, const D ictionary& init, ExceptionState& exceptionState)
218 {
219 return createRequestWithRequestOrString(context, 0, input, RequestInit(conte xt, init, exceptionState), exceptionState);
220 }
221
222 Request* Request::create(ExecutionContext* context, Request* input, ExceptionSta te& exceptionState)
223 {
224 return create(context, input, Dictionary(), exceptionState);
225 }
226
227 Request* Request::create(ExecutionContext* context, Request* input, const Dictio nary& init, ExceptionState& exceptionState)
228 {
229 return createRequestWithRequestOrString(context, input, String(), RequestIni t(context, init, exceptionState), exceptionState);
230 }
231
232 Request* Request::create(ExecutionContext* context, FetchRequestData* request)
233 {
234 Request* r = new Request(context, request);
235 r->suspendIfNeeded();
236 return r;
237 }
238
239 Request::Request(ExecutionContext* context, FetchRequestData* request)
240 : Body(context)
241 , m_request(request)
242 , m_headers(Headers::create(m_request->headerList()))
243 {
244 m_headers->setGuard(Headers::RequestGuard);
245 }
246
247 Request* Request::create(ExecutionContext* context, const WebServiceWorkerReques t& webRequest)
248 {
249 Request* r = new Request(context, webRequest);
250 r->suspendIfNeeded();
251 return r;
252 }
253
254 Request* Request::create(const Request& copyFrom)
255 {
256 Request* r = new Request(copyFrom);
257 r->suspendIfNeeded();
258 return r;
259 }
260
261 Request::Request(ExecutionContext* context, const WebServiceWorkerRequest& webRe quest)
262 : Body(context)
263 , m_request(FetchRequestData::create(webRequest))
264 , m_headers(Headers::create(m_request->headerList()))
265 {
266 m_headers->setGuard(Headers::RequestGuard);
267 }
268
269 Request::Request(const Request& copy_from)
270 : Body(copy_from)
271 , m_request(copy_from.m_request->createCopy())
272 , m_headers(Headers::create(m_request->headerList()))
273 {
274 }
275
276
277 String Request::method() const
278 {
279 // "The method attribute's getter must return request's method."
280 return m_request->method();
281 }
282
283 String Request::url() const
284 {
285 // The url attribute's getter must return request's url, serialized with the exclude fragment flag set.
286 if (!m_request->url().hasFragmentIdentifier())
287 return m_request->url();
288 KURL url(m_request->url());
289 url.removeFragmentIdentifier();
290 return url;
291 }
292
293 String Request::referrer() const
294 {
295 // "The referrer attribute's getter must return the empty string if
296 // request's referrer is no referrer, "about:client" if request's referrer
297 // is client and request's referrer, serialized, otherwise."
298 if (m_request->referrer().isNoReferrer())
299 return String();
300 if (m_request->referrer().isClient())
301 return String("about:client");
302 return m_request->referrer().referrer().referrer;
303 }
304
305 String Request::mode() const
306 {
307 // "The mode attribute's getter must return the value corresponding to the
308 // first matching statement, switching on request's mode:"
309 switch (m_request->mode()) {
310 case WebURLRequest::FetchRequestModeSameOrigin:
311 return "same-origin";
312 case WebURLRequest::FetchRequestModeNoCORS:
313 return "no-cors";
314 case WebURLRequest::FetchRequestModeCORS:
315 case WebURLRequest::FetchRequestModeCORSWithForcedPreflight:
316 return "cors";
317 }
318 ASSERT_NOT_REACHED();
319 return "";
320 }
321
322 String Request::credentials() const
323 {
324 // "The credentials attribute's getter must return the value corresponding
325 // to the first matching statement, switching on request's credentials
326 // mode:"
327 switch (m_request->credentials()) {
328 case WebURLRequest::FetchCredentialsModeOmit:
329 return "omit";
330 case WebURLRequest::FetchCredentialsModeSameOrigin:
331 return "same-origin";
332 case WebURLRequest::FetchCredentialsModeInclude:
333 return "include";
334 }
335 ASSERT_NOT_REACHED();
336 return "";
337 }
338
339 Request* Request::clone(ExceptionState& exceptionState) const
340 {
341 if (bodyUsed()) {
342 exceptionState.throwTypeError("Request body is already used");
343 return nullptr;
344 }
345 if (streamAccessed()) {
346 // FIXME: Support clone() of the stream accessed Request.
347 exceptionState.throwTypeError("clone() of the Request which .body is acc essed is not supported.");
348 return nullptr;
349 }
350 return Request::create(*this);
351 }
352
353 void Request::populateWebServiceWorkerRequest(WebServiceWorkerRequest& webReques t) const
354 {
355 webRequest.setMethod(method());
356 webRequest.setURL(m_request->url());
357
358 const FetchHeaderList* headerList = m_headers->headerList();
359 for (size_t i = 0, size = headerList->size(); i < size; ++i) {
360 const FetchHeaderList::Header& header = headerList->entry(i);
361 webRequest.appendHeader(header.first, header.second);
362 }
363
364 webRequest.setReferrer(m_request->referrer().referrer().referrer, static_cas t<WebReferrerPolicy>(m_request->referrer().referrer().referrerPolicy));
365 // FIXME: How can we set isReload properly? What is the correct place to loa d it in to the Request object? We should investigate the right way
366 // to plumb this information in to here.
367 }
368
369 void Request::setBodyBlobHandle(PassRefPtr<BlobDataHandle> blobDataHandle)
370 {
371 m_request->setBlobDataHandle(blobDataHandle);
372 }
373
374 void Request::clearHeaderList()
375 {
376 m_request->headerList()->clearList();
377 }
378
379 PassRefPtr<BlobDataHandle> Request::blobDataHandle() const
380 {
381 return m_request->blobDataHandle();
382 }
383
384 BodyStreamBuffer* Request::buffer() const
385 {
386 return nullptr;
387 }
388
389 String Request::contentTypeForBuffer() const
390 {
391 // We don't support BodyStreamBuffer for Request yet.
392 ASSERT_NOT_REACHED();
393 return String();
394 }
395
396 void Request::trace(Visitor* visitor)
397 {
398 Body::trace(visitor);
399 visitor->trace(m_request);
400 visitor->trace(m_headers);
401 }
402
403 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/serviceworkers/Request.h ('k') | Source/modules/serviceworkers/Request.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698