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

Side by Side Diff: Source/modules/serviceworkers/FetchResponseData.cpp

Issue 786893004: [ServiceWorker] Use BodyStreamBuffer as the body data of the Response object. (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
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 "FetchResponseData.h" 6 #include "FetchResponseData.h"
7 7
8 #include "core/dom/DOMArrayBuffer.h"
8 #include "core/fetch/CrossOriginAccessControl.h" 9 #include "core/fetch/CrossOriginAccessControl.h"
10 #include "modules/serviceworkers/BodyStreamBuffer.h"
9 #include "modules/serviceworkers/FetchHeaderList.h" 11 #include "modules/serviceworkers/FetchHeaderList.h"
10 #include "public/platform/WebServiceWorkerResponse.h" 12 #include "public/platform/WebServiceWorkerResponse.h"
11 13
12 namespace blink { 14 namespace blink {
13 15
14 namespace { 16 namespace {
15 17
16 WebServiceWorkerResponseType fetchTypeToWebType(FetchResponseData::Type fetchTyp e) 18 WebServiceWorkerResponseType fetchTypeToWebType(FetchResponseData::Type fetchTyp e)
17 { 19 {
18 WebServiceWorkerResponseType webType = WebServiceWorkerResponseTypeDefault; 20 WebServiceWorkerResponseType webType = WebServiceWorkerResponseTypeDefault;
(...skipping 10 matching lines...) Expand all
29 case FetchResponseData::ErrorType: 31 case FetchResponseData::ErrorType:
30 webType = WebServiceWorkerResponseTypeError; 32 webType = WebServiceWorkerResponseTypeError;
31 break; 33 break;
32 case FetchResponseData::OpaqueType: 34 case FetchResponseData::OpaqueType:
33 webType = WebServiceWorkerResponseTypeOpaque; 35 webType = WebServiceWorkerResponseTypeOpaque;
34 break; 36 break;
35 } 37 }
36 return webType; 38 return webType;
37 } 39 }
38 40
41 class StreamTeePump : public BodyStreamBuffer::Observer {
42 public:
43 StreamTeePump(BodyStreamBuffer* inBuffer, BodyStreamBuffer* outBuffer1, Body StreamBuffer* outBuffer2)
44 : m_inBuffer(inBuffer)
45 , m_outBuffer1(outBuffer1)
46 , m_outBuffer2(outBuffer2)
47 {
48 }
49 void onWrite() override
50 {
51 while (RefPtr<DOMArrayBuffer> buf = m_inBuffer->read()) {
52 m_outBuffer1->write(buf);
53 m_outBuffer2->write(buf);
54 }
55 }
56 void onClose() override
57 {
58 m_outBuffer1->close();
59 m_outBuffer2->close();
60 cleanup();
61 }
62 void onError() override
63 {
64 m_outBuffer1->error(m_inBuffer->exception());
65 m_outBuffer2->error(m_inBuffer->exception());
66 cleanup();
67 }
68 void trace(Visitor* visitor) override
69 {
70 BodyStreamBuffer::Observer::trace(visitor);
71 visitor->trace(m_inBuffer);
72 visitor->trace(m_outBuffer1);
73 visitor->trace(m_outBuffer2);
74 }
75 void start()
76 {
77 m_inBuffer->registerObserver(this);
78 onWrite();
79 if (m_inBuffer->hasError())
80 return onError();
81 if (m_inBuffer->isClosed())
82 return onClose();
83 }
84
85 private:
86 void cleanup()
87 {
88 m_inBuffer->unregisterObserver();
89 m_inBuffer.clear();
90 m_outBuffer1.clear();
91 m_outBuffer2.clear();
92 }
93 Member<BodyStreamBuffer> m_inBuffer;
94 Member<BodyStreamBuffer> m_outBuffer1;
95 Member<BodyStreamBuffer> m_outBuffer2;
96 };
97
39 } // namespace 98 } // namespace
40 99
41 FetchResponseData* FetchResponseData::create() 100 FetchResponseData* FetchResponseData::create()
42 { 101 {
43 // "Unless stated otherwise, a response's url is null, status is 200, status 102 // "Unless stated otherwise, a response's url is null, status is 200, status
44 // message is `OK`, header list is an empty header list, and body is null." 103 // message is `OK`, header list is an empty header list, and body is null."
45 return new FetchResponseData(DefaultType, 200, "OK"); 104 return new FetchResponseData(DefaultType, 200, "OK");
46 } 105 }
47 106
48 FetchResponseData* FetchResponseData::createNetworkErrorResponse() 107 FetchResponseData* FetchResponseData::createNetworkErrorResponse()
49 { 108 {
50 // "A network error is a response whose status is always 0, status message 109 // "A network error is a response whose status is always 0, status message
51 // is always the empty byte sequence, header list is aways an empty list, 110 // is always the empty byte sequence, header list is aways an empty list,
52 // and body is always null." 111 // and body is always null."
53 return new FetchResponseData(ErrorType, 0, ""); 112 return new FetchResponseData(ErrorType, 0, "");
54 } 113 }
55 114
115 FetchResponseData* FetchResponseData::createWithBuffer(BodyStreamBuffer* buffer)
116 {
117 FetchResponseData* response = FetchResponseData::create();
118 response->m_buffer = buffer;
119 return response;
120 }
121
56 FetchResponseData* FetchResponseData::createBasicFilteredResponse() 122 FetchResponseData* FetchResponseData::createBasicFilteredResponse()
57 { 123 {
58 // "A basic filtered response is a filtered response whose type is |basic|, 124 // "A basic filtered response is a filtered response whose type is |basic|,
59 // header list excludes any headers in internal response's header list whose 125 // header list excludes any headers in internal response's header list whose
60 // name is `Set-Cookie` or `Set-Cookie2`." 126 // name is `Set-Cookie` or `Set-Cookie2`."
61 FetchResponseData* response = new FetchResponseData(BasicType, m_status, m_s tatusMessage); 127 FetchResponseData* response = new FetchResponseData(BasicType, m_status, m_s tatusMessage);
62 response->m_url = m_url; 128 response->m_url = m_url;
63 for (size_t i = 0; i < m_headerList->size(); ++i) { 129 for (size_t i = 0; i < m_headerList->size(); ++i) {
64 const FetchHeaderList::Header* header = m_headerList->list()[i].get(); 130 const FetchHeaderList::Header* header = m_headerList->list()[i].get();
65 if (header->first == "set-cookie" || header->first == "set-cookie2") 131 if (header->first == "set-cookie" || header->first == "set-cookie2")
66 continue; 132 continue;
67 response->m_headerList->append(header->first, header->second); 133 response->m_headerList->append(header->first, header->second);
68 } 134 }
69 response->m_blobDataHandle = m_blobDataHandle; 135 response->m_blobDataHandle = m_blobDataHandle;
136 response->m_buffer = m_buffer;
137 response->m_contentTypeForBuffer = m_contentTypeForBuffer;
70 response->m_internalResponse = this; 138 response->m_internalResponse = this;
71 return response; 139 return response;
72 } 140 }
73 141
74 FetchResponseData* FetchResponseData::createCORSFilteredResponse() 142 FetchResponseData* FetchResponseData::createCORSFilteredResponse()
75 { 143 {
76 // "A CORS filtered response is a filtered response whose type is |CORS|, 144 // "A CORS filtered response is a filtered response whose type is |CORS|,
77 // header list excludes all headers in internal response's header list, 145 // header list excludes all headers in internal response's header list,
78 // except those whose name is either one of `Cache-Control`, 146 // except those whose name is either one of `Cache-Control`,
79 // `Content-Language`, `Content-Type`, `Expires`, `Last-Modified`, and 147 // `Content-Language`, `Content-Type`, `Expires`, `Last-Modified`, and
80 // `Pragma`, and except those whose name is one of the values resulting from 148 // `Pragma`, and except those whose name is one of the values resulting from
81 // parsing `Access-Control-Expose-Headers` in internal response's header 149 // parsing `Access-Control-Expose-Headers` in internal response's header
82 // list." 150 // list."
83 FetchResponseData* response = new FetchResponseData(CORSType, m_status, m_st atusMessage); 151 FetchResponseData* response = new FetchResponseData(CORSType, m_status, m_st atusMessage);
84 response->m_url = m_url; 152 response->m_url = m_url;
85 HTTPHeaderSet accessControlExposeHeaderSet; 153 HTTPHeaderSet accessControlExposeHeaderSet;
86 String accessControlExposeHeaders; 154 String accessControlExposeHeaders;
87 if (m_headerList->get("access-control-expose-headers", accessControlExposeHe aders)) 155 if (m_headerList->get("access-control-expose-headers", accessControlExposeHe aders))
88 parseAccessControlExposeHeadersAllowList(accessControlExposeHeaders, acc essControlExposeHeaderSet); 156 parseAccessControlExposeHeadersAllowList(accessControlExposeHeaders, acc essControlExposeHeaderSet);
89 for (size_t i = 0; i < m_headerList->size(); ++i) { 157 for (size_t i = 0; i < m_headerList->size(); ++i) {
90 const FetchHeaderList::Header* header = m_headerList->list()[i].get(); 158 const FetchHeaderList::Header* header = m_headerList->list()[i].get();
91 if (!isOnAccessControlResponseHeaderWhitelist(header->first) && !accessC ontrolExposeHeaderSet.contains(header->first)) 159 if (!isOnAccessControlResponseHeaderWhitelist(header->first) && !accessC ontrolExposeHeaderSet.contains(header->first))
92 continue; 160 continue;
93 response->m_headerList->append(header->first, header->second); 161 response->m_headerList->append(header->first, header->second);
94 } 162 }
95 response->m_blobDataHandle = m_blobDataHandle; 163 response->m_blobDataHandle = m_blobDataHandle;
164 response->m_buffer = m_buffer;
165 response->m_contentTypeForBuffer = m_contentTypeForBuffer;
96 response->m_internalResponse = this; 166 response->m_internalResponse = this;
97 return response; 167 return response;
98 } 168 }
99 169
100 FetchResponseData* FetchResponseData::createOpaqueFilteredResponse() 170 FetchResponseData* FetchResponseData::createOpaqueFilteredResponse()
101 { 171 {
102 // "An opaque filtered response is a filtered response whose type is 172 // "An opaque filtered response is a filtered response whose type is
103 // |opaque|, status is 0, status message is the empty byte sequence, header 173 // |opaque|, status is 0, status message is the empty byte sequence, header
104 // list is an empty list, and body is null." 174 // list is an empty list, and body is null."
105 FetchResponseData* response = new FetchResponseData(OpaqueType, 0, ""); 175 FetchResponseData* response = new FetchResponseData(OpaqueType, 0, "");
106 response->m_internalResponse = this; 176 response->m_internalResponse = this;
107 return response; 177 return response;
108 } 178 }
109 179
180 String FetchResponseData::contentTypeForBuffer() const
181 {
182 return m_contentTypeForBuffer;
183 }
184
185 PassRefPtr<BlobDataHandle> FetchResponseData::internalBlobDataHandle() const
186 {
187 if (m_internalResponse) {
188 return m_internalResponse->m_blobDataHandle;
189 }
190 return m_blobDataHandle;
191 }
192
193 BodyStreamBuffer* FetchResponseData::internalBuffer() const
194 {
195 if (m_internalResponse) {
196 return m_internalResponse->m_buffer;
197 }
198 return m_buffer;
199 }
200
201 String FetchResponseData::internalContentTypeForBuffer() const
202 {
203 if (m_internalResponse) {
204 return m_internalResponse->contentTypeForBuffer();
205 }
206 return m_contentTypeForBuffer;
207 }
208
209 FetchResponseData* FetchResponseData::clone()
210 {
211 FetchResponseData* newResponse = create();
212 newResponse->m_type = m_type;
213 if (m_terminationReason) {
214 newResponse->m_terminationReason = adoptPtr(new TerminationReason);
215 *newResponse->m_terminationReason = *m_terminationReason;
216 }
217 newResponse->m_url = m_url;
218 newResponse->m_status = m_status;
219 newResponse->m_statusMessage = m_statusMessage;
220 newResponse->m_headerList = m_headerList->createCopy();
221 newResponse->m_blobDataHandle = m_blobDataHandle;
222 newResponse->m_contentTypeForBuffer = m_contentTypeForBuffer;
223 if (!m_internalResponse) {
224 if (!m_buffer)
225 return newResponse;
226 BodyStreamBuffer* original = m_buffer;
227 m_buffer = new BodyStreamBuffer();
228 newResponse->m_buffer = new BodyStreamBuffer();
229 StreamTeePump* teePump = new StreamTeePump(original, m_buffer, newRespon se->m_buffer);
230 teePump->start();
231 return newResponse;
232 }
233
234 ASSERT(!m_buffer || m_buffer == m_internalResponse->m_buffer);
235 newResponse->m_internalResponse = m_internalResponse->clone();
236 if (m_buffer) {
237 m_buffer = m_internalResponse->m_buffer;
238 newResponse->m_buffer = newResponse->m_internalResponse->m_buffer;
239 }
240 return newResponse;
241 }
242
110 void FetchResponseData::populateWebServiceWorkerResponse(WebServiceWorkerRespons e& response) 243 void FetchResponseData::populateWebServiceWorkerResponse(WebServiceWorkerRespons e& response)
111 { 244 {
112 if (m_internalResponse) { 245 if (m_internalResponse) {
113 m_internalResponse->populateWebServiceWorkerResponse(response); 246 m_internalResponse->populateWebServiceWorkerResponse(response);
114 response.setResponseType(fetchTypeToWebType(m_type)); 247 response.setResponseType(fetchTypeToWebType(m_type));
115 return; 248 return;
116 } 249 }
117 250
118 response.setURL(url()); 251 response.setURL(url());
119 response.setStatus(status()); 252 response.setStatus(status());
120 response.setStatusText(statusMessage()); 253 response.setStatusText(statusMessage());
121 response.setResponseType(fetchTypeToWebType(m_type)); 254 response.setResponseType(fetchTypeToWebType(m_type));
122 for (size_t i = 0; i < headerList()->size(); ++i) { 255 for (size_t i = 0; i < headerList()->size(); ++i) {
123 const FetchHeaderList::Header* header = headerList()->list()[i].get(); 256 const FetchHeaderList::Header* header = headerList()->list()[i].get();
124 response.appendHeader(header->first, header->second); 257 response.appendHeader(header->first, header->second);
125 } 258 }
126 response.setBlobDataHandle(blobDataHandle()); 259 response.setBlobDataHandle(m_blobDataHandle);
127 } 260 }
128 261
129 FetchResponseData::FetchResponseData(Type type, unsigned short status, AtomicStr ing statusMessage) 262 FetchResponseData::FetchResponseData(Type type, unsigned short status, AtomicStr ing statusMessage)
130 : m_type(type) 263 : m_type(type)
131 , m_status(status) 264 , m_status(status)
132 , m_statusMessage(statusMessage) 265 , m_statusMessage(statusMessage)
133 , m_headerList(FetchHeaderList::create()) 266 , m_headerList(FetchHeaderList::create())
134 { 267 {
135 } 268 }
136 269
270 void FetchResponseData::setBlobDataHandle(PassRefPtr<BlobDataHandle> blobDataHan dle)
271 {
272 ASSERT(!m_buffer);
273 m_blobDataHandle = blobDataHandle;
274 }
275
137 void FetchResponseData::trace(Visitor* visitor) 276 void FetchResponseData::trace(Visitor* visitor)
138 { 277 {
139 visitor->trace(m_headerList); 278 visitor->trace(m_headerList);
140 visitor->trace(m_internalResponse); 279 visitor->trace(m_internalResponse);
280 visitor->trace(m_buffer);
141 } 281 }
142 282
143 } // namespace blink 283 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/serviceworkers/FetchResponseData.h ('k') | Source/modules/serviceworkers/Request.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698