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/fetch/CrossOriginAccessControl.h" 9 #include "modules/serviceworkers/FetchHeaderList.h" 10 #include "public/platform/WebServiceWorkerResponse.h" 11 12 namespace blink { 13 14 FetchResponseData* FetchResponseData::create() 15 { 16 // "Unless stated otherwise, a response's url is null, status is 200, status 17 // message is `OK`, header list is an empty header list, and body is null." 18 return new FetchResponseData(DefaultType, 200, "OK"); 19 } 20 21 FetchResponseData* FetchResponseData::createNetworkErrorResponse() 22 { 23 // "A network error is a response whose status is always 0, status message 24 // is always the empty byte sequence, header list is aways an empty list, 25 // and body is always null." 26 return new FetchResponseData(ErrorType, 0, ""); 27 } 28 29 FetchResponseData* FetchResponseData::createBasicFilteredResponse() 30 { 31 // "A basic filtered response is a filtered response whose type is |basic|, 32 // header list excludes any headers in internal response's header list whose 33 // name is `Set-Cookie` or `Set-Cookie2`." 34 FetchResponseData* response = new FetchResponseData(BasicType, m_status, m_statusMessage); 35 response->m_url = m_url; 36 for (size_t i = 0; i < m_headerList->size(); ++i) { 37 const FetchHeaderList::Header* header = m_headerList->list()[i].get(); 38 if (header->first == "set-cookie" || header->first == "set-cookie2") 39 continue; 40 response->m_headerList->append(header->first, header->second); 41 } 42 response->m_blobDataHandle = m_blobDataHandle; 43 response->m_internalResponse = this; 44 return response; 45 } 46 47 FetchResponseData* FetchResponseData::createCORSFilteredResponse() 48 { 49 // "A CORS filtered response is a filtered response whose type is |CORS|, 50 // header list excludes all headers in internal response's header list, 51 // except those whose name is either one of `Cache-Control`, 52 // `Content-Language`, `Content-Type`, `Expires`, `Last-Modified`, and 53 // `Pragma`, and except those whose name is one of the values resulting from 54 // parsing `Access-Control-Expose-Headers` in internal response's header 55 // list." 56 FetchResponseData* response = new FetchResponseData(CORSType, m_status, m_statusMessage); 57 response->m_url = m_url; 58 HTTPHeaderSet accessControlExposeHeaderSet; 59 String accessControlExposeHeaders; 60 if (m_headerList->get("access-control-expose-headers", accessControlExposeHeaders)) 61 parseAccessControlExposeHeadersAllowList(accessControlExposeHeaders, accessControlExposeHeaderSet); 62 for (size_t i = 0; i < m_headerList->size(); ++i) { 63 const FetchHeaderList::Header* header = m_headerList->list()[i].get(); 64 if (!isOnAccessControlResponseHeaderWhitelist(header->first) && !accessControlExposeHeaderSet.contains(header->first)) 65 continue; 66 response->m_headerList->append(header->first, header->second); 67 } 68 response->m_blobDataHandle = m_blobDataHandle; 69 response->m_internalResponse = this; 70 return response; 71 } 72 73 FetchResponseData* FetchResponseData::createOpaqueFilteredResponse() 74 { 75 // "An opaque filtered response is a filtered response whose type is 76 // |opaque|, status is 0, status message is the empty byte sequence, header 77 // list is an empty list, and body is null." 78 FetchResponseData* response = new FetchResponseData(OpaqueType, 0, ""); 79 response->m_internalResponse = this; 80 return response; 81 } 82 83 void FetchResponseData::populateWebServiceWorkerResponse(WebServiceWorkerResponse& response) 84 { 85 if (m_internalResponse) { 86 m_internalResponse->populateWebServiceWorkerResponse(response); 87 return; 88 } 89 response.setURL(url()); 90 response.setStatus(status()); 91 response.setStatusText(statusMessage()); 92 for (size_t i = 0; i < headerList()->size(); ++i) { 93 const FetchHeaderList::Header* header = headerList()->list()[i].get(); 94 response.appendHeader(header->first, header->second); 95 } 96 response.setBlobDataHandle(blobDataHandle()); 97 } 98 99 FetchResponseData::FetchResponseData(Type type, unsigned short status, AtomicString statusMessage) 100 : m_type(type) 101 , m_status(status) 102 , m_statusMessage(statusMessage) 103 , m_headerList(FetchHeaderList::create()) 104 { 105 } 106 107 void FetchResponseData::trace(Visitor* visitor) 108 { 109 visitor->trace(m_headerList); 110 visitor->trace(m_internalResponse); 111 } 112 113 } // namespace blink 114