• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4 
5 #include "libcef/common/response_impl.h"
6 
7 #include <string>
8 
9 #include "libcef/common/net/http_header_utils.h"
10 #include "libcef/common/net_service/net_service_util.h"
11 
12 #include "base/logging.h"
13 #include "base/strings/string_util.h"
14 #include "net/http/http_request_headers.h"
15 #include "net/http/http_response_headers.h"
16 #include "third_party/blink/public/platform/web_http_header_visitor.h"
17 #include "third_party/blink/public/platform/web_string.h"
18 #include "third_party/blink/public/platform/web_url.h"
19 #include "third_party/blink/public/platform/web_url_response.h"
20 
21 #define CHECK_READONLY_RETURN_VOID()       \
22   if (read_only_) {                        \
23     NOTREACHED() << "object is read only"; \
24     return;                                \
25   }
26 
27 // CefResponse ----------------------------------------------------------------
28 
29 // static
Create()30 CefRefPtr<CefResponse> CefResponse::Create() {
31   CefRefPtr<CefResponse> response(new CefResponseImpl());
32   return response;
33 }
34 
35 // CefResponseImpl ------------------------------------------------------------
36 
CefResponseImpl()37 CefResponseImpl::CefResponseImpl()
38     : error_code_(ERR_NONE), status_code_(0), read_only_(false) {}
39 
IsReadOnly()40 bool CefResponseImpl::IsReadOnly() {
41   base::AutoLock lock_scope(lock_);
42   return read_only_;
43 }
44 
GetError()45 cef_errorcode_t CefResponseImpl::GetError() {
46   base::AutoLock lock_scope(lock_);
47   return error_code_;
48 }
49 
SetError(cef_errorcode_t error)50 void CefResponseImpl::SetError(cef_errorcode_t error) {
51   base::AutoLock lock_scope(lock_);
52   CHECK_READONLY_RETURN_VOID();
53   error_code_ = error;
54 }
55 
GetStatus()56 int CefResponseImpl::GetStatus() {
57   base::AutoLock lock_scope(lock_);
58   return status_code_;
59 }
60 
SetStatus(int status)61 void CefResponseImpl::SetStatus(int status) {
62   base::AutoLock lock_scope(lock_);
63   CHECK_READONLY_RETURN_VOID();
64   status_code_ = status;
65 }
66 
GetStatusText()67 CefString CefResponseImpl::GetStatusText() {
68   base::AutoLock lock_scope(lock_);
69   return status_text_;
70 }
71 
SetStatusText(const CefString & statusText)72 void CefResponseImpl::SetStatusText(const CefString& statusText) {
73   base::AutoLock lock_scope(lock_);
74   CHECK_READONLY_RETURN_VOID();
75   status_text_ = statusText;
76 }
77 
GetMimeType()78 CefString CefResponseImpl::GetMimeType() {
79   base::AutoLock lock_scope(lock_);
80   return mime_type_;
81 }
82 
SetMimeType(const CefString & mimeType)83 void CefResponseImpl::SetMimeType(const CefString& mimeType) {
84   base::AutoLock lock_scope(lock_);
85   CHECK_READONLY_RETURN_VOID();
86   mime_type_ = mimeType;
87 }
88 
GetCharset()89 CefString CefResponseImpl::GetCharset() {
90   base::AutoLock lock_scope(lock_);
91   return charset_;
92 }
93 
SetCharset(const CefString & charset)94 void CefResponseImpl::SetCharset(const CefString& charset) {
95   base::AutoLock lock_scope(lock_);
96   CHECK_READONLY_RETURN_VOID();
97   charset_ = charset;
98 }
99 
GetHeaderByName(const CefString & name)100 CefString CefResponseImpl::GetHeaderByName(const CefString& name) {
101   base::AutoLock lock_scope(lock_);
102 
103   std::string nameLower = name;
104   HttpHeaderUtils::MakeASCIILower(&nameLower);
105 
106   auto it = HttpHeaderUtils::FindHeaderInMap(nameLower, header_map_);
107   if (it != header_map_.end())
108     return it->second;
109 
110   return CefString();
111 }
112 
SetHeaderByName(const CefString & name,const CefString & value,bool overwrite)113 void CefResponseImpl::SetHeaderByName(const CefString& name,
114                                       const CefString& value,
115                                       bool overwrite) {
116   base::AutoLock lock_scope(lock_);
117   CHECK_READONLY_RETURN_VOID();
118 
119   std::string nameLower = name;
120   HttpHeaderUtils::MakeASCIILower(&nameLower);
121 
122   // There may be multiple values, so remove any first.
123   for (auto it = header_map_.begin(); it != header_map_.end();) {
124     if (base::EqualsCaseInsensitiveASCII(it->first.ToString(), nameLower)) {
125       if (!overwrite)
126         return;
127       it = header_map_.erase(it);
128     } else {
129       ++it;
130     }
131   }
132 
133   header_map_.insert(std::make_pair(name, value));
134 }
135 
GetURL()136 CefString CefResponseImpl::GetURL() {
137   base::AutoLock lock_scope(lock_);
138   return url_;
139 }
140 
SetURL(const CefString & url)141 void CefResponseImpl::SetURL(const CefString& url) {
142   base::AutoLock lock_scope(lock_);
143   CHECK_READONLY_RETURN_VOID();
144   url_ = url;
145 }
146 
GetHeaderMap(HeaderMap & map)147 void CefResponseImpl::GetHeaderMap(HeaderMap& map) {
148   base::AutoLock lock_scope(lock_);
149   map = header_map_;
150 }
151 
SetHeaderMap(const HeaderMap & headerMap)152 void CefResponseImpl::SetHeaderMap(const HeaderMap& headerMap) {
153   base::AutoLock lock_scope(lock_);
154   CHECK_READONLY_RETURN_VOID();
155   header_map_ = headerMap;
156 }
157 
GetResponseHeaders()158 scoped_refptr<net::HttpResponseHeaders> CefResponseImpl::GetResponseHeaders() {
159   base::AutoLock lock_scope(lock_);
160 
161   std::string mime_type = mime_type_;
162   if (mime_type.empty())
163     mime_type = "text/html";
164 
165   std::multimap<std::string, std::string> extra_headers;
166   for (const auto& pair : header_map_)
167     extra_headers.insert(std::make_pair(pair.first, pair.second));
168 
169   return net_service::MakeResponseHeaders(
170       status_code_, status_text_, mime_type, charset_, -1, extra_headers,
171       true /* allow_existing_header_override */);
172 }
173 
SetResponseHeaders(const net::HttpResponseHeaders & headers)174 void CefResponseImpl::SetResponseHeaders(
175     const net::HttpResponseHeaders& headers) {
176   base::AutoLock lock_scope(lock_);
177   CHECK_READONLY_RETURN_VOID();
178 
179   header_map_.clear();
180 
181   size_t iter = 0;
182   std::string name, value;
183   while (headers.EnumerateHeaderLines(&iter, &name, &value))
184     header_map_.insert(std::make_pair(name, value));
185 
186   status_code_ = headers.response_code();
187   status_text_ = headers.GetStatusText();
188 
189   if (headers.IsRedirect(nullptr)) {
190     // Don't report Content-Type header values for redirects.
191     mime_type_.clear();
192     charset_.clear();
193   } else {
194     std::string mime_type, charset;
195     headers.GetMimeTypeAndCharset(&mime_type, &charset);
196     mime_type_ = mime_type;
197     charset_ = charset;
198   }
199 }
200 
Set(const blink::WebURLResponse & response)201 void CefResponseImpl::Set(const blink::WebURLResponse& response) {
202   DCHECK(!response.IsNull());
203 
204   base::AutoLock lock_scope(lock_);
205   CHECK_READONLY_RETURN_VOID();
206 
207   blink::WebString str;
208   status_code_ = response.HttpStatusCode();
209   str = response.HttpStatusText();
210   status_text_ = str.Utf16();
211   str = response.MimeType();
212   mime_type_ = str.Utf16();
213   str = response.CurrentRequestUrl().GetString();
214   url_ = str.Utf16();
215 
216   class HeaderVisitor : public blink::WebHTTPHeaderVisitor {
217    public:
218     explicit HeaderVisitor(HeaderMap* map) : map_(map) {}
219 
220     void VisitHeader(const blink::WebString& name,
221                      const blink::WebString& value) override {
222       map_->insert(std::make_pair(name.Utf16(), value.Utf16()));
223     }
224 
225    private:
226     HeaderMap* map_;
227   };
228 
229   HeaderVisitor visitor(&header_map_);
230   response.VisitHttpHeaderFields(&visitor);
231 }
232 
SetReadOnly(bool read_only)233 void CefResponseImpl::SetReadOnly(bool read_only) {
234   base::AutoLock lock_scope(lock_);
235   read_only_ = read_only;
236 }
237