• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2020 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 "tests/ceftests/test_request.h"
6 
7 #include <algorithm>
8 #include <memory>
9 
10 #include "include/cef_stream.h"
11 #include "include/cef_urlrequest.h"
12 #include "include/wrapper/cef_closure_task.h"
13 #include "include/wrapper/cef_helpers.h"
14 #include "include/wrapper/cef_stream_resource_handler.h"
15 
16 namespace test_request {
17 
18 namespace {
19 
20 // Implementation of CefURLRequestClient that stores response information.
21 class RequestClient : public CefURLRequestClient, public State {
22  public:
RequestClient(const bool has_credentials,const std::string & username,const std::string & password,RequestDoneCallback done_callback)23   RequestClient(const bool has_credentials,
24                 const std::string& username,
25                 const std::string& password,
26                 RequestDoneCallback done_callback)
27       : has_credentials_(has_credentials),
28         username_(username),
29         password_(password),
30         done_callback_(std::move(done_callback)) {
31     DCHECK(!done_callback_.is_null());
32   }
33 
OnUploadProgress(CefRefPtr<CefURLRequest> request,int64 current,int64 total)34   void OnUploadProgress(CefRefPtr<CefURLRequest> request,
35                         int64 current,
36                         int64 total) override {
37     upload_progress_ct_++;
38     upload_total_ = total;
39   }
40 
OnDownloadProgress(CefRefPtr<CefURLRequest> request,int64 current,int64 total)41   void OnDownloadProgress(CefRefPtr<CefURLRequest> request,
42                           int64 current,
43                           int64 total) override {
44     response_ = request->GetResponse();
45     DCHECK(response_.get());
46     DCHECK(response_->IsReadOnly());
47     download_progress_ct_++;
48     download_total_ = total;
49   }
50 
OnDownloadData(CefRefPtr<CefURLRequest> request,const void * data,size_t data_length)51   void OnDownloadData(CefRefPtr<CefURLRequest> request,
52                       const void* data,
53                       size_t data_length) override {
54     response_ = request->GetResponse();
55     DCHECK(response_.get());
56     DCHECK(response_->IsReadOnly());
57     download_data_ct_++;
58     download_data_ += std::string(static_cast<const char*>(data), data_length);
59   }
60 
GetAuthCredentials(bool isProxy,const CefString & host,int port,const CefString & realm,const CefString & scheme,CefRefPtr<CefAuthCallback> callback)61   bool GetAuthCredentials(bool isProxy,
62                           const CefString& host,
63                           int port,
64                           const CefString& realm,
65                           const CefString& scheme,
66                           CefRefPtr<CefAuthCallback> callback) override {
67     auth_credentials_ct_++;
68     if (has_credentials_) {
69       callback->Continue(username_, password_);
70       return true;
71     }
72     return false;
73   }
74 
OnRequestComplete(CefRefPtr<CefURLRequest> request)75   void OnRequestComplete(CefRefPtr<CefURLRequest> request) override {
76     request_complete_ct_++;
77 
78     request_ = request->GetRequest();
79     DCHECK(request_->IsReadOnly());
80     status_ = request->GetRequestStatus();
81     error_code_ = request->GetRequestError();
82     response_was_cached_ = request->ResponseWasCached();
83     response_ = request->GetResponse();
84     if (response_) {
85       DCHECK(response_->IsReadOnly());
86     }
87 
88     std::move(done_callback_).Run(*this);
89   }
90 
91  private:
92   const bool has_credentials_;
93   const std::string username_;
94   const std::string password_;
95   RequestDoneCallback done_callback_;
96 
97   IMPLEMENT_REFCOUNTING(RequestClient);
98   DISALLOW_COPY_AND_ASSIGN(RequestClient);
99 };
100 
101 // Implementation that collects all cookies, and optionally deletes them.
102 class CookieVisitor : public CefCookieVisitor {
103  public:
CookieVisitor(bool deleteCookies,CookieDoneCallback callback)104   CookieVisitor(bool deleteCookies, CookieDoneCallback callback)
105       : delete_cookies_(deleteCookies), callback_(std::move(callback)) {
106     DCHECK(!callback_.is_null());
107   }
108 
~CookieVisitor()109   ~CookieVisitor() override {
110     CEF_REQUIRE_UI_THREAD();
111     std::move(callback_).Run(cookies_);
112   }
113 
Visit(const CefCookie & cookie,int count,int total,bool & deleteCookie)114   bool Visit(const CefCookie& cookie,
115              int count,
116              int total,
117              bool& deleteCookie) override {
118     CEF_REQUIRE_UI_THREAD();
119     cookies_.push_back(cookie);
120     if (delete_cookies_)
121       deleteCookie = true;
122     return true;
123   }
124 
125  private:
126   CookieVector cookies_;
127   bool delete_cookies_;
128   CookieDoneCallback callback_;
129 
130   IMPLEMENT_REFCOUNTING(CookieVisitor);
131   DISALLOW_COPY_AND_ASSIGN(CookieVisitor);
132 };
133 
134 }  // namespace
135 
Send(const SendConfig & config,RequestDoneCallback callback)136 void Send(const SendConfig& config, RequestDoneCallback callback) {
137   DCHECK(config.request_);
138   CefRefPtr<RequestClient> client =
139       new RequestClient(config.has_credentials_, config.username_,
140                         config.password_, std::move(callback));
141   if (config.frame_) {
142     config.frame_->CreateURLRequest(config.request_, client.get());
143   } else {
144     CefURLRequest::Create(config.request_, client.get(),
145                           config.request_context_);
146   }
147 }
148 
GetPathURL(const std::string & url)149 std::string GetPathURL(const std::string& url) {
150   const size_t index1 = url.find('?');
151   const size_t index2 = url.find('#');
152   size_t index = std::string::npos;
153   if (index1 != std::string::npos && index2 != std::string::npos) {
154     index = std::min(index1, index2);
155   } else if (index1 != std::string::npos) {
156     index = index1;
157   } else if (index2 != std::string::npos) {
158     index = index2;
159   }
160   if (index != std::string::npos) {
161     return url.substr(0, index);
162   }
163   return url;
164 }
165 
CreateResourceHandler(CefRefPtr<CefResponse> response,const std::string & response_data)166 CefRefPtr<CefResourceHandler> CreateResourceHandler(
167     CefRefPtr<CefResponse> response,
168     const std::string& response_data) {
169   CefRefPtr<CefStreamReader> stream;
170   if (!response_data.empty()) {
171     stream = CefStreamReader::CreateForData(
172         static_cast<void*>(const_cast<char*>(response_data.c_str())),
173         response_data.length());
174   }
175 
176   CefResponse::HeaderMap headerMap;
177   response->GetHeaderMap(headerMap);
178 
179   return new CefStreamResourceHandler(
180       response->GetStatus(), response->GetStatusText(), response->GetMimeType(),
181       headerMap, stream);
182 }
183 
GetAllCookies(CefRefPtr<CefCookieManager> manager,bool deleteCookies,CookieDoneCallback callback)184 void GetAllCookies(CefRefPtr<CefCookieManager> manager,
185                    bool deleteCookies,
186                    CookieDoneCallback callback) {
187   bool result = manager->VisitAllCookies(
188       new CookieVisitor(deleteCookies, std::move(callback)));
189   DCHECK(result);
190 }
191 
192 // Retrieves URL cookies from |manager| and executes |callback| upon completion.
193 // If |deleteCookies| is true the cookies will also be deleted.
GetUrlCookies(CefRefPtr<CefCookieManager> manager,const CefString & url,bool includeHttpOnly,bool deleteCookies,CookieDoneCallback callback)194 void GetUrlCookies(CefRefPtr<CefCookieManager> manager,
195                    const CefString& url,
196                    bool includeHttpOnly,
197                    bool deleteCookies,
198                    CookieDoneCallback callback) {
199   bool result = manager->VisitUrlCookies(
200       url, includeHttpOnly,
201       new CookieVisitor(deleteCookies, std::move(callback)));
202   DCHECK(result);
203 }
204 
205 }  // namespace test_request
206