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

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;
70 response->m_internalResponse = this; 137 response->m_internalResponse = this;
71 return response; 138 return response;
72 } 139 }
73 140
74 FetchResponseData* FetchResponseData::createCORSFilteredResponse() 141 FetchResponseData* FetchResponseData::createCORSFilteredResponse()
75 { 142 {
76 // "A CORS filtered response is a filtered response whose type is |CORS|, 143 // "A CORS filtered response is a filtered response whose type is |CORS|,
77 // header list excludes all headers in internal response's header list, 144 // header list excludes all headers in internal response's header list,
78 // except those whose name is either one of `Cache-Control`, 145 // except those whose name is either one of `Cache-Control`,
79 // `Content-Language`, `Content-Type`, `Expires`, `Last-Modified`, and 146 // `Content-Language`, `Content-Type`, `Expires`, `Last-Modified`, and
80 // `Pragma`, and except those whose name is one of the values resulting from 147 // `Pragma`, and except those whose name is one of the values resulting from
81 // parsing `Access-Control-Expose-Headers` in internal response's header 148 // parsing `Access-Control-Expose-Headers` in internal response's header
82 // list." 149 // list."
83 FetchResponseData* response = new FetchResponseData(CORSType, m_status, m_st atusMessage); 150 FetchResponseData* response = new FetchResponseData(CORSType, m_status, m_st atusMessage);
84 response->m_url = m_url; 151 response->m_url = m_url;
85 HTTPHeaderSet accessControlExposeHeaderSet; 152 HTTPHeaderSet accessControlExposeHeaderSet;
86 String accessControlExposeHeaders; 153 String accessControlExposeHeaders;
87 if (m_headerList->get("access-control-expose-headers", accessControlExposeHe aders)) 154 if (m_headerList->get("access-control-expose-headers", accessControlExposeHe aders))
88 parseAccessControlExposeHeadersAllowList(accessControlExposeHeaders, acc essControlExposeHeaderSet); 155 parseAccessControlExposeHeadersAllowList(accessControlExposeHeaders, acc essControlExposeHeaderSet);
89 for (size_t i = 0; i < m_headerList->size(); ++i) { 156 for (size_t i = 0; i < m_headerList->size(); ++i) {
90 const FetchHeaderList::Header* header = m_headerList->list()[i].get(); 157 const FetchHeaderList::Header* header = m_headerList->list()[i].get();
91 if (!isOnAccessControlResponseHeaderWhitelist(header->first) && !accessC ontrolExposeHeaderSet.contains(header->first)) 158 if (!isOnAccessControlResponseHeaderWhitelist(header->first) && !accessC ontrolExposeHeaderSet.contains(header->first))
92 continue; 159 continue;
93 response->m_headerList->append(header->first, header->second); 160 response->m_headerList->append(header->first, header->second);
94 } 161 }
95 response->m_blobDataHandle = m_blobDataHandle; 162 response->m_blobDataHandle = m_blobDataHandle;
163 response->m_buffer = m_buffer;
96 response->m_internalResponse = this; 164 response->m_internalResponse = this;
97 return response; 165 return response;
98 } 166 }
99 167
100 FetchResponseData* FetchResponseData::createOpaqueFilteredResponse() 168 FetchResponseData* FetchResponseData::createOpaqueFilteredResponse()
101 { 169 {
102 // "An opaque filtered response is a filtered response whose type is 170 // "An opaque filtered response is a filtered response whose type is
103 // |opaque|, status is 0, status message is the empty byte sequence, header 171 // |opaque|, status is 0, status message is the empty byte sequence, header
104 // list is an empty list, and body is null." 172 // list is an empty list, and body is null."
105 FetchResponseData* response = new FetchResponseData(OpaqueType, 0, ""); 173 FetchResponseData* response = new FetchResponseData(OpaqueType, 0, "");
106 response->m_internalResponse = this; 174 response->m_internalResponse = this;
107 return response; 175 return response;
108 } 176 }
109 177
178 PassRefPtr<BlobDataHandle> FetchResponseData::blobDataHandle(bool internal) cons t
179 {
180 if (internal && m_internalResponse) {
181 return m_internalResponse->m_blobDataHandle;
182 }
183 return m_blobDataHandle;
184 }
185
186 BodyStreamBuffer* FetchResponseData::buffer(bool internal) const
187 {
188 if (internal && m_internalResponse) {
189 return m_internalResponse->m_buffer;
190 }
191 return m_buffer;
192 }
193
194 FetchResponseData* FetchResponseData::clone()
195 {
196 FetchResponseData* newResponse = create();
197 newResponse->m_type = m_type;
198 if (m_terminationReason) {
199 newResponse->m_terminationReason = adoptPtr(new TerminationReason);
200 *newResponse->m_terminationReason = *m_terminationReason;
201 }
202 newResponse->m_url = m_url;
203 newResponse->m_status = m_status;
204 newResponse->m_statusMessage = m_statusMessage;
205 newResponse->m_headerList = m_headerList->createCopy();
206 newResponse->m_blobDataHandle = m_blobDataHandle;
207 if (!m_internalResponse) {
208 if (!m_buffer)
209 return newResponse;
210 BodyStreamBuffer* original = m_buffer;
211 m_buffer = new BodyStreamBuffer(original->contentType());
212 newResponse->m_buffer = new BodyStreamBuffer(original->contentType());
213 StreamTeePump* teePump = new StreamTeePump(original, m_buffer, newRespon se->m_buffer);
214 teePump->start();
215 return newResponse;
216 }
217
218 newResponse->m_internalResponse = m_internalResponse->clone();
219 if (m_buffer) {
220 m_buffer = m_internalResponse->m_buffer;
221 newResponse->m_buffer = newResponse->m_internalResponse->m_buffer;
222 }
223 return newResponse;
224 }
225
110 void FetchResponseData::populateWebServiceWorkerResponse(WebServiceWorkerRespons e& response) 226 void FetchResponseData::populateWebServiceWorkerResponse(WebServiceWorkerRespons e& response)
111 { 227 {
112 if (m_internalResponse) { 228 if (m_internalResponse) {
113 m_internalResponse->populateWebServiceWorkerResponse(response); 229 m_internalResponse->populateWebServiceWorkerResponse(response);
114 response.setResponseType(fetchTypeToWebType(m_type)); 230 response.setResponseType(fetchTypeToWebType(m_type));
115 return; 231 return;
116 } 232 }
117 233
118 response.setURL(url()); 234 response.setURL(url());
119 response.setStatus(status()); 235 response.setStatus(status());
120 response.setStatusText(statusMessage()); 236 response.setStatusText(statusMessage());
121 response.setResponseType(fetchTypeToWebType(m_type)); 237 response.setResponseType(fetchTypeToWebType(m_type));
122 for (size_t i = 0; i < headerList()->size(); ++i) { 238 for (size_t i = 0; i < headerList()->size(); ++i) {
123 const FetchHeaderList::Header* header = headerList()->list()[i].get(); 239 const FetchHeaderList::Header* header = headerList()->list()[i].get();
124 response.appendHeader(header->first, header->second); 240 response.appendHeader(header->first, header->second);
125 } 241 }
126 response.setBlobDataHandle(blobDataHandle()); 242 response.setBlobDataHandle(m_blobDataHandle);
127 } 243 }
128 244
129 FetchResponseData::FetchResponseData(Type type, unsigned short status, AtomicStr ing statusMessage) 245 FetchResponseData::FetchResponseData(Type type, unsigned short status, AtomicStr ing statusMessage)
130 : m_type(type) 246 : m_type(type)
131 , m_status(status) 247 , m_status(status)
132 , m_statusMessage(statusMessage) 248 , m_statusMessage(statusMessage)
133 , m_headerList(FetchHeaderList::create()) 249 , m_headerList(FetchHeaderList::create())
134 { 250 {
135 } 251 }
136 252
253 void FetchResponseData::setBlobDataHandle(PassRefPtr<BlobDataHandle> blobDataHan dle)
254 {
255 ASSERT(!m_buffer);
256 m_blobDataHandle = blobDataHandle;
257 }
258
137 void FetchResponseData::trace(Visitor* visitor) 259 void FetchResponseData::trace(Visitor* visitor)
138 { 260 {
139 visitor->trace(m_headerList); 261 visitor->trace(m_headerList);
140 visitor->trace(m_internalResponse); 262 visitor->trace(m_internalResponse);
263 visitor->trace(m_buffer);
141 } 264 }
142 265
143 } // namespace blink 266 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698