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

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

Issue 1969333002: [Fetch API] |(new Response(stream)).body| should return |stream| (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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
« no previous file with comments | « third_party/WebKit/Source/modules/fetch/Response.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 return create(scriptState, nullptr, String(), ResponseInit(), 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 BodyStreamBuffer* bodyBuffer = nullptr;
123 String contentType; 123 String contentType;
124 if (bodyValue.isUndefined() || bodyValue.isNull()) { 124 if (bodyValue.isUndefined() || bodyValue.isNull()) {
125 // Note: The IDL processor cannot handle this situation. See 125 // Note: The IDL processor cannot handle this situation. See
126 // https://crbug.com/335871. 126 // https://crbug.com/335871.
127 } else if (V8Blob::hasInstance(body, isolate)) { 127 } else if (V8Blob::hasInstance(body, isolate)) {
128 Blob* blob = V8Blob::toImpl(body.As<v8::Object>()); 128 Blob* blob = V8Blob::toImpl(body.As<v8::Object>());
129 bodyHandle = FetchBlobDataConsumerHandle::create(executionContext, blob- >blobDataHandle()); 129 bodyBuffer = new BodyStreamBuffer(scriptState, FetchBlobDataConsumerHand le::create(executionContext, blob->blobDataHandle()));
130 contentType = blob->type(); 130 contentType = blob->type();
131 } else if (V8ArrayBuffer::hasInstance(body, isolate)) { 131 } else if (V8ArrayBuffer::hasInstance(body, isolate)) {
132 bodyHandle = FetchFormDataConsumerHandle::create(V8ArrayBuffer::toImpl(b ody.As<v8::Object>())); 132 bodyBuffer = new BodyStreamBuffer(scriptState, FetchFormDataConsumerHand le::create(V8ArrayBuffer::toImpl(body.As<v8::Object>())));
133 } else if (V8ArrayBufferView::hasInstance(body, isolate)) { 133 } else if (V8ArrayBufferView::hasInstance(body, isolate)) {
134 bodyHandle = FetchFormDataConsumerHandle::create(V8ArrayBufferView::toIm pl(body.As<v8::Object>())); 134 bodyBuffer = new BodyStreamBuffer(scriptState, FetchFormDataConsumerHand le::create(V8ArrayBufferView::toImpl(body.As<v8::Object>())));
135 } else if (V8FormData::hasInstance(body, isolate)) { 135 } else if (V8FormData::hasInstance(body, isolate)) {
136 RefPtr<EncodedFormData> formData = V8FormData::toImpl(body.As<v8::Object >())->encodeMultiPartFormData(); 136 RefPtr<EncodedFormData> formData = V8FormData::toImpl(body.As<v8::Object >())->encodeMultiPartFormData();
137 // Here we handle formData->boundary() as a C-style string. See 137 // Here we handle formData->boundary() as a C-style string. See
138 // FormDataEncoder::generateUniqueBoundaryString. 138 // FormDataEncoder::generateUniqueBoundaryString.
139 contentType = AtomicString("multipart/form-data; boundary=") + formData- >boundary().data(); 139 contentType = AtomicString("multipart/form-data; boundary=") + formData- >boundary().data();
140 bodyHandle = FetchFormDataConsumerHandle::create(executionContext, formD ata.release()); 140 bodyBuffer = new BodyStreamBuffer(scriptState, FetchFormDataConsumerHand le::create(executionContext, formData.release()));
141 } else if (RuntimeEnabledFeatures::responseConstructedWithReadableStreamEnab led() && ReadableStreamOperations::isReadableStream(scriptState, bodyValue)) { 141 } else if (RuntimeEnabledFeatures::responseConstructedWithReadableStreamEnab led() && ReadableStreamOperations::isReadableStream(scriptState, bodyValue)) {
142 bodyHandle = ReadableStreamDataConsumerHandle::create(scriptState, bodyV alue); 142 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
143 reader = ReadableStreamOperations::getReader(scriptState, bodyValue, exc eptionState); 143 bodyBuffer = new BodyStreamBuffer(scriptState, bodyValue);
144 if (exceptionState.hadException()) {
145 reader = ScriptValue();
146 bodyHandle = createFetchDataConsumerHandleFromWebHandle(createUnexpe ctedErrorDataConsumerHandle());
147 exceptionState.clearException();
148 } else { 144 } else {
149 bodyHandle = ReadableStreamDataConsumerHandle::create(scriptState, r eader); 145 OwnPtr<FetchDataConsumerHandle> bodyHandle;
146 reader = ReadableStreamOperations::getReader(scriptState, bodyValue, exceptionState);
147 if (exceptionState.hadException()) {
148 reader = ScriptValue();
149 bodyHandle = createFetchDataConsumerHandleFromWebHandle(createUn expectedErrorDataConsumerHandle());
150 exceptionState.clearException();
151 } else {
152 bodyHandle = ReadableStreamDataConsumerHandle::create(scriptStat e, reader);
153 }
154 bodyBuffer = new BodyStreamBuffer(scriptState, std::move(bodyHandle) );
150 } 155 }
151 } else { 156 } else {
152 String string = toUSVString(isolate, body, exceptionState); 157 String string = toUSVString(isolate, body, exceptionState);
153 if (exceptionState.hadException()) 158 if (exceptionState.hadException())
154 return nullptr; 159 return nullptr;
155 bodyHandle = FetchFormDataConsumerHandle::create(string); 160 bodyBuffer = new BodyStreamBuffer(scriptState, FetchFormDataConsumerHand le::create(string));
156 contentType = "text/plain;charset=UTF-8"; 161 contentType = "text/plain;charset=UTF-8";
157 } 162 }
158 // TODO(yhirano): Add the URLSearchParams case. 163 // TODO(yhirano): Add the URLSearchParams case.
159 Response* response = create(scriptState, std::move(bodyHandle), contentType, ResponseInit(init, exceptionState), exceptionState); 164 Response* response = create(scriptState, bodyBuffer, contentType, ResponseIn it(init, exceptionState), exceptionState);
160 if (!exceptionState.hadException() && !reader.isEmpty()) { 165 if (!exceptionState.hadException() && !reader.isEmpty()) {
161 // Add a hidden reference so that the weak persistent in the 166 // Add a hidden reference so that the weak persistent in the
162 // ReadableStreamDataConsumerHandle will be valid as long as the 167 // ReadableStreamDataConsumerHandle will be valid as long as the
163 // Response is valid. 168 // Response is valid.
164 v8::Local<v8::Value> wrapper = toV8(response, scriptState); 169 v8::Local<v8::Value> wrapper = toV8(response, scriptState);
165 if (wrapper.IsEmpty()) { 170 if (wrapper.IsEmpty()) {
166 exceptionState.throwTypeError("Cannot create a Response wrapper"); 171 exceptionState.throwTypeError("Cannot create a Response wrapper");
167 return nullptr; 172 return nullptr;
168 } 173 }
169 ASSERT(wrapper->IsObject()); 174 ASSERT(wrapper->IsObject());
170 V8HiddenValue::setHiddenValue(scriptState, wrapper.As<v8::Object>(), V8H iddenValue::readableStreamReaderInResponse(scriptState->isolate()), reader.v8Val ue()); 175 V8HiddenValue::setHiddenValue(scriptState, wrapper.As<v8::Object>(), V8H iddenValue::readableStreamReaderInResponse(scriptState->isolate()), reader.v8Val ue());
171 } 176 }
172 return response; 177 return response;
173 } 178 }
174 179
175 Response* Response::create(ScriptState* scriptState, PassOwnPtr<FetchDataConsume rHandle> bodyHandle, const String& contentType, const ResponseInit& init, Except ionState& exceptionState) 180 Response* Response::create(ScriptState* scriptState, BodyStreamBuffer* body, con st String& contentType, const ResponseInit& init, ExceptionState& exceptionState )
176 { 181 {
177 unsigned short status = init.status; 182 unsigned short status = init.status;
178 183
179 // "1. If |init|'s status member is not in the range 200 to 599, inclusive, throw a 184 // "1. If |init|'s status member is not in the range 200 to 599, inclusive, throw a
180 // RangeError." 185 // RangeError."
181 if (status < 200 || 599 < status) { 186 if (status < 200 || 599 < status) {
182 exceptionState.throwRangeError(ExceptionMessages::indexOutsideRange<unsi gned>("status", status, 200, ExceptionMessages::InclusiveBound, 599, ExceptionMe ssages::InclusiveBound)); 187 exceptionState.throwRangeError(ExceptionMessages::indexOutsideRange<unsi gned>("status", status, 200, ExceptionMessages::InclusiveBound, 599, ExceptionMe ssages::InclusiveBound));
183 return nullptr; 188 return nullptr;
184 } 189 }
185 190
(...skipping 26 matching lines...) Expand all
212 } else if (!init.headersDictionary.isUndefinedOrNull()) { 217 } else if (!init.headersDictionary.isUndefinedOrNull()) {
213 // "1. Empty |r|'s response's header list." 218 // "1. Empty |r|'s response's header list."
214 r->m_response->headerList()->clearList(); 219 r->m_response->headerList()->clearList();
215 // "2. Fill |r|'s Headers object with |init|'s headers member. Rethrow 220 // "2. Fill |r|'s Headers object with |init|'s headers member. Rethrow
216 // any exceptions." 221 // any exceptions."
217 r->m_headers->fillWith(init.headersDictionary, exceptionState); 222 r->m_headers->fillWith(init.headersDictionary, exceptionState);
218 if (exceptionState.hadException()) 223 if (exceptionState.hadException())
219 return nullptr; 224 return nullptr;
220 } 225 }
221 // "7. If body is given, run these substeps:" 226 // "7. If body is given, run these substeps:"
222 if (bodyHandle) { 227 if (body) {
223 // "1. If |init|'s status member is a null body status, throw a 228 // "1. If |init|'s status member is a null body status, throw a
224 // TypeError." 229 // TypeError."
225 // "2. Let |stream| and |Content-Type| be the result of extracting 230 // "2. Let |stream| and |Content-Type| be the result of extracting
226 // body." 231 // body."
227 // "3. Set |r|'s response's body to |stream|." 232 // "3. Set |r|'s response's body to |stream|."
228 // "4. If |Content-Type| is non-null and |r|'s response's header list 233 // "4. If |Content-Type| is non-null and |r|'s response's header list
229 // contains no header named `Content-Type`, append `Content-Type`/ 234 // contains no header named `Content-Type`, append `Content-Type`/
230 // |Content-Type| to |r|'s response's header list." 235 // |Content-Type| to |r|'s response's header list."
231 // https://fetch.spec.whatwg.org/#concept-bodyinit-extract 236 // https://fetch.spec.whatwg.org/#concept-bodyinit-extract
232 // Step 3, Blob: 237 // Step 3, Blob:
233 // "If object's type attribute is not the empty byte sequence, set 238 // "If object's type attribute is not the empty byte sequence, set
234 // Content-Type to its value." 239 // Content-Type to its value."
235 if (isNullBodyStatus(status)) { 240 if (isNullBodyStatus(status)) {
236 exceptionState.throwTypeError("Response with null body status cannot have body"); 241 exceptionState.throwTypeError("Response with null body status cannot have body");
237 return nullptr; 242 return nullptr;
238 } 243 }
239 r->m_response->replaceBodyStreamBuffer(new BodyStreamBuffer(scriptState, std::move(bodyHandle))); 244 r->m_response->replaceBodyStreamBuffer(body);
240 if (!contentType.isEmpty() && !r->m_response->headerList()->has("Content -Type")) 245 if (!contentType.isEmpty() && !r->m_response->headerList()->has("Content -Type"))
241 r->m_response->headerList()->append("Content-Type", contentType); 246 r->m_response->headerList()->append("Content-Type", contentType);
242 } 247 }
243 248
244 // "8. Set |r|'s MIME type to the result of extracting a MIME type 249 // "8. Set |r|'s MIME type to the result of extracting a MIME type
245 // from |r|'s response's header list." 250 // from |r|'s response's header list."
246 r->m_response->setMIMEType(r->m_response->headerList()->extractMIMEType()); 251 r->m_response->setMIMEType(r->m_response->headerList()->extractMIMEType());
247 252
248 // "9. Return |r|." 253 // "9. Return |r|."
249 return r; 254 return r;
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 } 417 }
413 418
414 DEFINE_TRACE(Response) 419 DEFINE_TRACE(Response)
415 { 420 {
416 Body::trace(visitor); 421 Body::trace(visitor);
417 visitor->trace(m_response); 422 visitor->trace(m_response);
418 visitor->trace(m_headers); 423 visitor->trace(m_headers);
419 } 424 }
420 425
421 } // namespace blink 426 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/fetch/Response.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698