Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / serviceworkers / FetchResponseData.cpp
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 namespace {
15
16 WebServiceWorkerResponseType fetchTypeToWebType(FetchResponseData::Type fetchType)
17 {
18     WebServiceWorkerResponseType webType = WebServiceWorkerResponseTypeDefault;
19     switch (fetchType) {
20     case FetchResponseData::BasicType:
21         webType = WebServiceWorkerResponseTypeBasic;
22         break;
23     case FetchResponseData::CORSType:
24         webType = WebServiceWorkerResponseTypeCORS;
25         break;
26     case FetchResponseData::DefaultType:
27         webType = WebServiceWorkerResponseTypeDefault;
28         break;
29     case FetchResponseData::ErrorType:
30         webType = WebServiceWorkerResponseTypeError;
31         break;
32     case FetchResponseData::OpaqueType:
33         webType = WebServiceWorkerResponseTypeOpaque;
34         break;
35     }
36     return webType;
37 }
38
39 } // namespace
40
41 FetchResponseData* FetchResponseData::create()
42 {
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");
46 }
47
48 FetchResponseData* FetchResponseData::createNetworkErrorResponse()
49 {
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, "");
54 }
55
56 FetchResponseData* FetchResponseData::createBasicFilteredResponse()
57 {
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")
66             continue;
67         response->m_headerList->append(header->first, header->second);
68     }
69     response->m_blobDataHandle = m_blobDataHandle;
70     response->m_internalResponse = this;
71     return response;
72 }
73
74 FetchResponseData* FetchResponseData::createCORSFilteredResponse()
75 {
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
82     // list."
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))
92             continue;
93         response->m_headerList->append(header->first, header->second);
94     }
95     response->m_blobDataHandle = m_blobDataHandle;
96     response->m_internalResponse = this;
97     return response;
98 }
99
100 FetchResponseData* FetchResponseData::createOpaqueFilteredResponse()
101 {
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;
107     return response;
108 }
109
110 void FetchResponseData::populateWebServiceWorkerResponse(WebServiceWorkerResponse& response)
111 {
112     if (m_internalResponse) {
113         m_internalResponse->populateWebServiceWorkerResponse(response);
114         response.setResponseType(fetchTypeToWebType(m_type));
115         return;
116     }
117
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);
125     }
126     response.setBlobDataHandle(blobDataHandle());
127 }
128
129 FetchResponseData::FetchResponseData(Type type, unsigned short status, AtomicString statusMessage)
130     : m_type(type)
131     , m_status(status)
132     , m_statusMessage(statusMessage)
133     , m_headerList(FetchHeaderList::create())
134 {
135 }
136
137 void FetchResponseData::trace(Visitor* visitor)
138 {
139     visitor->trace(m_headerList);
140     visitor->trace(m_internalResponse);
141 }
142
143 } // namespace blink