| OLD | NEW |
| 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/FetchResponseData.h" | 5 #include "modules/fetch/FetchResponseData.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/ScriptState.h" | 7 #include "bindings/core/v8/ScriptState.h" |
| 8 #include "core/dom/DOMArrayBuffer.h" | 8 #include "core/dom/DOMArrayBuffer.h" |
| 9 #include "core/fetch/CrossOriginAccessControl.h" | |
| 10 #include "core/fetch/FetchUtils.h" | 9 #include "core/fetch/FetchUtils.h" |
| 11 #include "modules/fetch/BodyStreamBuffer.h" | 10 #include "modules/fetch/BodyStreamBuffer.h" |
| 12 #include "modules/fetch/DataConsumerHandleUtil.h" | 11 #include "modules/fetch/DataConsumerHandleUtil.h" |
| 13 #include "modules/fetch/FetchHeaderList.h" | 12 #include "modules/fetch/FetchHeaderList.h" |
| 14 #include "public/platform/modules/serviceworker/WebServiceWorkerResponse.h" | 13 #include "public/platform/modules/serviceworker/WebServiceWorkerResponse.h" |
| 15 | 14 |
| 16 namespace blink { | 15 namespace blink { |
| 17 | 16 |
| 18 namespace { | 17 namespace { |
| 19 | 18 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 36 case FetchResponseData::OpaqueType: | 35 case FetchResponseData::OpaqueType: |
| 37 webType = WebServiceWorkerResponseTypeOpaque; | 36 webType = WebServiceWorkerResponseTypeOpaque; |
| 38 break; | 37 break; |
| 39 case FetchResponseData::OpaqueRedirectType: | 38 case FetchResponseData::OpaqueRedirectType: |
| 40 webType = WebServiceWorkerResponseTypeOpaqueRedirect; | 39 webType = WebServiceWorkerResponseTypeOpaqueRedirect; |
| 41 break; | 40 break; |
| 42 } | 41 } |
| 43 return webType; | 42 return webType; |
| 44 } | 43 } |
| 45 | 44 |
| 45 WebVector<WebString> headerSetToWebVector(const HTTPHeaderSet& headers) |
| 46 { |
| 47 // Can't just pass *headers to the WebVector constructor because HashSet |
| 48 // iterators are not stl iterator compatible. |
| 49 WebVector<WebString> result(static_cast<size_t>(headers.size())); |
| 50 int idx = 0; |
| 51 for (const auto& header : headers) |
| 52 result[idx++] = header; |
| 53 return result; |
| 54 } |
| 55 |
| 46 } // namespace | 56 } // namespace |
| 47 | 57 |
| 48 FetchResponseData* FetchResponseData::create() | 58 FetchResponseData* FetchResponseData::create() |
| 49 { | 59 { |
| 50 // "Unless stated otherwise, a response's url is null, status is 200, status | 60 // "Unless stated otherwise, a response's url is null, status is 200, status |
| 51 // message is `OK`, header list is an empty header list, and body is null." | 61 // message is `OK`, header list is an empty header list, and body is null." |
| 52 return new FetchResponseData(DefaultType, 200, "OK"); | 62 return new FetchResponseData(DefaultType, 200, "OK"); |
| 53 } | 63 } |
| 54 | 64 |
| 55 FetchResponseData* FetchResponseData::createNetworkErrorResponse() | 65 FetchResponseData* FetchResponseData::createNetworkErrorResponse() |
| (...skipping 27 matching lines...) Expand all Loading... |
| 83 } | 93 } |
| 84 response->m_buffer = m_buffer; | 94 response->m_buffer = m_buffer; |
| 85 response->m_mimeType = m_mimeType; | 95 response->m_mimeType = m_mimeType; |
| 86 response->m_internalResponse = const_cast<FetchResponseData*>(this); | 96 response->m_internalResponse = const_cast<FetchResponseData*>(this); |
| 87 return response; | 97 return response; |
| 88 } | 98 } |
| 89 | 99 |
| 90 FetchResponseData* FetchResponseData::createCORSFilteredResponse() const | 100 FetchResponseData* FetchResponseData::createCORSFilteredResponse() const |
| 91 { | 101 { |
| 92 DCHECK_EQ(m_type, DefaultType); | 102 DCHECK_EQ(m_type, DefaultType); |
| 103 HTTPHeaderSet accessControlExposeHeaderSet; |
| 104 String accessControlExposeHeaders; |
| 105 if (m_headerList->get(HTTPNames::Access_Control_Expose_Headers, accessContro
lExposeHeaders)) |
| 106 parseAccessControlExposeHeadersAllowList(accessControlExposeHeaders, acc
essControlExposeHeaderSet); |
| 107 return createCORSFilteredResponse(accessControlExposeHeaderSet); |
| 108 } |
| 109 |
| 110 FetchResponseData* FetchResponseData::createCORSFilteredResponse(const HTTPHeade
rSet& exposedHeaders) const |
| 111 { |
| 112 DCHECK_EQ(m_type, DefaultType); |
| 93 // "A CORS filtered response is a filtered response whose type is |CORS|, | 113 // "A CORS filtered response is a filtered response whose type is |CORS|, |
| 94 // header list excludes all headers in internal response's header list, | 114 // header list excludes all headers in internal response's header list, |
| 95 // except those whose name is either one of `Cache-Control`, | 115 // except those whose name is either one of `Cache-Control`, |
| 96 // `Content-Language`, `Content-Type`, `Expires`, `Last-Modified`, and | 116 // `Content-Language`, `Content-Type`, `Expires`, `Last-Modified`, and |
| 97 // `Pragma`, and except those whose name is one of the values resulting from | 117 // `Pragma`, and except those whose name is one of the values resulting from |
| 98 // parsing `Access-Control-Expose-Headers` in internal response's header | 118 // parsing `Access-Control-Expose-Headers` in internal response's header |
| 99 // list." | 119 // list." |
| 100 FetchResponseData* response = new FetchResponseData(CORSType, m_status, m_st
atusMessage); | 120 FetchResponseData* response = new FetchResponseData(CORSType, m_status, m_st
atusMessage); |
| 101 response->m_url = m_url; | 121 response->m_url = m_url; |
| 102 HTTPHeaderSet accessControlExposeHeaderSet; | |
| 103 String accessControlExposeHeaders; | |
| 104 if (m_headerList->get("access-control-expose-headers", accessControlExposeHe
aders)) | |
| 105 parseAccessControlExposeHeadersAllowList(accessControlExposeHeaders, acc
essControlExposeHeaderSet); | |
| 106 for (size_t i = 0; i < m_headerList->size(); ++i) { | 122 for (size_t i = 0; i < m_headerList->size(); ++i) { |
| 107 const FetchHeaderList::Header* header = m_headerList->list()[i].get(); | 123 const FetchHeaderList::Header* header = m_headerList->list()[i].get(); |
| 108 const String& name = header->first; | 124 const String& name = header->first; |
| 109 if (isOnAccessControlResponseHeaderWhitelist(name) || (accessControlExpo
seHeaderSet.contains(name) && !FetchUtils::isForbiddenResponseHeaderName(name))) | 125 const bool explicitlyExposed = exposedHeaders.contains(name); |
| 126 if (isOnAccessControlResponseHeaderWhitelist(name) || (explicitlyExposed
&& !FetchUtils::isForbiddenResponseHeaderName(name))) { |
| 127 if (explicitlyExposed) |
| 128 response->m_corsExposedHeaderNames.add(name); |
| 110 response->m_headerList->append(name, header->second); | 129 response->m_headerList->append(name, header->second); |
| 130 } |
| 111 } | 131 } |
| 112 response->m_buffer = m_buffer; | 132 response->m_buffer = m_buffer; |
| 113 response->m_mimeType = m_mimeType; | 133 response->m_mimeType = m_mimeType; |
| 114 response->m_internalResponse = const_cast<FetchResponseData*>(this); | 134 response->m_internalResponse = const_cast<FetchResponseData*>(this); |
| 115 return response; | 135 return response; |
| 116 } | 136 } |
| 117 | 137 |
| 118 FetchResponseData* FetchResponseData::createOpaqueFilteredResponse() const | 138 FetchResponseData* FetchResponseData::createOpaqueFilteredResponse() const |
| 119 { | 139 { |
| 120 DCHECK_EQ(m_type, DefaultType); | 140 DCHECK_EQ(m_type, DefaultType); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 newResponse->m_terminationReason = adoptPtr(new TerminationReason); | 192 newResponse->m_terminationReason = adoptPtr(new TerminationReason); |
| 173 *newResponse->m_terminationReason = *m_terminationReason; | 193 *newResponse->m_terminationReason = *m_terminationReason; |
| 174 } | 194 } |
| 175 newResponse->m_url = m_url; | 195 newResponse->m_url = m_url; |
| 176 newResponse->m_status = m_status; | 196 newResponse->m_status = m_status; |
| 177 newResponse->m_statusMessage = m_statusMessage; | 197 newResponse->m_statusMessage = m_statusMessage; |
| 178 newResponse->m_headerList = m_headerList->clone(); | 198 newResponse->m_headerList = m_headerList->clone(); |
| 179 newResponse->m_mimeType = m_mimeType; | 199 newResponse->m_mimeType = m_mimeType; |
| 180 newResponse->m_responseTime = m_responseTime; | 200 newResponse->m_responseTime = m_responseTime; |
| 181 newResponse->m_cacheStorageCacheName = m_cacheStorageCacheName; | 201 newResponse->m_cacheStorageCacheName = m_cacheStorageCacheName; |
| 202 newResponse->m_corsExposedHeaderNames = m_corsExposedHeaderNames; |
| 182 | 203 |
| 183 switch (m_type) { | 204 switch (m_type) { |
| 184 case BasicType: | 205 case BasicType: |
| 185 case CORSType: | 206 case CORSType: |
| 186 ASSERT(m_internalResponse); | 207 ASSERT(m_internalResponse); |
| 187 ASSERT(m_buffer == m_internalResponse->m_buffer); | 208 ASSERT(m_buffer == m_internalResponse->m_buffer); |
| 188 ASSERT(m_internalResponse->m_type == DefaultType); | 209 ASSERT(m_internalResponse->m_type == DefaultType); |
| 189 newResponse->m_internalResponse = m_internalResponse->clone(scriptState)
; | 210 newResponse->m_internalResponse = m_internalResponse->clone(scriptState)
; |
| 190 m_buffer = m_internalResponse->m_buffer; | 211 m_buffer = m_internalResponse->m_buffer; |
| 191 newResponse->m_buffer = newResponse->m_internalResponse->m_buffer; | 212 newResponse->m_buffer = newResponse->m_internalResponse->m_buffer; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 214 break; | 235 break; |
| 215 } | 236 } |
| 216 return newResponse; | 237 return newResponse; |
| 217 } | 238 } |
| 218 | 239 |
| 219 void FetchResponseData::populateWebServiceWorkerResponse(WebServiceWorkerRespons
e& response) | 240 void FetchResponseData::populateWebServiceWorkerResponse(WebServiceWorkerRespons
e& response) |
| 220 { | 241 { |
| 221 if (m_internalResponse) { | 242 if (m_internalResponse) { |
| 222 m_internalResponse->populateWebServiceWorkerResponse(response); | 243 m_internalResponse->populateWebServiceWorkerResponse(response); |
| 223 response.setResponseType(fetchTypeToWebType(m_type)); | 244 response.setResponseType(fetchTypeToWebType(m_type)); |
| 245 response.setCorsExposedHeaderNames(headerSetToWebVector(m_corsExposedHea
derNames)); |
| 224 return; | 246 return; |
| 225 } | 247 } |
| 226 | 248 |
| 227 response.setURL(url()); | 249 response.setURL(url()); |
| 228 response.setStatus(status()); | 250 response.setStatus(status()); |
| 229 response.setStatusText(statusMessage()); | 251 response.setStatusText(statusMessage()); |
| 230 response.setResponseType(fetchTypeToWebType(m_type)); | 252 response.setResponseType(fetchTypeToWebType(m_type)); |
| 231 response.setResponseTime(responseTime()); | 253 response.setResponseTime(responseTime()); |
| 232 response.setCacheStorageCacheName(cacheStorageCacheName()); | 254 response.setCacheStorageCacheName(cacheStorageCacheName()); |
| 255 response.setCorsExposedHeaderNames(headerSetToWebVector(m_corsExposedHeaderN
ames)); |
| 233 for (size_t i = 0; i < headerList()->size(); ++i) { | 256 for (size_t i = 0; i < headerList()->size(); ++i) { |
| 234 const FetchHeaderList::Header* header = headerList()->list()[i].get(); | 257 const FetchHeaderList::Header* header = headerList()->list()[i].get(); |
| 235 response.appendHeader(header->first, header->second); | 258 response.appendHeader(header->first, header->second); |
| 236 } | 259 } |
| 237 } | 260 } |
| 238 | 261 |
| 239 FetchResponseData::FetchResponseData(Type type, unsigned short status, AtomicStr
ing statusMessage) | 262 FetchResponseData::FetchResponseData(Type type, unsigned short status, AtomicStr
ing statusMessage) |
| 240 : m_type(type) | 263 : m_type(type) |
| 241 , m_status(status) | 264 , m_status(status) |
| 242 , m_statusMessage(statusMessage) | 265 , m_statusMessage(statusMessage) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 258 } | 281 } |
| 259 | 282 |
| 260 DEFINE_TRACE(FetchResponseData) | 283 DEFINE_TRACE(FetchResponseData) |
| 261 { | 284 { |
| 262 visitor->trace(m_headerList); | 285 visitor->trace(m_headerList); |
| 263 visitor->trace(m_internalResponse); | 286 visitor->trace(m_internalResponse); |
| 264 visitor->trace(m_buffer); | 287 visitor->trace(m_buffer); |
| 265 } | 288 } |
| 266 | 289 |
| 267 } // namespace blink | 290 } // namespace blink |
| OLD | NEW |