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

Side by Side Diff: Source/modules/serviceworkers/Response.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/Response.h ('k') | Source/modules/serviceworkers/Response.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 "Response.h"
7
8 #include "bindings/core/v8/Dictionary.h"
9 #include "bindings/core/v8/ExceptionState.h"
10 #include "core/dom/DOMArrayBuffer.h"
11 #include "core/dom/DOMArrayBufferView.h"
12 #include "core/fileapi/Blob.h"
13 #include "modules/serviceworkers/ResponseInit.h"
14 #include "public/platform/WebServiceWorkerResponse.h"
15 #include "wtf/RefPtr.h"
16
17 namespace blink {
18
19 namespace {
20
21 FetchResponseData* createFetchResponseDataFromWebResponse(const WebServiceWorker Response& webResponse)
22 {
23 FetchResponseData* response = 0;
24 if (200 <= webResponse.status() && webResponse.status() < 300)
25 response = FetchResponseData::create();
26 else
27 response = FetchResponseData::createNetworkErrorResponse();
28
29 response->setURL(webResponse.url());
30 response->setStatus(webResponse.status());
31 response->setStatusMessage(webResponse.statusText());
32
33 for (HTTPHeaderMap::const_iterator i = webResponse.headers().begin(), end = webResponse.headers().end(); i != end; ++i) {
34 response->headerList()->append(i->key, i->value);
35 }
36
37 response->setBlobDataHandle(webResponse.blobDataHandle());
38
39 // Filter the response according to |webResponse|'s ResponseType.
40 switch (webResponse.responseType()) {
41 case WebServiceWorkerResponseTypeBasic:
42 response = response->createBasicFilteredResponse();
43 break;
44 case WebServiceWorkerResponseTypeCORS:
45 response = response->createCORSFilteredResponse();
46 break;
47 case WebServiceWorkerResponseTypeOpaque:
48 response = response->createOpaqueFilteredResponse();
49 break;
50 case WebServiceWorkerResponseTypeDefault:
51 break;
52 case WebServiceWorkerResponseTypeError:
53 ASSERT(response->type() == FetchResponseData::ErrorType);
54 break;
55 }
56
57 return response;
58 }
59
60 }
61
62 Response* Response::create(ExecutionContext* context, ExceptionState& exceptionS tate)
63 {
64 return create(context, nullptr, ResponseInit(), exceptionState);
65 }
66
67 Response* Response::create(ExecutionContext* context, const BodyInit& body, cons t Dictionary& responseInit, ExceptionState& exceptionState)
68 {
69 ASSERT(!body.isNull());
70 if (body.isBlob())
71 return create(context, body.getAsBlob(), ResponseInit(responseInit, exce ptionState), exceptionState);
72 if (body.isUSVString()) {
73 OwnPtr<BlobData> blobData = BlobData::create();
74 blobData->appendText(body.getAsUSVString(), false);
75 // "Set |Content-Type| to `text/plain;charset=UTF-8`."
76 blobData->setContentType("text/plain;charset=UTF-8");
77 const long long length = blobData->length();
78 Blob* blob = Blob::create(BlobDataHandle::create(blobData.release(), len gth));
79 return create(context, blob, ResponseInit(responseInit, exceptionState), exceptionState);
80 }
81 if (body.isArrayBuffer()) {
82 RefPtr<DOMArrayBuffer> arrayBuffer = body.getAsArrayBuffer();
83 OwnPtr<BlobData> blobData = BlobData::create();
84 blobData->appendBytes(arrayBuffer->data(), arrayBuffer->byteLength());
85 const long long length = blobData->length();
86 Blob* blob = Blob::create(BlobDataHandle::create(blobData.release(), len gth));
87 return create(context, blob, ResponseInit(responseInit, exceptionState), exceptionState);
88 }
89 if (body.isArrayBufferView()) {
90 RefPtr<DOMArrayBufferView> arrayBufferView = body.getAsArrayBufferView() ;
91 OwnPtr<BlobData> blobData = BlobData::create();
92 blobData->appendBytes(arrayBufferView->baseAddress(), arrayBufferView->b yteLength());
93 const long long length = blobData->length();
94 Blob* blob = Blob::create(BlobDataHandle::create(blobData.release(), len gth));
95 return create(context, blob, ResponseInit(responseInit, exceptionState), exceptionState);
96 }
97 ASSERT_NOT_REACHED();
98 return nullptr;
99 }
100
101 Response* Response::create(ExecutionContext* context, Blob* body, const Response Init& responseInit, ExceptionState& exceptionState)
102 {
103 // "1. If |init|'s status member is not in the range 200 to 599, throw a
104 // RangeError."
105 if (responseInit.status < 200 || 599 < responseInit.status) {
106 exceptionState.throwRangeError("Invalid status");
107 return 0;
108 }
109
110 // FIXME: "2. If |init|'s statusText member does not match the Reason-Phrase
111 // token production, throw a TypeError."
112
113 // "3. Let |r| be a new Response object, associated with a new response,
114 // Headers object, and Body object."
115 Response* r = new Response(context);
116 r->suspendIfNeeded();
117
118 // "4. Set |r|'s response's status to |init|'s status member."
119 r->m_response->setStatus(responseInit.status);
120
121 // "5. Set |r|'s response's status message to |init|'s statusText member."
122 r->m_response->setStatusMessage(AtomicString(responseInit.statusText));
123
124 // "6. If |init|'s headers member is present, run these substeps:"
125 if (responseInit.headers) {
126 // "1. Empty |r|'s response's header list."
127 r->m_response->headerList()->clearList();
128 // "2. Fill |r|'s Headers object with |init|'s headers member. Rethrow
129 // any exceptions."
130 r->m_headers->fillWith(responseInit.headers.get(), exceptionState);
131 if (exceptionState.hadException())
132 return 0;
133 } else if (!responseInit.headersDictionary.isUndefinedOrNull()) {
134 // "1. Empty |r|'s response's header list."
135 r->m_response->headerList()->clearList();
136 // "2. Fill |r|'s Headers object with |init|'s headers member. Rethrow
137 // any exceptions."
138 r->m_headers->fillWith(responseInit.headersDictionary, exceptionState);
139 if (exceptionState.hadException())
140 return 0;
141 }
142 // "7. If body is given, run these substeps:"
143 if (body) {
144 // "1. Let |stream| and |Content-Type| be the result of extracting body. "
145 // "2. Set |r|'s response's body to |stream|."
146 // "3. If |Content-Type| is non-null and |r|'s response's header list
147 // contains no header named `Content-Type`, append `Content-Type`/
148 // |Content-Type| to |r|'s response's header list."
149 r->m_response->setBlobDataHandle(body->blobDataHandle());
150 if (!body->type().isNull() && !r->m_response->headerList()->has("Content -Type"))
151 r->m_response->headerList()->append("Content-Type", body->type());
152 }
153
154 // FIXME: "8. Set |r|'s MIME type to the result of extracting a MIME type
155 // from |r|'s response's header list."
156
157 // "9. Return |r|."
158 return r;
159 }
160
161 Response* Response::create(ExecutionContext* context, FetchResponseData* respons e)
162 {
163 Response* r = new Response(context, response);
164 r->suspendIfNeeded();
165 return r;
166 }
167
168 Response* Response::create(ExecutionContext* context, const WebServiceWorkerResp onse& webResponse)
169 {
170 FetchResponseData* responseData = createFetchResponseDataFromWebResponse(web Response);
171 Response* r = new Response(context, responseData);
172 r->suspendIfNeeded();
173 return r;
174 }
175
176 Response* Response::createClone(const Response& cloneFrom)
177 {
178 Response* r = new Response(cloneFrom);
179 r->suspendIfNeeded();
180 return r;
181 }
182
183 String Response::type() const
184 {
185 // "The type attribute's getter must return response's type."
186 switch (m_response->type()) {
187 case FetchResponseData::BasicType:
188 return "basic";
189 case FetchResponseData::CORSType:
190 return "cors";
191 case FetchResponseData::DefaultType:
192 return "default";
193 case FetchResponseData::ErrorType:
194 return "error";
195 case FetchResponseData::OpaqueType:
196 return "opaque";
197 }
198 ASSERT_NOT_REACHED();
199 return "";
200 }
201
202 String Response::url() const
203 {
204 // "The url attribute's getter must return the empty string if response's
205 // url is null and response's url, serialized with the exclude fragment
206 // flag set, otherwise."
207 if (!m_response->url().hasFragmentIdentifier())
208 return m_response->url();
209 KURL url(m_response->url());
210 url.removeFragmentIdentifier();
211 return url;
212 }
213
214 unsigned short Response::status() const
215 {
216 // "The status attribute's getter must return response's status."
217 return m_response->status();
218 }
219
220 String Response::statusText() const
221 {
222 // "The statusText attribute's getter must return response's status message. "
223 return m_response->statusMessage();
224 }
225
226 Headers* Response::headers() const
227 {
228 // "The headers attribute's getter must return the associated Headers object ."
229 return m_headers;
230 }
231
232 Response* Response::clone(ExceptionState& exceptionState) const
233 {
234 if (bodyUsed()) {
235 exceptionState.throwTypeError("Response body is already used");
236 return nullptr;
237 }
238 if (streamAccessed()) {
239 // FIXME: Support clone() of the stream accessed Response.
240 exceptionState.throwTypeError("clone() of the Response which .body is ac cessed is not supported.");
241 return nullptr;
242 }
243 return Response::createClone(*this);
244 }
245
246 void Response::populateWebServiceWorkerResponse(WebServiceWorkerResponse& respon se)
247 {
248 m_response->populateWebServiceWorkerResponse(response);
249 }
250
251 Response::Response(ExecutionContext* context)
252 : Body(context)
253 , m_response(FetchResponseData::create())
254 , m_headers(Headers::create(m_response->headerList()))
255 {
256 m_headers->setGuard(Headers::ResponseGuard);
257 }
258
259 Response::Response(const Response& clone_from)
260 : Body(clone_from)
261 , m_response(clone_from.m_response->clone())
262 , m_headers(Headers::create(m_response->headerList()))
263 {
264 }
265
266 Response::Response(ExecutionContext* context, FetchResponseData* response)
267 : Body(context)
268 , m_response(response)
269 , m_headers(Headers::create(m_response->headerList()))
270 {
271 m_headers->setGuard(Headers::ResponseGuard);
272 }
273
274 bool Response::hasBody() const
275 {
276 return internalBlobDataHandle() || internalBuffer();
277 }
278
279 PassRefPtr<BlobDataHandle> Response::blobDataHandle() const
280 {
281 return m_response->blobDataHandle();
282 }
283
284 BodyStreamBuffer* Response::buffer() const
285 {
286 return m_response->buffer();
287 }
288
289 String Response::contentTypeForBuffer() const
290 {
291 return m_response->contentTypeForBuffer();
292 }
293
294 PassRefPtr<BlobDataHandle> Response::internalBlobDataHandle() const
295 {
296 return m_response->internalBlobDataHandle();
297 }
298
299 BodyStreamBuffer* Response::internalBuffer() const
300 {
301 return m_response->internalBuffer();
302 }
303
304 String Response::internalContentTypeForBuffer() const
305 {
306 return m_response->internalContentTypeForBuffer();
307 }
308
309 void Response::trace(Visitor* visitor)
310 {
311 Body::trace(visitor);
312 visitor->trace(m_response);
313 visitor->trace(m_headers);
314 }
315
316 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/serviceworkers/Response.h ('k') | Source/modules/serviceworkers/Response.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698