mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			187 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			187 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
 | 
						|
// reserved. Use of this source code is governed by a BSD-style license that
 | 
						|
// can be found in the LICENSE file.
 | 
						|
 | 
						|
#include "tests/cefclient/browser/urlrequest_test.h"
 | 
						|
 | 
						|
#include <string>
 | 
						|
 | 
						|
#include "include/base/cef_bind.h"
 | 
						|
#include "include/base/cef_callback.h"
 | 
						|
#include "include/base/cef_logging.h"
 | 
						|
#include "include/cef_urlrequest.h"
 | 
						|
#include "include/wrapper/cef_helpers.h"
 | 
						|
#include "tests/cefclient/browser/test_runner.h"
 | 
						|
 | 
						|
namespace client {
 | 
						|
namespace urlrequest_test {
 | 
						|
 | 
						|
namespace {
 | 
						|
 | 
						|
const char kTestUrlPath[] = "/urlrequest";
 | 
						|
const char kTestMessageName[] = "URLRequestTest";
 | 
						|
 | 
						|
// Implementation of CefURLRequestClient that stores response information. Only
 | 
						|
// accessed on the UI thread.
 | 
						|
class RequestClient : public CefURLRequestClient {
 | 
						|
 public:
 | 
						|
  // Callback to be executed on request completion.
 | 
						|
  typedef base::Callback<void(CefURLRequest::ErrorCode /*error_code*/,
 | 
						|
                              const std::string& /*download_data*/)>
 | 
						|
      Callback;
 | 
						|
 | 
						|
  explicit RequestClient(const Callback& callback) : callback_(callback) {
 | 
						|
    CEF_REQUIRE_UI_THREAD();
 | 
						|
    DCHECK(!callback_.is_null());
 | 
						|
  }
 | 
						|
 | 
						|
  void Detach() {
 | 
						|
    CEF_REQUIRE_UI_THREAD();
 | 
						|
    if (!callback_.is_null())
 | 
						|
      callback_.Reset();
 | 
						|
  }
 | 
						|
 | 
						|
  void OnRequestComplete(CefRefPtr<CefURLRequest> request) OVERRIDE {
 | 
						|
    CEF_REQUIRE_UI_THREAD();
 | 
						|
    if (!callback_.is_null()) {
 | 
						|
      callback_.Run(request->GetRequestError(), download_data_);
 | 
						|
      callback_.Reset();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  void OnUploadProgress(CefRefPtr<CefURLRequest> request,
 | 
						|
                        int64 current,
 | 
						|
                        int64 total) OVERRIDE {}
 | 
						|
 | 
						|
  void OnDownloadProgress(CefRefPtr<CefURLRequest> request,
 | 
						|
                          int64 current,
 | 
						|
                          int64 total) OVERRIDE {}
 | 
						|
 | 
						|
  void OnDownloadData(CefRefPtr<CefURLRequest> request,
 | 
						|
                      const void* data,
 | 
						|
                      size_t data_length) OVERRIDE {
 | 
						|
    CEF_REQUIRE_UI_THREAD();
 | 
						|
    download_data_ += std::string(static_cast<const char*>(data), data_length);
 | 
						|
  }
 | 
						|
 | 
						|
  bool GetAuthCredentials(bool isProxy,
 | 
						|
                          const CefString& host,
 | 
						|
                          int port,
 | 
						|
                          const CefString& realm,
 | 
						|
                          const CefString& scheme,
 | 
						|
                          CefRefPtr<CefAuthCallback> callback) OVERRIDE {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
 private:
 | 
						|
  Callback callback_;
 | 
						|
  std::string download_data_;
 | 
						|
 | 
						|
  IMPLEMENT_REFCOUNTING(RequestClient);
 | 
						|
  DISALLOW_COPY_AND_ASSIGN(RequestClient);
 | 
						|
};
 | 
						|
 | 
						|
// Handle messages in the browser process. Only accessed on the UI thread.
 | 
						|
class Handler : public CefMessageRouterBrowserSide::Handler {
 | 
						|
 public:
 | 
						|
  Handler() { CEF_REQUIRE_UI_THREAD(); }
 | 
						|
 | 
						|
  ~Handler() { CancelPendingRequest(); }
 | 
						|
 | 
						|
  // Called due to cefQuery execution in urlrequest.html.
 | 
						|
  bool OnQuery(CefRefPtr<CefBrowser> browser,
 | 
						|
               CefRefPtr<CefFrame> frame,
 | 
						|
               int64 query_id,
 | 
						|
               const CefString& request,
 | 
						|
               bool persistent,
 | 
						|
               CefRefPtr<Callback> callback) OVERRIDE {
 | 
						|
    CEF_REQUIRE_UI_THREAD();
 | 
						|
 | 
						|
    // Only handle messages from the test URL.
 | 
						|
    const std::string& url = frame->GetURL();
 | 
						|
    if (!test_runner::IsTestURL(url, kTestUrlPath))
 | 
						|
      return false;
 | 
						|
 | 
						|
    const std::string& message_name = request;
 | 
						|
    if (message_name.find(kTestMessageName) == 0) {
 | 
						|
      const std::string& load_url =
 | 
						|
          message_name.substr(sizeof(kTestMessageName));
 | 
						|
 | 
						|
      CancelPendingRequest();
 | 
						|
 | 
						|
      DCHECK(!callback_.get());
 | 
						|
      DCHECK(!urlrequest_.get());
 | 
						|
 | 
						|
      callback_ = callback;
 | 
						|
 | 
						|
      // Create a CefRequest for the specified URL.
 | 
						|
      CefRefPtr<CefRequest> cef_request = CefRequest::Create();
 | 
						|
      cef_request->SetURL(load_url);
 | 
						|
      cef_request->SetMethod("GET");
 | 
						|
 | 
						|
      // Callback to be executed on request completion.
 | 
						|
      // It's safe to use base::Unretained() here because there is only one
 | 
						|
      // RequestClient pending at any given time and we explicitly detach the
 | 
						|
      // callback in the Handler destructor.
 | 
						|
      const RequestClient::Callback& request_callback =
 | 
						|
          base::Bind(&Handler::OnRequestComplete, base::Unretained(this));
 | 
						|
 | 
						|
      // Create and start a new CefURLRequest associated with the frame, so
 | 
						|
      // that it shares authentication with ClientHandler::GetAuthCredentials.
 | 
						|
      urlrequest_ = frame->CreateURLRequest(
 | 
						|
          cef_request, new RequestClient(request_callback));
 | 
						|
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
 private:
 | 
						|
  // Cancel the currently pending URL request, if any.
 | 
						|
  void CancelPendingRequest() {
 | 
						|
    CEF_REQUIRE_UI_THREAD();
 | 
						|
 | 
						|
    if (urlrequest_.get()) {
 | 
						|
      // Don't execute the callback when we explicitly cancel the request.
 | 
						|
      static_cast<RequestClient*>(urlrequest_->GetClient().get())->Detach();
 | 
						|
 | 
						|
      urlrequest_->Cancel();
 | 
						|
      urlrequest_ = nullptr;
 | 
						|
    }
 | 
						|
 | 
						|
    if (callback_.get()) {
 | 
						|
      // Must always execute |callback_| before deleting it.
 | 
						|
      callback_->Failure(ERR_ABORTED, test_runner::GetErrorString(ERR_ABORTED));
 | 
						|
      callback_ = nullptr;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  void OnRequestComplete(CefURLRequest::ErrorCode error_code,
 | 
						|
                         const std::string& download_data) {
 | 
						|
    CEF_REQUIRE_UI_THREAD();
 | 
						|
 | 
						|
    if (error_code == ERR_NONE)
 | 
						|
      callback_->Success(download_data);
 | 
						|
    else
 | 
						|
      callback_->Failure(error_code, test_runner::GetErrorString(error_code));
 | 
						|
 | 
						|
    callback_ = nullptr;
 | 
						|
    urlrequest_ = nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  CefRefPtr<Callback> callback_;
 | 
						|
  CefRefPtr<CefURLRequest> urlrequest_;
 | 
						|
 | 
						|
  DISALLOW_COPY_AND_ASSIGN(Handler);
 | 
						|
};
 | 
						|
 | 
						|
}  // namespace
 | 
						|
 | 
						|
void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers) {
 | 
						|
  handlers.insert(new Handler());
 | 
						|
}
 | 
						|
 | 
						|
}  // namespace urlrequest_test
 | 
						|
}  // namespace client
 |