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.
6 #include "FetchResponseData.h"
8 #include "core/fetch/CrossOriginAccessControl.h"
9 #include "modules/serviceworkers/FetchHeaderList.h"
10 #include "public/platform/WebServiceWorkerResponse.h"
16 WebServiceWorkerResponseType fetchTypeToWebType(FetchResponseData::Type fetchType)
18 WebServiceWorkerResponseType webType = WebServiceWorkerResponseTypeDefault;
20 case FetchResponseData::BasicType:
21 webType = WebServiceWorkerResponseTypeBasic;
23 case FetchResponseData::CORSType:
24 webType = WebServiceWorkerResponseTypeCORS;
26 case FetchResponseData::DefaultType:
27 webType = WebServiceWorkerResponseTypeDefault;
29 case FetchResponseData::ErrorType:
30 webType = WebServiceWorkerResponseTypeError;
32 case FetchResponseData::OpaqueType:
33 webType = WebServiceWorkerResponseTypeOpaque;
41 FetchResponseData* FetchResponseData::create()
43 // "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."
45 return new FetchResponseData(DefaultType, 200, "OK");
48 FetchResponseData* FetchResponseData::createNetworkErrorResponse()
50 // "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,
52 // and body is always null."
53 return new FetchResponseData(ErrorType, 0, "");
56 FetchResponseData* FetchResponseData::createBasicFilteredResponse()
58 // "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
60 // name is `Set-Cookie` or `Set-Cookie2`."
61 FetchResponseData* response = new FetchResponseData(BasicType, m_status, m_statusMessage);
62 response->m_url = m_url;
63 for (size_t i = 0; i < m_headerList->size(); ++i) {
64 const FetchHeaderList::Header* header = m_headerList->list()[i].get();
65 if (header->first == "set-cookie" || header->first == "set-cookie2")
67 response->m_headerList->append(header->first, header->second);
69 response->m_blobDataHandle = m_blobDataHandle;
70 response->m_internalResponse = this;
74 FetchResponseData* FetchResponseData::createCORSFilteredResponse()
76 // "A CORS filtered response is a filtered response whose type is |CORS|,
77 // header list excludes all headers in internal response's header list,
78 // except those whose name is either one of `Cache-Control`,
79 // `Content-Language`, `Content-Type`, `Expires`, `Last-Modified`, and
80 // `Pragma`, and except those whose name is one of the values resulting from
81 // parsing `Access-Control-Expose-Headers` in internal response's header
83 FetchResponseData* response = new FetchResponseData(CORSType, m_status, m_statusMessage);
84 response->m_url = m_url;
85 HTTPHeaderSet accessControlExposeHeaderSet;
86 String accessControlExposeHeaders;
87 if (m_headerList->get("access-control-expose-headers", accessControlExposeHeaders))
88 parseAccessControlExposeHeadersAllowList(accessControlExposeHeaders, accessControlExposeHeaderSet);
89 for (size_t i = 0; i < m_headerList->size(); ++i) {
90 const FetchHeaderList::Header* header = m_headerList->list()[i].get();
91 if (!isOnAccessControlResponseHeaderWhitelist(header->first) && !accessControlExposeHeaderSet.contains(header->first))
93 response->m_headerList->append(header->first, header->second);
95 response->m_blobDataHandle = m_blobDataHandle;
96 response->m_internalResponse = this;
100 FetchResponseData* FetchResponseData::createOpaqueFilteredResponse()
102 // "An opaque filtered response is a filtered response whose type is
103 // |opaque|, status is 0, status message is the empty byte sequence, header
104 // list is an empty list, and body is null."
105 FetchResponseData* response = new FetchResponseData(OpaqueType, 0, "");
106 response->m_internalResponse = this;
110 void FetchResponseData::populateWebServiceWorkerResponse(WebServiceWorkerResponse& response)
112 if (m_internalResponse) {
113 m_internalResponse->populateWebServiceWorkerResponse(response);
114 response.setResponseType(fetchTypeToWebType(m_type));
118 response.setURL(url());
119 response.setStatus(status());
120 response.setStatusText(statusMessage());
121 response.setResponseType(fetchTypeToWebType(m_type));
122 for (size_t i = 0; i < headerList()->size(); ++i) {
123 const FetchHeaderList::Header* header = headerList()->list()[i].get();
124 response.appendHeader(header->first, header->second);
126 response.setBlobDataHandle(blobDataHandle());
129 FetchResponseData::FetchResponseData(Type type, unsigned short status, AtomicString statusMessage)
132 , m_statusMessage(statusMessage)
133 , m_headerList(FetchHeaderList::create())
137 void FetchResponseData::trace(Visitor* visitor)
139 visitor->trace(m_headerList);
140 visitor->trace(m_internalResponse);