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/core/v8/Dictionary.h" | 8 #include "bindings/core/v8/Dictionary.h" |
9 #include "core/dom/ExecutionContext.h" | 9 #include "core/dom/ExecutionContext.h" |
10 #include "core/fetch/FetchUtils.h" | 10 #include "core/fetch/FetchUtils.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 m_webRequest->setHeader(key, value); | 39 m_webRequest->setHeader(key, value); |
40 return true; | 40 return true; |
41 } | 41 } |
42 | 42 |
43 private: | 43 private: |
44 WebServiceWorkerRequest* m_webRequest; | 44 WebServiceWorkerRequest* m_webRequest; |
45 }; | 45 }; |
46 | 46 |
47 Request* createRequestWithRequestData(ExecutionContext* context, FetchRequestDat
a* request, const RequestInit& init, FetchRequestData::Mode mode, FetchRequestDa
ta::Credentials credentials, ExceptionState& exceptionState) | 47 Request* createRequestWithRequestData(ExecutionContext* context, FetchRequestDat
a* request, const RequestInit& init, FetchRequestData::Mode mode, FetchRequestDa
ta::Credentials credentials, ExceptionState& exceptionState) |
48 { | 48 { |
49 // "6. Let |mode| be |init|'s mode member if it is present, and | 49 // "7. Let |mode| be |init|'s mode member if it is present, and |
50 // |fallbackMode| otherwise." | 50 // |fallbackMode| otherwise." |
51 // "7. If |mode| is non-null, set |request|'s mode to |mode|." | 51 // "8. If |mode| is non-null, set |request|'s mode to |mode|." |
52 if (init.mode == "same-origin") { | 52 if (init.mode == "same-origin") { |
53 request->setMode(FetchRequestData::SameOriginMode); | 53 request->setMode(FetchRequestData::SameOriginMode); |
54 } else if (init.mode == "no-cors") { | 54 } else if (init.mode == "no-cors") { |
55 request->setMode(mode = FetchRequestData::NoCORSMode); | 55 request->setMode(mode = FetchRequestData::NoCORSMode); |
56 } else if (init.mode == "cors") { | 56 } else if (init.mode == "cors") { |
57 request->setMode(FetchRequestData::CORSMode); | 57 request->setMode(FetchRequestData::CORSMode); |
58 } else { | 58 } else { |
59 // Instead of using null as a special fallback value, we pass the | 59 // Instead of using null as a special fallback value, we pass the |
60 // current mode in Request::create(). So we just set here. | 60 // current mode in Request::create(). So we just set here. |
61 request->setMode(mode); | 61 request->setMode(mode); |
62 } | 62 } |
63 | 63 |
64 // "8. Let |credentials| be |init|'s credentials member if it is present, | 64 // "9. Let |credentials| be |init|'s credentials member if it is present, |
65 // and |fallbackCredentials| otherwise." | 65 // and |fallbackCredentials| otherwise." |
66 // "9. If |credentials| is non-null, set |request|'s credentials mode to | 66 // "10. If |credentials| is non-null, set |request|'s credentials mode to |
67 // |credentials|. | 67 // |credentials|. |
68 if (init.credentials == "omit") { | 68 if (init.credentials == "omit") { |
69 request->setCredentials(FetchRequestData::OmitCredentials); | 69 request->setCredentials(FetchRequestData::OmitCredentials); |
70 } else if (init.credentials == "same-origin") { | 70 } else if (init.credentials == "same-origin") { |
71 request->setCredentials(FetchRequestData::SameOriginCredentials); | 71 request->setCredentials(FetchRequestData::SameOriginCredentials); |
72 } else if (init.credentials == "include") { | 72 } else if (init.credentials == "include") { |
73 request->setCredentials(FetchRequestData::IncludeCredentials); | 73 request->setCredentials(FetchRequestData::IncludeCredentials); |
74 } else { | 74 } else { |
75 // Instead of using null as a special fallback value, we pass the | 75 // Instead of using null as a special fallback value, we pass the |
76 // current credentials in Request::create(). So we just set here. | 76 // current credentials in Request::create(). So we just set here. |
77 request->setCredentials(credentials); | 77 request->setCredentials(credentials); |
78 } | 78 } |
79 | 79 |
80 // "10. If |init|'s method member is present, let |method| be it and run | 80 // "11. If |init|'s method member is present, let |method| be it and run |
81 // these substeps:" | 81 // these substeps:" |
82 if (!init.method.isEmpty()) { | 82 if (!init.method.isEmpty()) { |
83 // "1. If |method| is not a useful method, throw a TypeError." | 83 // "1. If |method| is not a useful method, throw a TypeError." |
84 if (!FetchUtils::isUsefulMethod(init.method)) { | 84 if (!FetchUtils::isUsefulMethod(init.method)) { |
85 exceptionState.throwTypeError("'" + init.method + "' HTTP method is
unsupported."); | 85 exceptionState.throwTypeError("'" + init.method + "' HTTP method is
unsupported."); |
86 return 0; | 86 return 0; |
87 } | 87 } |
88 if (!isValidHTTPToken(init.method)) { | 88 if (!isValidHTTPToken(init.method)) { |
89 exceptionState.throwTypeError("'" + init.method + "' is not a valid
HTTP method."); | 89 exceptionState.throwTypeError("'" + init.method + "' is not a valid
HTTP method."); |
90 return 0; | 90 return 0; |
91 } | 91 } |
92 // FIXME: "2. Add case correction as in XMLHttpRequest?" | 92 // FIXME: "2. Add case correction as in XMLHttpRequest?" |
93 // "3. Set |request|'s method to |method|." | 93 // "3. Set |request|'s method to |method|." |
94 request->setMethod(XMLHttpRequest::uppercaseKnownHTTPMethod(AtomicString
(init.method))); | 94 request->setMethod(XMLHttpRequest::uppercaseKnownHTTPMethod(AtomicString
(init.method))); |
95 } | 95 } |
96 // "11. Let |r| be a new Request object associated with |request|, Headers | 96 // "12. Let |r| be a new Request object associated with |request|, Headers |
97 // object." | 97 // object." |
98 Request* r = Request::create(context, request); | 98 Request* r = Request::create(context, request); |
99 | 99 |
100 // "12. Let |headers| be a copy of |r|'s Headers object." | 100 // "13. Let |headers| be a copy of |r|'s Headers object." |
101 // "13. If |init|'s headers member is present, set |headers| to |init|'s | 101 // "14. If |init|'s headers member is present, set |headers| to |init|'s |
102 // headers member." | 102 // headers member." |
103 // We don't create a copy of r's Headers object when init's headers member | 103 // We don't create a copy of r's Headers object when init's headers member |
104 // is present. | 104 // is present. |
105 Headers* headers = 0; | 105 Headers* headers = 0; |
106 if (!init.headers && init.headersDictionary.isUndefinedOrNull()) { | 106 if (!init.headers && init.headersDictionary.isUndefinedOrNull()) { |
107 headers = r->headers()->createCopy(); | 107 headers = r->headers()->createCopy(); |
108 } | 108 } |
109 // "14. Empty |r|'s request's header list." | 109 // "15. Empty |r|'s request's header list." |
110 r->request()->headerList()->clearList(); | 110 r->request()->headerList()->clearList(); |
111 | 111 |
112 // "15. If |r|'s request's mode is no CORS, run these substeps: | 112 // "16. If |r|'s request's mode is no CORS, run these substeps: |
113 if (r->request()->mode() == FetchRequestData::NoCORSMode) { | 113 if (r->request()->mode() == FetchRequestData::NoCORSMode) { |
114 // "1. If |r|'s request's method is not a simple method, throw a | 114 // "1. If |r|'s request's method is not a simple method, throw a |
115 // TypeError." | 115 // TypeError." |
116 if (!FetchUtils::isSimpleMethod(r->request()->method())) { | 116 if (!FetchUtils::isSimpleMethod(r->request()->method())) { |
117 exceptionState.throwTypeError("'" + r->request()->method() + "' is u
nsupported in no-cors mode."); | 117 exceptionState.throwTypeError("'" + r->request()->method() + "' is u
nsupported in no-cors mode."); |
118 return 0; | 118 return 0; |
119 } | 119 } |
120 // "Set |r|'s Headers object's guard to |request-no-CORS|. | 120 // "Set |r|'s Headers object's guard to |request-no-CORS|. |
121 r->headers()->setGuard(Headers::RequestNoCORSGuard); | 121 r->headers()->setGuard(Headers::RequestNoCORSGuard); |
122 } | 122 } |
123 | 123 |
124 // "16. Fill |r|'s Headers object with |headers|. Rethrow any exceptions." | 124 // "17. Fill |r|'s Headers object with |headers|. Rethrow any exceptions." |
125 if (init.headers) { | 125 if (init.headers) { |
126 ASSERT(init.headersDictionary.isUndefinedOrNull()); | 126 ASSERT(init.headersDictionary.isUndefinedOrNull()); |
127 r->headers()->fillWith(init.headers.get(), exceptionState); | 127 r->headers()->fillWith(init.headers.get(), exceptionState); |
128 } else if (!init.headersDictionary.isUndefinedOrNull()) { | 128 } else if (!init.headersDictionary.isUndefinedOrNull()) { |
129 r->headers()->fillWith(init.headersDictionary, exceptionState); | 129 r->headers()->fillWith(init.headersDictionary, exceptionState); |
130 } else { | 130 } else { |
131 ASSERT(headers); | 131 ASSERT(headers); |
132 r->headers()->fillWith(headers, exceptionState); | 132 r->headers()->fillWith(headers, exceptionState); |
133 } | 133 } |
134 if (exceptionState.hadException()) | 134 if (exceptionState.hadException()) |
135 return 0; | 135 return 0; |
136 // "17. If |init|'s body member is present, run these substeps:" | 136 // "18. If |init|'s body member is present, run these substeps:" |
137 if (init.bodyBlobHandle) { | 137 if (init.bodyBlobHandle) { |
138 // "1. Let |stream| and |Content-Type| be the result of extracting | 138 // "1. Let |stream| and |Content-Type| be the result of extracting |
139 // |init|'s body member." | 139 // |init|'s body member." |
140 // "2. Set |r|'s request's body to |stream|." | 140 // "2. Set |r|'s request's body to |stream|." |
141 // "3.If |Content-Type| is non-null and |r|'s request's header list | 141 // "3.If |Content-Type| is non-null and |r|'s request's header list |
142 // contains no header named `Content-Type`, append | 142 // contains no header named `Content-Type`, append |
143 // `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any | 143 // `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any |
144 // exception." | 144 // exception." |
145 r->setBodyBlobHandle(init.bodyBlobHandle); | 145 r->setBodyBlobHandle(init.bodyBlobHandle); |
146 if (!init.bodyBlobHandle->type().isEmpty() && !r->headers()->has("Conten
t-Type", exceptionState)) { | 146 if (!init.bodyBlobHandle->type().isEmpty() && !r->headers()->has("Conten
t-Type", exceptionState)) { |
147 r->headers()->append("Content-Type", init.bodyBlobHandle->type(), ex
ceptionState); | 147 r->headers()->append("Content-Type", init.bodyBlobHandle->type(), ex
ceptionState); |
148 } | 148 } |
149 if (exceptionState.hadException()) | 149 if (exceptionState.hadException()) |
150 return 0; | 150 return 0; |
151 } | 151 } |
152 // "18. Set |r|'s MIME type to the result of extracting a MIME type from | 152 // "19. Set |r|'s MIME type to the result of extracting a MIME type from |
153 // |r|'s request's header list." | 153 // |r|'s request's header list." |
154 // FIXME: We don't have MIME type in Request object yet. | 154 // FIXME: We don't have MIME type in Request object yet. |
155 | 155 |
156 // "19. Return |r|." | 156 // "20. Return |r|." |
157 return r; | 157 return r; |
158 } | 158 } |
159 | 159 |
160 } // namespace | 160 } // namespace |
161 | 161 |
162 Request* Request::create(ExecutionContext* context, const String& input, Excepti
onState& exceptionState) | 162 Request* Request::create(ExecutionContext* context, const String& input, Excepti
onState& exceptionState) |
163 { | 163 { |
164 return create(context, input, Dictionary(), exceptionState); | 164 return create(context, input, Dictionary(), exceptionState); |
165 } | 165 } |
166 | 166 |
167 Request* Request::create(ExecutionContext* context, const String& input, const D
ictionary& init, ExceptionState& exceptionState) | 167 Request* Request::create(ExecutionContext* context, const String& input, const D
ictionary& init, ExceptionState& exceptionState) |
168 { | 168 { |
169 // "1. Let |request| be |input|'s associated request, if |input| is a | 169 // "2. Let |request| be |input|'s associated request, if |input| is a |
170 // Request object, and a new request otherwise." | 170 // Request object, and a new request otherwise." |
171 FetchRequestData* request(FetchRequestData::create(context)); | 171 FetchRequestData* request(FetchRequestData::create(context)); |
172 // "2. Set |request| to a restricted copy of itself." | 172 // "3. Set |request| to a restricted copy of itself." |
173 request = request->createRestrictedCopy(context, SecurityOrigin::create(cont
ext->url())); | 173 request = request->createRestrictedCopy(context, SecurityOrigin::create(cont
ext->url())); |
174 // "5. If |input| is a string, run these substeps:" | 174 // "6. If |input| is a string, run these substeps:" |
175 // "1. Let |parsedURL| be the result of parsing |input| with entry settings | 175 // "1. Let |parsedURL| be the result of parsing |input| with entry settings |
176 // object's API base URL." | 176 // object's API base URL." |
177 KURL parsedURL = context->completeURL(input); | 177 KURL parsedURL = context->completeURL(input); |
178 // "2. If |parsedURL| is failure, throw a TypeError." | 178 // "2. If |parsedURL| is failure, throw a TypeError." |
179 if (!parsedURL.isValid()) { | 179 if (!parsedURL.isValid()) { |
180 exceptionState.throwTypeError("Invalid URL"); | 180 exceptionState.throwTypeError("Invalid URL"); |
181 return 0; | 181 return 0; |
182 } | 182 } |
183 // "3. Set |request|'s url to |parsedURL|." | 183 // "3. Set |request|'s url to |parsedURL|." |
184 request->setURL(parsedURL); | 184 request->setURL(parsedURL); |
185 // "4. Set |fallbackMode| to CORS." | 185 // "4. Set |fallbackMode| to CORS." |
186 // "5. Set |fallbackCredentials| to omit." | 186 // "5. Set |fallbackCredentials| to omit." |
187 return createRequestWithRequestData(context, request, RequestInit(context, i
nit, exceptionState), FetchRequestData::CORSMode, FetchRequestData::OmitCredenti
als, exceptionState); | 187 return createRequestWithRequestData(context, request, RequestInit(context, i
nit, exceptionState), FetchRequestData::CORSMode, FetchRequestData::OmitCredenti
als, exceptionState); |
188 } | 188 } |
189 | 189 |
190 Request* Request::create(ExecutionContext* context, Request* input, ExceptionSta
te& exceptionState) | 190 Request* Request::create(ExecutionContext* context, Request* input, ExceptionSta
te& exceptionState) |
191 { | 191 { |
192 return create(context, input, Dictionary(), exceptionState); | 192 return create(context, input, Dictionary(), exceptionState); |
193 } | 193 } |
194 | 194 |
195 Request* Request::create(ExecutionContext* context, Request* input, const Dictio
nary& init, ExceptionState& exceptionState) | 195 Request* Request::create(ExecutionContext* context, Request* input, const Dictio
nary& init, ExceptionState& exceptionState) |
196 { | 196 { |
197 // "1. Let |request| be |input|'s associated request, if |input| is a | 197 // "1. If input is a Request object, run these substeps:" |
| 198 // " 1. If input's used flag is set, throw a TypeError." |
| 199 // " 2. Set input's used flag." |
| 200 if (input->bodyUsed()) { |
| 201 exceptionState.throwTypeError( |
| 202 "Cannot construct a Request with a Request object that has already b
een used."); |
| 203 return 0; |
| 204 } |
| 205 input->setBodyUsed(); |
| 206 // "2. Let |request| be |input|'s associated request, if |input| is a |
198 // Request object, and a new request otherwise." | 207 // Request object, and a new request otherwise." |
199 // "2. Set |request| to a restricted copy of itself." | 208 // "3. Set |request| to a restricted copy of itself." |
200 FetchRequestData* request(input->request()->createRestrictedCopy(context, Se
curityOrigin::create(context->url()))); | 209 FetchRequestData* request(input->request()->createRestrictedCopy(context, Se
curityOrigin::create(context->url()))); |
201 // "3. Let |fallbackMode| be null." | 210 // "4. Let |fallbackMode| be null." |
202 // "4. Let |fallbackCredentials| be null." | 211 // "5. Let |fallbackCredentials| be null." |
203 // Instead of using null as a special fallback value, just pass the current | 212 // Instead of using null as a special fallback value, just pass the current |
204 // mode and credentials; it has the same effect. | 213 // mode and credentials; it has the same effect. |
205 const FetchRequestData::Mode currentMode = request->mode(); | 214 const FetchRequestData::Mode currentMode = request->mode(); |
206 const FetchRequestData::Credentials currentCredentials = request->credential
s(); | 215 const FetchRequestData::Credentials currentCredentials = request->credential
s(); |
207 return createRequestWithRequestData(context, request, RequestInit(context, i
nit, exceptionState), currentMode, currentCredentials, exceptionState); | 216 return createRequestWithRequestData(context, request, RequestInit(context, i
nit, exceptionState), currentMode, currentCredentials, exceptionState); |
208 } | 217 } |
209 | 218 |
210 Request* Request::create(ExecutionContext* context, FetchRequestData* request) | 219 Request* Request::create(ExecutionContext* context, FetchRequestData* request) |
211 { | 220 { |
212 Request* r = new Request(context, request); | 221 Request* r = new Request(context, request); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 } | 325 } |
317 | 326 |
318 void Request::trace(Visitor* visitor) | 327 void Request::trace(Visitor* visitor) |
319 { | 328 { |
320 Body::trace(visitor); | 329 Body::trace(visitor); |
321 visitor->trace(m_request); | 330 visitor->trace(m_request); |
322 visitor->trace(m_headers); | 331 visitor->trace(m_headers); |
323 } | 332 } |
324 | 333 |
325 } // namespace blink | 334 } // namespace blink |
OLD | NEW |