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