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

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

Issue 1490243002: [Fetch API] Use FetchFormDataConsumerHandle in Response constructor. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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 | « 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 "config.h" 5 #include "config.h"
6 #include "modules/fetch/Response.h" 6 #include "modules/fetch/Response.h"
7 7
8 #include "bindings/core/v8/Dictionary.h" 8 #include "bindings/core/v8/Dictionary.h"
9 #include "bindings/core/v8/ExceptionState.h" 9 #include "bindings/core/v8/ExceptionState.h"
10 #include "core/dom/DOMArrayBuffer.h" 10 #include "core/dom/DOMArrayBuffer.h"
11 #include "core/dom/DOMArrayBufferView.h" 11 #include "core/dom/DOMArrayBufferView.h"
12 #include "core/fileapi/Blob.h" 12 #include "core/fileapi/Blob.h"
13 #include "core/html/FormData.h" 13 #include "core/html/FormData.h"
14 #include "modules/fetch/BodyStreamBuffer.h" 14 #include "modules/fetch/BodyStreamBuffer.h"
15 #include "modules/fetch/FetchBlobDataConsumerHandle.h" 15 #include "modules/fetch/FetchBlobDataConsumerHandle.h"
16 #include "modules/fetch/FetchFormDataConsumerHandle.h"
16 #include "modules/fetch/ResponseInit.h" 17 #include "modules/fetch/ResponseInit.h"
17 #include "platform/network/EncodedFormData.h" 18 #include "platform/network/EncodedFormData.h"
18 #include "platform/network/HTTPHeaderMap.h" 19 #include "platform/network/HTTPHeaderMap.h"
19 #include "public/platform/modules/serviceworker/WebServiceWorkerResponse.h" 20 #include "public/platform/modules/serviceworker/WebServiceWorkerResponse.h"
20 #include "wtf/RefPtr.h" 21 #include "wtf/RefPtr.h"
21 22
22 namespace blink { 23 namespace blink {
23 24
24 namespace { 25 namespace {
25 26
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 || (0x80 <= c && c <= 0xFF))) // obs-text 90 || (0x80 <= c && c <= 0xFF))) // obs-text
90 return false; 91 return false;
91 } 92 }
92 return true; 93 return true;
93 } 94 }
94 95
95 } 96 }
96 97
97 Response* Response::create(ExecutionContext* context, ExceptionState& exceptionS tate) 98 Response* Response::create(ExecutionContext* context, ExceptionState& exceptionS tate)
98 { 99 {
99 return create(context, nullptr, ResponseInit(), exceptionState); 100 return create(context, nullptr, String(), ResponseInit(), exceptionState);
100 } 101 }
101 102
102 Response* Response::create(ExecutionContext* context, const BodyInit& body, cons t Dictionary& responseInit, ExceptionState& exceptionState) 103 Response* Response::create(ExecutionContext* context, const BodyInit& body, cons t Dictionary& init, ExceptionState& exceptionState)
103 { 104 {
104 ASSERT(!body.isNull()); 105 ASSERT(!body.isNull());
105 if (body.isBlob()) 106 OwnPtr<FetchDataConsumerHandle> bodyHandle;
106 return create(context, body.getAsBlob(), ResponseInit(responseInit, exce ptionState), exceptionState); 107 String contentType;
107 if (body.isUSVString()) { 108 if (body.isBlob()) {
108 OwnPtr<BlobData> blobData = BlobData::create(); 109 bodyHandle = FetchBlobDataConsumerHandle::create(context, body.getAsBlob ()->blobDataHandle());
109 blobData->appendText(body.getAsUSVString(), false); 110 contentType = body.getAsBlob()->type();
110 // "Set |Content-Type| to `text/plain;charset=UTF-8`." 111 } else if (body.isUSVString()) {
111 blobData->setContentType("text/plain;charset=UTF-8"); 112 bodyHandle = FetchFormDataConsumerHandle::create(body.getAsUSVString());
112 const long long length = blobData->length(); 113 contentType = "text/plain;charset=UTF-8";
113 Blob* blob = Blob::create(BlobDataHandle::create(blobData.release(), len gth)); 114 } else if (body.isArrayBuffer()) {
114 return create(context, blob, ResponseInit(responseInit, exceptionState), exceptionState); 115 bodyHandle = FetchFormDataConsumerHandle::create(body.getAsArrayBuffer() );
116 } else if (body.isArrayBufferView()) {
117 bodyHandle = FetchFormDataConsumerHandle::create(body.getAsArrayBufferVi ew());
118 } else if (body.isFormData()) {
119 RefPtr<EncodedFormData> formData = body.getAsFormData()->encodeMultiPart FormData();
120 // Here we handle formData->boundary() as a C-style string. See
121 // FormDataEncoder::generateUniqueBoundaryString.
122 contentType = AtomicString("multipart/form-data; boundary=", AtomicStrin g::ConstructFromLiteral) + formData->boundary().data();
123 bodyHandle = FetchFormDataConsumerHandle::create(context, formData.relea se());
124 } else {
125 ASSERT_NOT_REACHED();
126 return nullptr;
115 } 127 }
116 if (body.isArrayBuffer()) { 128 return create(context, bodyHandle.release(), contentType, ResponseInit(init, exceptionState), exceptionState);
117 RefPtr<DOMArrayBuffer> arrayBuffer = body.getAsArrayBuffer();
118 OwnPtr<BlobData> blobData = BlobData::create();
119 blobData->appendBytes(arrayBuffer->data(), arrayBuffer->byteLength());
120 const long long length = blobData->length();
121 Blob* blob = Blob::create(BlobDataHandle::create(blobData.release(), len gth));
122 return create(context, blob, ResponseInit(responseInit, exceptionState), exceptionState);
123 }
124 if (body.isArrayBufferView()) {
125 RefPtr<DOMArrayBufferView> arrayBufferView = body.getAsArrayBufferView() ;
126 OwnPtr<BlobData> blobData = BlobData::create();
127 blobData->appendBytes(arrayBufferView->baseAddress(), arrayBufferView->b yteLength());
128 const long long length = blobData->length();
129 Blob* blob = Blob::create(BlobDataHandle::create(blobData.release(), len gth));
130 return create(context, blob, ResponseInit(responseInit, exceptionState), exceptionState);
131 }
132 if (body.isFormData()) {
133 FormData* domFormData = body.getAsFormData();
134 OwnPtr<BlobData> blobData = BlobData::create();
135 // FIXME: the same code exist in RequestInit::RequestInit().
136 RefPtr<EncodedFormData> httpBody = domFormData->encodeMultiPartFormData( );
137 for (size_t i = 0; i < httpBody->elements().size(); ++i) {
138 const FormDataElement& element = httpBody->elements()[i];
139 switch (element.m_type) {
140 case FormDataElement::data: {
141 blobData->appendBytes(element.m_data.data(), element.m_data.size ());
142 break;
143 }
144 case FormDataElement::encodedFile:
145 blobData->appendFile(element.m_filename, element.m_fileStart, el ement.m_fileLength, element.m_expectedFileModificationTime);
146 break;
147 case FormDataElement::encodedBlob:
148 if (element.m_optionalBlobDataHandle)
149 blobData->appendBlob(element.m_optionalBlobDataHandle, 0, el ement.m_optionalBlobDataHandle->size());
150 break;
151 case FormDataElement::encodedFileSystemURL:
152 blobData->appendFileSystemURL(element.m_fileSystemURL, element.m _fileStart, element.m_fileLength, element.m_expectedFileModificationTime);
153 break;
154 default:
155 ASSERT_NOT_REACHED();
156 }
157 }
158 blobData->setContentType(AtomicString("multipart/form-data; boundary=", AtomicString::ConstructFromLiteral) + httpBody->boundary().data());
159 const long long length = blobData->length();
160 Blob* blob = Blob::create(BlobDataHandle::create(blobData.release(), len gth));
161 return create(context, blob, ResponseInit(responseInit, exceptionState), exceptionState);
162 }
163 ASSERT_NOT_REACHED();
164 return nullptr;
165 } 129 }
166 130
167 Response* Response::create(ExecutionContext* context, Blob* body, const Response Init& responseInit, ExceptionState& exceptionState) 131 Response* Response::create(ExecutionContext* context, PassOwnPtr<FetchDataConsum erHandle> bodyHandle, const String& contentType, const ResponseInit& init, Excep tionState& exceptionState)
168 { 132 {
169 unsigned short status = responseInit.status; 133 unsigned short status = init.status;
170 134
171 // "1. If |init|'s status member is not in the range 200 to 599, inclusive, throw a 135 // "1. If |init|'s status member is not in the range 200 to 599, inclusive, throw a
172 // RangeError." 136 // RangeError."
173 if (status < 200 || 599 < status) { 137 if (status < 200 || 599 < status) {
174 exceptionState.throwRangeError(ExceptionMessages::indexOutsideRange<unsi gned>("status", status, 200, ExceptionMessages::InclusiveBound, 599, ExceptionMe ssages::InclusiveBound)); 138 exceptionState.throwRangeError(ExceptionMessages::indexOutsideRange<unsi gned>("status", status, 200, ExceptionMessages::InclusiveBound, 599, ExceptionMe ssages::InclusiveBound));
175 return 0; 139 return nullptr;
176 } 140 }
177 141
178 // "2. If |init|'s statusText member does not match the Reason-Phrase 142 // "2. If |init|'s statusText member does not match the Reason-Phrase
179 // token production, throw a TypeError." 143 // token production, throw a TypeError."
180 if (!isValidReasonPhrase(responseInit.statusText)) { 144 if (!isValidReasonPhrase(init.statusText)) {
181 exceptionState.throwTypeError("Invalid statusText"); 145 exceptionState.throwTypeError("Invalid statusText");
182 return 0; 146 return nullptr;
183 } 147 }
184 148
185 // "3. Let |r| be a new Response object, associated with a new response, 149 // "3. Let |r| be a new Response object, associated with a new response,
186 // Headers object, and Body object." 150 // Headers object, and Body object."
187 Response* r = new Response(context); 151 Response* r = new Response(context);
188 152
189 // "4. Set |r|'s response's status to |init|'s status member." 153 // "4. Set |r|'s response's status to |init|'s status member."
190 r->m_response->setStatus(responseInit.status); 154 r->m_response->setStatus(init.status);
191 155
192 // "5. Set |r|'s response's status message to |init|'s statusText member." 156 // "5. Set |r|'s response's status message to |init|'s statusText member."
193 r->m_response->setStatusMessage(AtomicString(responseInit.statusText)); 157 r->m_response->setStatusMessage(AtomicString(init.statusText));
194 158
195 // "6. If |init|'s headers member is present, run these substeps:" 159 // "6. If |init|'s headers member is present, run these substeps:"
196 if (responseInit.headers) { 160 if (init.headers) {
197 // "1. Empty |r|'s response's header list." 161 // "1. Empty |r|'s response's header list."
198 r->m_response->headerList()->clearList(); 162 r->m_response->headerList()->clearList();
199 // "2. Fill |r|'s Headers object with |init|'s headers member. Rethrow 163 // "2. Fill |r|'s Headers object with |init|'s headers member. Rethrow
200 // any exceptions." 164 // any exceptions."
201 r->m_headers->fillWith(responseInit.headers.get(), exceptionState); 165 r->m_headers->fillWith(init.headers.get(), exceptionState);
202 if (exceptionState.hadException()) 166 if (exceptionState.hadException())
203 return 0; 167 return nullptr;
204 } else if (!responseInit.headersDictionary.isUndefinedOrNull()) { 168 } else if (!init.headersDictionary.isUndefinedOrNull()) {
205 // "1. Empty |r|'s response's header list." 169 // "1. Empty |r|'s response's header list."
206 r->m_response->headerList()->clearList(); 170 r->m_response->headerList()->clearList();
207 // "2. Fill |r|'s Headers object with |init|'s headers member. Rethrow 171 // "2. Fill |r|'s Headers object with |init|'s headers member. Rethrow
208 // any exceptions." 172 // any exceptions."
209 r->m_headers->fillWith(responseInit.headersDictionary, exceptionState); 173 r->m_headers->fillWith(init.headersDictionary, exceptionState);
210 if (exceptionState.hadException()) 174 if (exceptionState.hadException())
211 return 0; 175 return nullptr;
212 } 176 }
213 // "7. If body is given, run these substeps:" 177 // "7. If body is given, run these substeps:"
214 if (body) { 178 if (bodyHandle) {
215 // "1. If |init|'s status member is a null body status, throw a TypeErro r." 179 // "1. If |init|'s status member is a null body status, throw a
216 // "2. Let |stream| and |Content-Type| be the result of extracting body. " 180 // TypeError."
181 // "2. Let |stream| and |Content-Type| be the result of extracting
182 // body."
217 // "3. Set |r|'s response's body to |stream|." 183 // "3. Set |r|'s response's body to |stream|."
218 // "4. If |Content-Type| is non-null and |r|'s response's header list 184 // "4. If |Content-Type| is non-null and |r|'s response's header list
219 // contains no header named `Content-Type`, append `Content-Type`/ 185 // contains no header named `Content-Type`, append `Content-Type`/
220 // |Content-Type| to |r|'s response's header list." 186 // |Content-Type| to |r|'s response's header list."
221 // https://fetch.spec.whatwg.org/#concept-bodyinit-extract 187 // https://fetch.spec.whatwg.org/#concept-bodyinit-extract
222 // Step 3, Blob: 188 // Step 3, Blob:
223 // "If object's type attribute is not the empty byte sequence, set 189 // "If object's type attribute is not the empty byte sequence, set
224 // Content-Type to its value." 190 // Content-Type to its value."
225 if (isNullBodyStatus(status)) { 191 if (isNullBodyStatus(status)) {
226 exceptionState.throwTypeError("Response with null body status cannot have body"); 192 exceptionState.throwTypeError("Response with null body status cannot have body");
227 return 0; 193 return nullptr;
228 } 194 }
229 r->m_response->replaceBodyStreamBuffer(new BodyStreamBuffer(FetchBlobDat aConsumerHandle::create(context, body->blobDataHandle()))); 195 r->m_response->replaceBodyStreamBuffer(new BodyStreamBuffer(bodyHandle)) ;
230 if (!body->type().isEmpty() && !r->m_response->headerList()->has("Conten t-Type")) 196 if (!contentType.isEmpty() && !r->m_response->headerList()->has("Content -Type"))
231 r->m_response->headerList()->append("Content-Type", body->type()); 197 r->m_response->headerList()->append("Content-Type", contentType);
232 } 198 }
233 199
234 // "8. Set |r|'s MIME type to the result of extracting a MIME type 200 // "8. Set |r|'s MIME type to the result of extracting a MIME type
235 // from |r|'s response's header list." 201 // from |r|'s response's header list."
236 r->m_response->setMIMEType(r->m_response->headerList()->extractMIMEType()); 202 r->m_response->setMIMEType(r->m_response->headerList()->extractMIMEType());
237 203
238 // "9. Return |r|." 204 // "9. Return |r|."
239 return r; 205 return r;
240 } 206 }
241 207
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 } 372 }
407 373
408 DEFINE_TRACE(Response) 374 DEFINE_TRACE(Response)
409 { 375 {
410 Body::trace(visitor); 376 Body::trace(visitor);
411 visitor->trace(m_response); 377 visitor->trace(m_response);
412 visitor->trace(m_headers); 378 visitor->trace(m_headers);
413 } 379 }
414 380
415 } // namespace blink 381 } // 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