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

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

Issue 795323003: Move Fetch API releted code to modules/fetch. (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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "FetchResponseData.h"
7
8 #include "core/dom/DOMArrayBuffer.h"
9 #include "core/fetch/CrossOriginAccessControl.h"
10 #include "modules/serviceworkers/BodyStreamBuffer.h"
11 #include "modules/serviceworkers/FetchHeaderList.h"
12 #include "public/platform/WebServiceWorkerResponse.h"
13
14 namespace blink {
15
16 namespace {
17
18 WebServiceWorkerResponseType fetchTypeToWebType(FetchResponseData::Type fetchTyp e)
19 {
20 WebServiceWorkerResponseType webType = WebServiceWorkerResponseTypeDefault;
21 switch (fetchType) {
22 case FetchResponseData::BasicType:
23 webType = WebServiceWorkerResponseTypeBasic;
24 break;
25 case FetchResponseData::CORSType:
26 webType = WebServiceWorkerResponseTypeCORS;
27 break;
28 case FetchResponseData::DefaultType:
29 webType = WebServiceWorkerResponseTypeDefault;
30 break;
31 case FetchResponseData::ErrorType:
32 webType = WebServiceWorkerResponseTypeError;
33 break;
34 case FetchResponseData::OpaqueType:
35 webType = WebServiceWorkerResponseTypeOpaque;
36 break;
37 }
38 return webType;
39 }
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
98 } // namespace
99
100 FetchResponseData* FetchResponseData::create()
101 {
102 // "Unless stated otherwise, a response's url is null, status is 200, status
103 // message is `OK`, header list is an empty header list, and body is null."
104 return new FetchResponseData(DefaultType, 200, "OK");
105 }
106
107 FetchResponseData* FetchResponseData::createNetworkErrorResponse()
108 {
109 // "A network error is a response whose status is always 0, status message
110 // is always the empty byte sequence, header list is aways an empty list,
111 // and body is always null."
112 return new FetchResponseData(ErrorType, 0, "");
113 }
114
115 FetchResponseData* FetchResponseData::createWithBuffer(BodyStreamBuffer* buffer)
116 {
117 FetchResponseData* response = FetchResponseData::create();
118 response->m_buffer = buffer;
119 return response;
120 }
121
122 FetchResponseData* FetchResponseData::createBasicFilteredResponse()
123 {
124 // "A basic filtered response is a filtered response whose type is |basic|,
125 // header list excludes any headers in internal response's header list whose
126 // name is `Set-Cookie` or `Set-Cookie2`."
127 FetchResponseData* response = new FetchResponseData(BasicType, m_status, m_s tatusMessage);
128 response->m_url = m_url;
129 for (size_t i = 0; i < m_headerList->size(); ++i) {
130 const FetchHeaderList::Header* header = m_headerList->list()[i].get();
131 if (header->first == "set-cookie" || header->first == "set-cookie2")
132 continue;
133 response->m_headerList->append(header->first, header->second);
134 }
135 response->m_blobDataHandle = m_blobDataHandle;
136 response->m_buffer = m_buffer;
137 response->m_contentTypeForBuffer = m_contentTypeForBuffer;
138 response->m_internalResponse = this;
139 return response;
140 }
141
142 FetchResponseData* FetchResponseData::createCORSFilteredResponse()
143 {
144 // "A CORS filtered response is a filtered response whose type is |CORS|,
145 // header list excludes all headers in internal response's header list,
146 // except those whose name is either one of `Cache-Control`,
147 // `Content-Language`, `Content-Type`, `Expires`, `Last-Modified`, and
148 // `Pragma`, and except those whose name is one of the values resulting from
149 // parsing `Access-Control-Expose-Headers` in internal response's header
150 // list."
151 FetchResponseData* response = new FetchResponseData(CORSType, m_status, m_st atusMessage);
152 response->m_url = m_url;
153 HTTPHeaderSet accessControlExposeHeaderSet;
154 String accessControlExposeHeaders;
155 if (m_headerList->get("access-control-expose-headers", accessControlExposeHe aders))
156 parseAccessControlExposeHeadersAllowList(accessControlExposeHeaders, acc essControlExposeHeaderSet);
157 for (size_t i = 0; i < m_headerList->size(); ++i) {
158 const FetchHeaderList::Header* header = m_headerList->list()[i].get();
159 if (!isOnAccessControlResponseHeaderWhitelist(header->first) && !accessC ontrolExposeHeaderSet.contains(header->first))
160 continue;
161 response->m_headerList->append(header->first, header->second);
162 }
163 response->m_blobDataHandle = m_blobDataHandle;
164 response->m_buffer = m_buffer;
165 response->m_contentTypeForBuffer = m_contentTypeForBuffer;
166 response->m_internalResponse = this;
167 return response;
168 }
169
170 FetchResponseData* FetchResponseData::createOpaqueFilteredResponse()
171 {
172 // "An opaque filtered response is a filtered response whose type is
173 // |opaque|, status is 0, status message is the empty byte sequence, header
174 // list is an empty list, and body is null."
175 FetchResponseData* response = new FetchResponseData(OpaqueType, 0, "");
176 response->m_internalResponse = this;
177 return response;
178 }
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
243 void FetchResponseData::populateWebServiceWorkerResponse(WebServiceWorkerRespons e& response)
244 {
245 if (m_internalResponse) {
246 m_internalResponse->populateWebServiceWorkerResponse(response);
247 response.setResponseType(fetchTypeToWebType(m_type));
248 return;
249 }
250
251 response.setURL(url());
252 response.setStatus(status());
253 response.setStatusText(statusMessage());
254 response.setResponseType(fetchTypeToWebType(m_type));
255 for (size_t i = 0; i < headerList()->size(); ++i) {
256 const FetchHeaderList::Header* header = headerList()->list()[i].get();
257 response.appendHeader(header->first, header->second);
258 }
259 response.setBlobDataHandle(m_blobDataHandle);
260 }
261
262 FetchResponseData::FetchResponseData(Type type, unsigned short status, AtomicStr ing statusMessage)
263 : m_type(type)
264 , m_status(status)
265 , m_statusMessage(statusMessage)
266 , m_headerList(FetchHeaderList::create())
267 {
268 }
269
270 void FetchResponseData::setBlobDataHandle(PassRefPtr<BlobDataHandle> blobDataHan dle)
271 {
272 ASSERT(!m_buffer);
273 m_blobDataHandle = blobDataHandle;
274 }
275
276 void FetchResponseData::trace(Visitor* visitor)
277 {
278 visitor->trace(m_headerList);
279 visitor->trace(m_internalResponse);
280 visitor->trace(m_buffer);
281 }
282
283 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/serviceworkers/FetchResponseData.h ('k') | Source/modules/serviceworkers/FetchResponseDataTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698