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 12namespace blink { 13 14FetchResponseData* 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 21FetchResponseData* 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 29FetchResponseData* 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 47FetchResponseData* 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 73FetchResponseData* 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 83void 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 99FetchResponseData::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 107void FetchResponseData::trace(Visitor* visitor) 108{ 109 visitor->trace(m_headerList); 110 visitor->trace(m_internalResponse); 111} 112 113} // namespace blink 114