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

Side by Side Diff: third_party/WebKit/Source/modules/fetch/Response.cpp

Issue 1899873006: Make Response::body return v8-extra based stream behind flag (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@notify-locked-released
Patch Set: Created 4 years, 8 months 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
OLDNEW
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 "modules/fetch/Response.h" 5 #include "modules/fetch/Response.h"
6 6
7 #include "bindings/core/v8/Dictionary.h" 7 #include "bindings/core/v8/Dictionary.h"
8 #include "bindings/core/v8/ExceptionState.h" 8 #include "bindings/core/v8/ExceptionState.h"
9 #include "bindings/core/v8/ScriptState.h" 9 #include "bindings/core/v8/ScriptState.h"
10 #include "bindings/core/v8/V8ArrayBuffer.h" 10 #include "bindings/core/v8/V8ArrayBuffer.h"
(...skipping 16 matching lines...) Expand all
27 #include "platform/RuntimeEnabledFeatures.h" 27 #include "platform/RuntimeEnabledFeatures.h"
28 #include "platform/network/EncodedFormData.h" 28 #include "platform/network/EncodedFormData.h"
29 #include "platform/network/HTTPHeaderMap.h" 29 #include "platform/network/HTTPHeaderMap.h"
30 #include "public/platform/modules/serviceworker/WebServiceWorkerResponse.h" 30 #include "public/platform/modules/serviceworker/WebServiceWorkerResponse.h"
31 #include "wtf/RefPtr.h" 31 #include "wtf/RefPtr.h"
32 32
33 namespace blink { 33 namespace blink {
34 34
35 namespace { 35 namespace {
36 36
37 FetchResponseData* createFetchResponseDataFromWebResponse(ExecutionContext* exec utionContext, const WebServiceWorkerResponse& webResponse) 37 FetchResponseData* createFetchResponseDataFromWebResponse(ScriptState* scriptSta te, const WebServiceWorkerResponse& webResponse)
38 { 38 {
39 FetchResponseData* response = nullptr; 39 FetchResponseData* response = nullptr;
40 if (webResponse.status() > 0) 40 if (webResponse.status() > 0)
41 response = FetchResponseData::create(); 41 response = FetchResponseData::create();
42 else 42 else
43 response = FetchResponseData::createNetworkErrorResponse(); 43 response = FetchResponseData::createNetworkErrorResponse();
44 44
45 response->setURL(webResponse.url()); 45 response->setURL(webResponse.url());
46 response->setStatus(webResponse.status()); 46 response->setStatus(webResponse.status());
47 response->setStatusMessage(webResponse.statusText()); 47 response->setStatusMessage(webResponse.statusText());
48 response->setResponseTime(webResponse.responseTime()); 48 response->setResponseTime(webResponse.responseTime());
49 response->setCacheStorageCacheName(webResponse.cacheStorageCacheName()); 49 response->setCacheStorageCacheName(webResponse.cacheStorageCacheName());
50 50
51 for (HTTPHeaderMap::const_iterator i = webResponse.headers().begin(), end = webResponse.headers().end(); i != end; ++i) { 51 for (HTTPHeaderMap::const_iterator i = webResponse.headers().begin(), end = webResponse.headers().end(); i != end; ++i) {
52 response->headerList()->append(i->key, i->value); 52 response->headerList()->append(i->key, i->value);
53 } 53 }
54 54
55 response->replaceBodyStreamBuffer(new BodyStreamBuffer(FetchBlobDataConsumer Handle::create(executionContext, webResponse.blobDataHandle()))); 55 response->replaceBodyStreamBuffer(new BodyStreamBuffer(scriptState, FetchBlo bDataConsumerHandle::create(scriptState->getExecutionContext(), webResponse.blob DataHandle())));
56 56
57 // Filter the response according to |webResponse|'s ResponseType. 57 // Filter the response according to |webResponse|'s ResponseType.
58 switch (webResponse.responseType()) { 58 switch (webResponse.responseType()) {
59 case WebServiceWorkerResponseTypeBasic: 59 case WebServiceWorkerResponseTypeBasic:
60 response = response->createBasicFilteredResponse(); 60 response = response->createBasicFilteredResponse();
61 break; 61 break;
62 case WebServiceWorkerResponseTypeCORS: 62 case WebServiceWorkerResponseTypeCORS:
63 response = response->createCORSFilteredResponse(); 63 response = response->createCORSFilteredResponse();
64 break; 64 break;
65 case WebServiceWorkerResponseTypeOpaque: 65 case WebServiceWorkerResponseTypeOpaque:
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 || (0x80 <= c && c <= 0xFF))) // obs-text 102 || (0x80 <= c && c <= 0xFF))) // obs-text
103 return false; 103 return false;
104 } 104 }
105 return true; 105 return true;
106 } 106 }
107 107
108 } // namespace 108 } // namespace
109 109
110 Response* Response::create(ScriptState* scriptState, ExceptionState& exceptionSt ate) 110 Response* Response::create(ScriptState* scriptState, ExceptionState& exceptionSt ate)
111 { 111 {
112 return create(scriptState->getExecutionContext(), nullptr, String(), Respons eInit(), exceptionState); 112 return create(scriptState, nullptr, String(), ResponseInit(), exceptionState );
113 } 113 }
114 114
115 Response* Response::create(ScriptState* scriptState, ScriptValue bodyValue, cons t Dictionary& init, ExceptionState& exceptionState) 115 Response* Response::create(ScriptState* scriptState, ScriptValue bodyValue, cons t Dictionary& init, ExceptionState& exceptionState)
116 { 116 {
117 v8::Local<v8::Value> body = bodyValue.v8Value(); 117 v8::Local<v8::Value> body = bodyValue.v8Value();
118 ScriptValue reader; 118 ScriptValue reader;
119 v8::Isolate* isolate = scriptState->isolate(); 119 v8::Isolate* isolate = scriptState->isolate();
120 ExecutionContext* executionContext = scriptState->getExecutionContext(); 120 ExecutionContext* executionContext = scriptState->getExecutionContext();
121 121
122 OwnPtr<FetchDataConsumerHandle> bodyHandle; 122 OwnPtr<FetchDataConsumerHandle> bodyHandle;
(...skipping 26 matching lines...) Expand all
149 bodyHandle = ReadableStreamDataConsumerHandle::create(scriptState, r eader); 149 bodyHandle = ReadableStreamDataConsumerHandle::create(scriptState, r eader);
150 } 150 }
151 } else { 151 } else {
152 String string = toUSVString(isolate, body, exceptionState); 152 String string = toUSVString(isolate, body, exceptionState);
153 if (exceptionState.hadException()) 153 if (exceptionState.hadException())
154 return nullptr; 154 return nullptr;
155 bodyHandle = FetchFormDataConsumerHandle::create(string); 155 bodyHandle = FetchFormDataConsumerHandle::create(string);
156 contentType = "text/plain;charset=UTF-8"; 156 contentType = "text/plain;charset=UTF-8";
157 } 157 }
158 // TODO(yhirano): Add the URLSearchParams case. 158 // TODO(yhirano): Add the URLSearchParams case.
159 Response* response = create(executionContext, bodyHandle.release(), contentT ype, ResponseInit(init, exceptionState), exceptionState); 159 Response* response = create(scriptState, bodyHandle.release(), contentType, ResponseInit(init, exceptionState), exceptionState);
160 if (!exceptionState.hadException() && !reader.isEmpty()) { 160 if (!exceptionState.hadException() && !reader.isEmpty()) {
161 // Add a hidden reference so that the weak persistent in the 161 // Add a hidden reference so that the weak persistent in the
162 // ReadableStreamDataConsumerHandle will be valid as long as the 162 // ReadableStreamDataConsumerHandle will be valid as long as the
163 // Response is valid. 163 // Response is valid.
164 v8::Local<v8::Value> wrapper = toV8(response, scriptState); 164 v8::Local<v8::Value> wrapper = toV8(response, scriptState);
165 if (wrapper.IsEmpty()) { 165 if (wrapper.IsEmpty()) {
166 exceptionState.throwTypeError("Cannot create a Response wrapper"); 166 exceptionState.throwTypeError("Cannot create a Response wrapper");
167 return nullptr; 167 return nullptr;
168 } 168 }
169 ASSERT(wrapper->IsObject()); 169 ASSERT(wrapper->IsObject());
170 V8HiddenValue::setHiddenValue(scriptState, wrapper.As<v8::Object>(), V8H iddenValue::readableStreamReaderInResponse(scriptState->isolate()), reader.v8Val ue()); 170 V8HiddenValue::setHiddenValue(scriptState, wrapper.As<v8::Object>(), V8H iddenValue::readableStreamReaderInResponse(scriptState->isolate()), reader.v8Val ue());
171 } 171 }
172 return response; 172 return response;
173 } 173 }
174 174
175 Response* Response::create(ExecutionContext* context, PassOwnPtr<FetchDataConsum erHandle> bodyHandle, const String& contentType, const ResponseInit& init, Excep tionState& exceptionState) 175 Response* Response::create(ScriptState* scriptState, PassOwnPtr<FetchDataConsume rHandle> bodyHandle, const String& contentType, const ResponseInit& init, Except ionState& exceptionState)
176 { 176 {
177 unsigned short status = init.status; 177 unsigned short status = init.status;
178 178
179 // "1. If |init|'s status member is not in the range 200 to 599, inclusive, throw a 179 // "1. If |init|'s status member is not in the range 200 to 599, inclusive, throw a
180 // RangeError." 180 // RangeError."
181 if (status < 200 || 599 < status) { 181 if (status < 200 || 599 < status) {
182 exceptionState.throwRangeError(ExceptionMessages::indexOutsideRange<unsi gned>("status", status, 200, ExceptionMessages::InclusiveBound, 599, ExceptionMe ssages::InclusiveBound)); 182 exceptionState.throwRangeError(ExceptionMessages::indexOutsideRange<unsi gned>("status", status, 200, ExceptionMessages::InclusiveBound, 599, ExceptionMe ssages::InclusiveBound));
183 return nullptr; 183 return nullptr;
184 } 184 }
185 185
186 // "2. If |init|'s statusText member does not match the Reason-Phrase 186 // "2. If |init|'s statusText member does not match the Reason-Phrase
187 // token production, throw a TypeError." 187 // token production, throw a TypeError."
188 if (!isValidReasonPhrase(init.statusText)) { 188 if (!isValidReasonPhrase(init.statusText)) {
189 exceptionState.throwTypeError("Invalid statusText"); 189 exceptionState.throwTypeError("Invalid statusText");
190 return nullptr; 190 return nullptr;
191 } 191 }
192 192
193 // "3. Let |r| be a new Response object, associated with a new response, 193 // "3. Let |r| be a new Response object, associated with a new response,
194 // Headers object, and Body object." 194 // Headers object, and Body object."
195 Response* r = new Response(context); 195 Response* r = new Response(scriptState->getExecutionContext());
196 196
197 // "4. Set |r|'s response's status to |init|'s status member." 197 // "4. Set |r|'s response's status to |init|'s status member."
198 r->m_response->setStatus(init.status); 198 r->m_response->setStatus(init.status);
199 199
200 // "5. Set |r|'s response's status message to |init|'s statusText member." 200 // "5. Set |r|'s response's status message to |init|'s statusText member."
201 r->m_response->setStatusMessage(AtomicString(init.statusText)); 201 r->m_response->setStatusMessage(AtomicString(init.statusText));
202 202
203 // "6. If |init|'s headers member is present, run these substeps:" 203 // "6. If |init|'s headers member is present, run these substeps:"
204 if (init.headers) { 204 if (init.headers) {
205 // "1. Empty |r|'s response's header list." 205 // "1. Empty |r|'s response's header list."
(...skipping 23 matching lines...) Expand all
229 // contains no header named `Content-Type`, append `Content-Type`/ 229 // contains no header named `Content-Type`, append `Content-Type`/
230 // |Content-Type| to |r|'s response's header list." 230 // |Content-Type| to |r|'s response's header list."
231 // https://fetch.spec.whatwg.org/#concept-bodyinit-extract 231 // https://fetch.spec.whatwg.org/#concept-bodyinit-extract
232 // Step 3, Blob: 232 // Step 3, Blob:
233 // "If object's type attribute is not the empty byte sequence, set 233 // "If object's type attribute is not the empty byte sequence, set
234 // Content-Type to its value." 234 // Content-Type to its value."
235 if (isNullBodyStatus(status)) { 235 if (isNullBodyStatus(status)) {
236 exceptionState.throwTypeError("Response with null body status cannot have body"); 236 exceptionState.throwTypeError("Response with null body status cannot have body");
237 return nullptr; 237 return nullptr;
238 } 238 }
239 r->m_response->replaceBodyStreamBuffer(new BodyStreamBuffer(bodyHandle)) ; 239 r->m_response->replaceBodyStreamBuffer(new BodyStreamBuffer(scriptState, bodyHandle));
240 if (!contentType.isEmpty() && !r->m_response->headerList()->has("Content -Type")) 240 if (!contentType.isEmpty() && !r->m_response->headerList()->has("Content -Type"))
241 r->m_response->headerList()->append("Content-Type", contentType); 241 r->m_response->headerList()->append("Content-Type", contentType);
242 } 242 }
243 243
244 // "8. Set |r|'s MIME type to the result of extracting a MIME type 244 // "8. Set |r|'s MIME type to the result of extracting a MIME type
245 // from |r|'s response's header list." 245 // from |r|'s response's header list."
246 r->m_response->setMIMEType(r->m_response->headerList()->extractMIMEType()); 246 r->m_response->setMIMEType(r->m_response->headerList()->extractMIMEType());
247 247
248 // "9. Return |r|." 248 // "9. Return |r|."
249 return r; 249 return r;
250 } 250 }
251 251
252 Response* Response::create(ExecutionContext* context, FetchResponseData* respons e) 252 Response* Response::create(ExecutionContext* context, FetchResponseData* respons e)
253 { 253 {
254 return new Response(context, response); 254 return new Response(context, response);
255 } 255 }
256 256
257 Response* Response::create(ExecutionContext* context, const WebServiceWorkerResp onse& webResponse) 257 Response* Response::create(ScriptState* scriptState, const WebServiceWorkerRespo nse& webResponse)
258 { 258 {
259 FetchResponseData* responseData = createFetchResponseDataFromWebResponse(con text, webResponse); 259 FetchResponseData* responseData = createFetchResponseDataFromWebResponse(scr iptState, webResponse);
260 return new Response(context, responseData); 260 return new Response(scriptState->getExecutionContext(), responseData);
261 } 261 }
262 262
263 Response* Response::error(ExecutionContext* context) 263 Response* Response::error(ExecutionContext* context)
264 { 264 {
265 FetchResponseData* responseData = FetchResponseData::createNetworkErrorRespo nse(); 265 FetchResponseData* responseData = FetchResponseData::createNetworkErrorRespo nse();
266 Response* r = new Response(context, responseData); 266 Response* r = new Response(context, responseData);
267 r->m_headers->setGuard(Headers::ImmutableGuard); 267 r->m_headers->setGuard(Headers::ImmutableGuard);
268 return r; 268 return r;
269 } 269 }
270 270
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 // "The statusText attribute's getter must return response's status message. " 340 // "The statusText attribute's getter must return response's status message. "
341 return m_response->statusMessage(); 341 return m_response->statusMessage();
342 } 342 }
343 343
344 Headers* Response::headers() const 344 Headers* Response::headers() const
345 { 345 {
346 // "The headers attribute's getter must return the associated Headers object ." 346 // "The headers attribute's getter must return the associated Headers object ."
347 return m_headers; 347 return m_headers;
348 } 348 }
349 349
350 Response* Response::clone(ExceptionState& exceptionState) 350 Response* Response::clone(ScriptState* scriptState, ExceptionState& exceptionSta te)
351 { 351 {
352 if (isBodyLocked() || bodyUsed()) { 352 if (isBodyLocked() || bodyUsed()) {
353 exceptionState.throwTypeError("Response body is already used"); 353 exceptionState.throwTypeError("Response body is already used");
354 return nullptr; 354 return nullptr;
355 } 355 }
356 356
357 FetchResponseData* response = m_response->clone(getExecutionContext()); 357 FetchResponseData* response = m_response->clone(scriptState);
358 Headers* headers = Headers::create(response->headerList()); 358 Headers* headers = Headers::create(response->headerList());
359 headers->setGuard(m_headers->getGuard()); 359 headers->setGuard(m_headers->getGuard());
360 return new Response(getExecutionContext(), response, headers); 360 return new Response(getExecutionContext(), response, headers);
361 } 361 }
362 362
363 bool Response::hasPendingActivity() const 363 bool Response::hasPendingActivity() const
364 { 364 {
365 if (!getExecutionContext() || getExecutionContext()->activeDOMObjectsAreStop ped()) 365 if (!getExecutionContext() || getExecutionContext()->activeDOMObjectsAreStop ped())
366 return false; 366 return false;
367 if (!internalBodyBuffer()) 367 if (!internalBodyBuffer())
368 return false; 368 return false;
369 if (internalBodyBuffer()->hasPendingActivity()) 369 if (internalBodyBuffer()->hasPendingActivity())
370 return true; 370 return true;
371 return Body::hasPendingActivity(); 371 return Body::hasPendingActivity();
372 } 372 }
373 373
374 void Response::stop() 374 void Response::stop()
375 { 375 {
376 if (m_response->internalBuffer()) 376 if (m_response->internalBuffer())
377 m_response->internalBuffer()->stop(); 377 m_response->internalBuffer()->stop();
378 } 378 }
379 379
380 void Response::populateWebServiceWorkerResponse(WebServiceWorkerResponse& respon se) 380 void Response::populateWebServiceWorkerResponse(WebServiceWorkerResponse& respon se)
381 { 381 {
382 m_response->populateWebServiceWorkerResponse(response); 382 m_response->populateWebServiceWorkerResponse(response);
383 } 383 }
384 384
385 Response::Response(ExecutionContext* context) 385 Response::Response(ExecutionContext* context) : Response(context, FetchResponseD ata::create()) {}
386 : Body(context)
387 , m_response(FetchResponseData::create())
388 , m_headers(Headers::create(m_response->headerList()))
389 {
390 m_headers->setGuard(Headers::ResponseGuard);
391 }
392 386
393 Response::Response(ExecutionContext* context, FetchResponseData* response) 387 Response::Response(ExecutionContext* context, FetchResponseData* response)
394 : Body(context) 388 : Response(context, response, Headers::create(response->headerList()))
395 , m_response(response)
396 , m_headers(Headers::create(m_response->headerList()))
397 { 389 {
398 m_headers->setGuard(Headers::ResponseGuard); 390 m_headers->setGuard(Headers::ResponseGuard);
399 } 391 }
400 392
401 Response::Response(ExecutionContext* context, FetchResponseData* response, Heade rs* headers) 393 Response::Response(ExecutionContext* context, FetchResponseData* response, Heade rs* headers)
402 : Body(context) , m_response(response) , m_headers(headers) {} 394 : Body(context)
395 , m_response(response)
396 , m_headers(headers)
397 {
398 }
403 399
404 bool Response::hasBody() const 400 bool Response::hasBody() const
405 { 401 {
406 return m_response->internalBuffer(); 402 return m_response->internalBuffer();
407 } 403 }
408 404
409 bool Response::bodyUsed() 405 bool Response::bodyUsed()
410 { 406 {
411 return internalBodyBuffer() && internalBodyBuffer()->isStreamDisturbed(); 407 return internalBodyBuffer() && internalBodyBuffer()->isStreamDisturbed();
412 } 408 }
413 409
414 String Response::mimeType() const 410 String Response::mimeType() const
415 { 411 {
416 return m_response->mimeType(); 412 return m_response->mimeType();
417 } 413 }
418 414
419 String Response::internalMIMEType() const 415 String Response::internalMIMEType() const
420 { 416 {
421 return m_response->internalMIMEType(); 417 return m_response->internalMIMEType();
422 } 418 }
423 419
424 DEFINE_TRACE(Response) 420 DEFINE_TRACE(Response)
425 { 421 {
426 Body::trace(visitor); 422 Body::trace(visitor);
427 visitor->trace(m_response); 423 visitor->trace(m_response);
428 visitor->trace(m_headers); 424 visitor->trace(m_headers);
429 } 425 }
430 426
431 } // namespace blink 427 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698