OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "Request.h" | 6 #include "Request.h" |
7 | 7 |
8 #include "bindings/v8/Dictionary.h" | 8 #include "bindings/v8/Dictionary.h" |
9 #include "core/dom/DOMURLUtilsReadOnly.h" | 9 #include "core/dom/ExecutionContext.h" |
10 #include "core/fetch/CrossOriginAccessControl.h" | |
11 #include "core/fetch/ResourceLoaderOptions.h" | |
12 #include "core/loader/ThreadableLoader.h" | |
13 #include "core/xml/XMLHttpRequest.h" | |
14 #include "modules/serviceworkers/FetchManager.h" | |
10 #include "modules/serviceworkers/RequestInit.h" | 15 #include "modules/serviceworkers/RequestInit.h" |
11 #include "platform/NotImplemented.h" | 16 #include "platform/NotImplemented.h" |
17 #include "platform/network/HTTPParsers.h" | |
12 #include "platform/network/ResourceRequest.h" | 18 #include "platform/network/ResourceRequest.h" |
19 #include "platform/weborigin/Referrer.h" | |
13 #include "public/platform/WebServiceWorkerRequest.h" | 20 #include "public/platform/WebServiceWorkerRequest.h" |
14 | 21 |
15 namespace WebCore { | 22 namespace WebCore { |
16 | 23 |
17 PassRefPtr<Request> Request::create() | 24 namespace { |
25 | |
26 PassRefPtr<Request> createRequestWithRequestData(PassRefPtr<FetchRequestData> re quest, const RequestInit& init, FetchRequestData::Mode mode, FetchRequestData::C redentials credentials, ExceptionState& exceptionState) | |
18 { | 27 { |
19 return create(Dictionary()); | 28 // "6. Let |mode| be |init|'s mode member if it is present, and |
29 // |fallbackMode| otherwise." | |
30 if (init.mode == "same-origin") { | |
31 mode = FetchRequestData::SameOriginMode; | |
32 } else if (init.mode == "no-cors") { | |
33 mode = FetchRequestData::NoCORSMode; | |
34 } else if (init.mode == "cors") { | |
35 mode = FetchRequestData::CORSMode; | |
36 } | |
37 // "7. If |mode| is non-null, set |request|'s mode to |mode|." | |
38 if (mode != FetchRequestData::NullMode) | |
39 request->setMode(mode); | |
40 | |
41 // "8. Let |credentials| be |init|'s credentials member if it is present, | |
42 // and |fallbackCredentials| otherwise." | |
43 if (init.credentials == "omit") { | |
44 credentials = FetchRequestData::OmitCredentials; | |
45 } else if (init.credentials == "same-origin") { | |
46 credentials = FetchRequestData::SameOriginCredentials; | |
47 } else if (init.credentials == "include") { | |
48 credentials = FetchRequestData::IncludeCredentials; | |
49 } | |
50 // "9. If |credentials| is non-null, set |request|'s credentials mode to | |
51 // |credentials|. | |
52 if (credentials != FetchRequestData::NullCredentials) | |
53 request->setCredentials(credentials); | |
54 | |
55 // "10. If |init|'s method member is present, let |method| be it and run | |
56 // these substeps:" | |
57 if (!init.method.isEmpty()) { | |
58 // "1. If |method| is not a useful method, throw a TypeError." | |
59 if (!FetchManager::isUsefulMethod(init.method)) { | |
60 exceptionState.throwTypeError("'" + init.method + "' HTTP method is unsupported."); | |
61 return nullptr; | |
62 } | |
63 if (!isValidHTTPToken(init.method)) { | |
64 exceptionState.throwTypeError("'" + init.method + "' is not a valid HTTP method."); | |
65 return nullptr; | |
66 } | |
67 // FIXME: "2. Add case correction as in XMLHttpRequest?" | |
68 // "3. Set |request|'s method to |method|." | |
69 request->setMethod(XMLHttpRequest::uppercaseKnownHTTPMethod(AtomicString (init.method))); | |
70 } | |
71 // "11. Let |r| be a new Request object associated with |request|, Headers | |
72 // object, and FetchBodyStream object." | |
73 RefPtr<Request> r = Request::create(request); | |
74 // "12. If |r|'s request's mode is no CORS, run these substeps: | |
75 if (r->request()->mode() == FetchRequestData::NoCORSMode) { | |
76 // "1. If |r|'s request's method is not a simple method, throw a | |
77 // TypeError." | |
78 if (!FetchManager::isSimpleMethod(r->request()->method())) { | |
79 exceptionState.throwTypeError("'" + r->request()->method() + "' is u nsupported in no-cors mode."); | |
80 return nullptr; | |
81 } | |
82 // "Set |r|'s Headers object's guard to |request-no-CORS|. | |
83 r->headers()->setGuard(Headers::RequestNoCORSGuard); | |
84 } | |
85 | |
86 // "13. If |init|'s headers member is present, run these substeps:" | |
87 if (init.headers) { | |
88 // "1. Empty |r|'s request's header list." | |
yhirano
2014/07/02 01:53:07
ASSERT(init.headersDictionary.isUndefinedOrNull())
horo
2014/07/02 03:33:04
Done.
| |
89 r->request()->headerList()->clearList(); | |
90 // "2. Fill |r|'s Headers object with |init|'s headers member. Rethrow | |
91 // any exceptions." | |
92 r->headers()->fillWith(init.headers.get(), exceptionState); | |
93 if (exceptionState.hadException()) | |
94 return nullptr; | |
95 } else if (!init.headersDictionary.isUndefinedOrNull()) { | |
96 // "1. Empty |r|'s request's header list." | |
97 r->request()->headerList()->clearList(); | |
98 // "2. Fill |r|'s Headers object with |init|'s headers member. Rethrow | |
99 // any exceptions." | |
100 r->headers()->fillWith(init.headersDictionary, exceptionState); | |
101 if (exceptionState.hadException()) | |
102 return nullptr; | |
103 } | |
104 // FIXME: Support body. | |
105 // "17. Return |r|." | |
106 return r.release(); | |
20 } | 107 } |
21 | 108 |
22 PassRefPtr<Request> Request::create(const Dictionary& requestInit) | 109 |
110 } // namespace | |
111 | |
112 PassRefPtr<Request> Request::create(ExecutionContext* context, const String& inp ut, ExceptionState& exceptionState) | |
23 { | 113 { |
24 return adoptRef(new Request(RequestInit(requestInit))); | 114 return create(context, input, Dictionary(), exceptionState); |
115 } | |
116 | |
117 PassRefPtr<Request> Request::create(ExecutionContext* context, const String& inp ut, const Dictionary& init, ExceptionState& exceptionState) | |
118 { | |
119 // "1. Let |request| be |input|'s associated request, if |input| is a | |
120 // Request object, and a new request otherwise." | |
121 RefPtr<FetchRequestData> request(FetchRequestData::create()); | |
122 // "2. Set |request| to a restricted copy of itself." | |
123 request = request->createRestrictedCopy(true, SecurityOrigin::create(context ->url())); | |
124 // "5. If |input| is a string, run these substeps:" | |
125 // "1. Let |parsedURL| be the result of parsing |input| with entry settings | |
126 // object's API base URL." | |
127 KURL parsedURL = context->completeURL(input); | |
128 // "2. If |parsedURL| is failure, throw a TypeError." | |
129 if (!parsedURL.isValid()) { | |
130 exceptionState.throwTypeError("Invalid URL"); | |
131 return nullptr; | |
132 } | |
133 // "3. Set |request|'s url to |parsedURL|." | |
134 request->setURL(parsedURL); | |
135 // "4. Set |fallbackMode| to CORS." | |
136 // "5. Set |fallbackCredentials| to omit." | |
137 return createRequestWithRequestData(request.release(), RequestInit(init), Fe tchRequestData::CORSMode, FetchRequestData::OmitCredentials, exceptionState); | |
138 } | |
139 | |
140 | |
141 PassRefPtr<Request> Request::create(ExecutionContext* context, Request* input, E xceptionState& exceptionState) | |
142 { | |
143 return create(context, input, Dictionary(), exceptionState); | |
144 } | |
145 | |
146 PassRefPtr<Request> Request::create(ExecutionContext* context, Request* input, c onst Dictionary& init, ExceptionState& exceptionState) | |
147 { | |
148 // "1. Let |request| be |input|'s associated request, if |input| is a | |
149 // Request object, and a new request otherwise." | |
150 // "2. Set |request| to a restricted copy of itself." | |
151 RefPtr<FetchRequestData> request(input->request()->createRestrictedCopy(true , SecurityOrigin::create(context->url()))); | |
152 // "3. Let |fallbackMode| be null." | |
153 // "4. Let |fallbackCredentials| be null." | |
154 return createRequestWithRequestData(request.release(), RequestInit(init), Fe tchRequestData::NullMode, FetchRequestData::NullCredentials, exceptionState); | |
155 } | |
156 | |
157 PassRefPtr<Request> Request::create(PassRefPtr<FetchRequestData> request) | |
158 { | |
159 return adoptRef(new Request(request)); | |
160 } | |
161 | |
162 Request::Request(PassRefPtr<FetchRequestData> request) | |
163 : m_request(request) | |
164 , m_headers(Headers::create(m_request->headerList())) | |
165 { | |
166 m_headers->setGuard(Headers::RequestGuard); | |
167 ScriptWrappable::init(this); | |
25 } | 168 } |
26 | 169 |
27 PassRefPtr<Request> Request::create(const blink::WebServiceWorkerRequest& webReq uest) | 170 PassRefPtr<Request> Request::create(const blink::WebServiceWorkerRequest& webReq uest) |
28 { | 171 { |
29 return adoptRef(new Request(webRequest)); | 172 return adoptRef(new Request(webRequest)); |
30 } | 173 } |
31 | 174 |
32 void Request::setURL(const String& value) | 175 Request::Request(const blink::WebServiceWorkerRequest& webRequest) |
176 : m_request(FetchRequestData::create(webRequest)) | |
177 , m_headers(Headers::create(m_request->headerList())) | |
33 { | 178 { |
34 m_url = KURL(ParsedURLString, value); | 179 m_headers->setGuard(Headers::RequestGuard); |
180 ScriptWrappable::init(this); | |
35 } | 181 } |
36 | 182 |
37 void Request::setMethod(const String& value) | 183 String Request::method() const |
38 { | 184 { |
39 m_method = value; | 185 // "The method attribute's getter must return request's method." |
186 return m_request->method(); | |
40 } | 187 } |
41 | 188 |
42 String Request::origin() const | 189 String Request::url() const |
43 { | 190 { |
44 return DOMURLUtilsReadOnly::origin(m_url); | 191 // The url attribute's getter must return request's url, serialized with the exclude fragment flag set. |
192 if (!m_request->url().hasFragmentIdentifier()) | |
193 return m_request->url(); | |
194 KURL url(m_request->url()); | |
195 url.removeFragmentIdentifier(); | |
196 return url; | |
197 } | |
198 | |
199 String Request::referrer() const | |
200 { | |
201 // "The referrer attribute's getter must return the empty string if | |
202 // request's referrer is none, and request's referrer, serialized, | |
203 // otherwise." | |
204 return m_request->referrer().getUrl(); | |
205 } | |
206 | |
207 String Request::mode() const | |
208 { | |
209 // "The mode attribute's getter must return the value corresponding to the | |
210 // first matching statement, switching on request's mode:" | |
211 switch (m_request->mode()) { | |
212 case FetchRequestData::SameOriginMode: | |
213 return "same-origin"; | |
214 case FetchRequestData::NoCORSMode: | |
215 return "no-cors"; | |
216 case FetchRequestData::CORSMode: | |
217 case FetchRequestData::CORSWithForcedPreflight: | |
218 return "cors"; | |
219 case FetchRequestData::NullMode: | |
220 ASSERT_NOT_REACHED(); | |
221 return ""; | |
222 } | |
223 return ""; | |
224 } | |
225 | |
226 String Request::credentials() const | |
227 { | |
228 // "The credentials attribute's getter must return the value corresponding | |
229 // to the first matching statement, switching on request's credentials | |
230 // mode:" | |
231 switch (m_request->credentials()) { | |
232 case FetchRequestData::OmitCredentials: | |
233 return "omit"; | |
234 case FetchRequestData::SameOriginCredentials: | |
235 return "same-origin"; | |
236 case FetchRequestData::IncludeCredentials: | |
237 return "include"; | |
238 case FetchRequestData::NullCredentials: | |
239 ASSERT_NOT_REACHED(); | |
240 return ""; | |
241 } | |
242 return ""; | |
45 } | 243 } |
46 | 244 |
47 PassOwnPtr<ResourceRequest> Request::createResourceRequest() const | 245 PassOwnPtr<ResourceRequest> Request::createResourceRequest() const |
48 { | 246 { |
49 OwnPtr<ResourceRequest> request = adoptPtr(new ResourceRequest(m_url)); | 247 OwnPtr<ResourceRequest> request = adoptPtr(new ResourceRequest(url())); |
50 request->setHTTPMethod("GET"); | 248 request->setHTTPMethod("GET"); |
51 // FIXME: Fill more info. | 249 // FIXME: Fill more info. |
52 return request.release(); | 250 return request.release(); |
53 } | 251 } |
54 | 252 |
55 Request::Request(const RequestInit& requestInit) | |
56 : m_url(KURL(ParsedURLString, requestInit.url)) | |
57 , m_method(requestInit.method) | |
58 , m_headers(requestInit.headers) | |
59 { | |
60 ScriptWrappable::init(this); | |
61 | |
62 if (!m_headers) | |
63 m_headers = HeaderMap::create(); | |
64 } | |
65 | |
66 Request::Request(const blink::WebServiceWorkerRequest& webRequest) | |
67 : m_url(webRequest.url()) | |
68 , m_method(webRequest.method()) | |
69 , m_headers(HeaderMap::create(webRequest.headers())) | |
70 { | |
71 ScriptWrappable::init(this); | |
72 } | |
73 | |
74 } // namespace WebCore | 253 } // namespace WebCore |
OLD | NEW |