mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-24 07:58:11 +01:00
Convert usage and tests to the new CefResourceHandler API (see issue #2622)
Limited test coverage for the old API is still available by passing the `--test-old-resource-api` command-line flag to ceftests.
This commit is contained in:
parent
dfcfb51bef
commit
1c88c74f86
@ -37,14 +37,10 @@
|
||||
#define CEF_INCLUDE_WRAPPER_CEF_STREAM_RESOURCE_HANDLER_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/base/cef_logging.h"
|
||||
#include "include/base/cef_macros.h"
|
||||
#include "include/base/cef_scoped_ptr.h"
|
||||
#include "include/cef_base.h"
|
||||
#include "include/cef_resource_handler.h"
|
||||
#include "include/cef_response.h"
|
||||
|
||||
class CefStreamReader;
|
||||
#include "include/cef_stream.h"
|
||||
|
||||
///
|
||||
// Implementation of the CefResourceHandler class for reading from a CefStream.
|
||||
@ -65,37 +61,25 @@ class CefStreamResourceHandler : public CefResourceHandler {
|
||||
CefResponse::HeaderMap header_map,
|
||||
CefRefPtr<CefStreamReader> stream);
|
||||
|
||||
virtual ~CefStreamResourceHandler();
|
||||
|
||||
// CefResourceHandler methods.
|
||||
virtual bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) OVERRIDE;
|
||||
virtual void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
||||
int64& response_length,
|
||||
CefString& redirectUrl) OVERRIDE;
|
||||
virtual bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) OVERRIDE;
|
||||
virtual void Cancel() OVERRIDE;
|
||||
bool Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) OVERRIDE;
|
||||
void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
||||
int64& response_length,
|
||||
CefString& redirectUrl) OVERRIDE;
|
||||
bool Read(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) OVERRIDE;
|
||||
void Cancel() OVERRIDE;
|
||||
|
||||
private:
|
||||
void ReadOnFileThread(int bytes_to_read, CefRefPtr<CefCallback> callback);
|
||||
|
||||
const int status_code_;
|
||||
const CefString status_text_;
|
||||
const CefString mime_type_;
|
||||
const CefResponse::HeaderMap header_map_;
|
||||
const CefRefPtr<CefStreamReader> stream_;
|
||||
bool read_on_file_thread_;
|
||||
|
||||
class Buffer;
|
||||
scoped_ptr<Buffer> buffer_;
|
||||
#if DCHECK_IS_ON()
|
||||
// Used in debug builds to verify that |buffer_| isn't being accessed on
|
||||
// multiple threads at the same time.
|
||||
bool buffer_owned_by_file_thread_;
|
||||
#endif
|
||||
|
||||
IMPLEMENT_REFCOUNTING(CefStreamResourceHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefStreamResourceHandler);
|
||||
|
@ -52,9 +52,11 @@ class RedirectHandler : public CefResourceHandler {
|
||||
public:
|
||||
explicit RedirectHandler(const GURL& url) : url_(url) {}
|
||||
|
||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
callback->Continue();
|
||||
bool Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
// Continue immediately.
|
||||
handle_request = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -65,10 +67,11 @@ class RedirectHandler : public CefResourceHandler {
|
||||
redirectUrl = url_.spec();
|
||||
}
|
||||
|
||||
bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
bool Read(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) override {
|
||||
NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -78,6 +81,7 @@ class RedirectHandler : public CefResourceHandler {
|
||||
GURL url_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(RedirectHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(RedirectHandler);
|
||||
};
|
||||
|
||||
class InternalHandler : public CefResourceHandler {
|
||||
@ -87,9 +91,11 @@ class InternalHandler : public CefResourceHandler {
|
||||
int size)
|
||||
: mime_type_(mime_type), reader_(reader), size_(size) {}
|
||||
|
||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
callback->Continue();
|
||||
bool Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
// Continue immediately.
|
||||
handle_request = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -102,11 +108,21 @@ class InternalHandler : public CefResourceHandler {
|
||||
response->SetStatus(200);
|
||||
}
|
||||
|
||||
bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
bytes_read = reader_->Read(data_out, 1, bytes_to_read);
|
||||
bool Read(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) override {
|
||||
// Read until the buffer is full or until Read() returns 0 to indicate no
|
||||
// more data.
|
||||
bytes_read = 0;
|
||||
int read = 0;
|
||||
do {
|
||||
read = static_cast<int>(
|
||||
reader_->Read(static_cast<char*>(data_out) + bytes_read, 1,
|
||||
bytes_to_read - bytes_read));
|
||||
bytes_read += read;
|
||||
} while (read != 0 && bytes_read < bytes_to_read);
|
||||
|
||||
return (bytes_read > 0);
|
||||
}
|
||||
|
||||
@ -118,6 +134,7 @@ class InternalHandler : public CefResourceHandler {
|
||||
int size_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(InternalHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(InternalHandler);
|
||||
};
|
||||
|
||||
class InternalHandlerFactory : public CefSchemeHandlerFactory {
|
||||
@ -170,6 +187,7 @@ class InternalHandlerFactory : public CefSchemeHandlerFactory {
|
||||
std::unique_ptr<InternalHandlerDelegate> delegate_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(InternalHandlerFactory);
|
||||
DISALLOW_COPY_AND_ASSIGN(InternalHandlerFactory);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -6,84 +6,19 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "include/base/cef_logging.h"
|
||||
#include "include/base/cef_macros.h"
|
||||
#include "include/cef_callback.h"
|
||||
#include "include/cef_request.h"
|
||||
#include "include/cef_stream.h"
|
||||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "include/cef_task.h"
|
||||
#include "include/wrapper/cef_helpers.h"
|
||||
|
||||
// Class that represents a readable/writable character buffer.
|
||||
class CefStreamResourceHandler::Buffer {
|
||||
public:
|
||||
Buffer() : size_(0), bytes_requested_(0), bytes_written_(0), bytes_read_(0) {}
|
||||
|
||||
void Reset(int new_size) {
|
||||
if (size_ < new_size) {
|
||||
size_ = new_size;
|
||||
buffer_.reset(new char[size_]);
|
||||
DCHECK(buffer_);
|
||||
}
|
||||
bytes_requested_ = new_size;
|
||||
bytes_written_ = 0;
|
||||
bytes_read_ = 0;
|
||||
}
|
||||
|
||||
bool IsEmpty() const { return (bytes_written_ == 0); }
|
||||
|
||||
bool CanRead() const { return (bytes_read_ < bytes_written_); }
|
||||
|
||||
int WriteTo(void* data_out, int bytes_to_read) {
|
||||
const int write_size =
|
||||
std::min(bytes_to_read, bytes_written_ - bytes_read_);
|
||||
if (write_size > 0) {
|
||||
memcpy(data_out, buffer_.get() + bytes_read_, write_size);
|
||||
bytes_read_ += write_size;
|
||||
}
|
||||
return write_size;
|
||||
}
|
||||
|
||||
int ReadFrom(CefRefPtr<CefStreamReader> reader) {
|
||||
// Read until the buffer is full or until Read() returns 0 to indicate no
|
||||
// more data.
|
||||
int bytes_read;
|
||||
do {
|
||||
bytes_read =
|
||||
static_cast<int>(reader->Read(buffer_.get() + bytes_written_, 1,
|
||||
bytes_requested_ - bytes_written_));
|
||||
bytes_written_ += bytes_read;
|
||||
} while (bytes_read != 0 && bytes_written_ < bytes_requested_);
|
||||
|
||||
return bytes_written_;
|
||||
}
|
||||
|
||||
private:
|
||||
scoped_ptr<char[]> buffer_;
|
||||
int size_;
|
||||
int bytes_requested_;
|
||||
int bytes_written_;
|
||||
int bytes_read_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Buffer);
|
||||
};
|
||||
|
||||
CefStreamResourceHandler::CefStreamResourceHandler(
|
||||
const CefString& mime_type,
|
||||
CefRefPtr<CefStreamReader> stream)
|
||||
: status_code_(200),
|
||||
status_text_("OK"),
|
||||
mime_type_(mime_type),
|
||||
stream_(stream)
|
||||
#if DCHECK_IS_ON()
|
||||
,
|
||||
buffer_owned_by_file_thread_(false)
|
||||
#endif
|
||||
{
|
||||
stream_(stream) {
|
||||
DCHECK(!mime_type_.empty());
|
||||
DCHECK(stream_.get());
|
||||
read_on_file_thread_ = stream_->MayBlock();
|
||||
}
|
||||
|
||||
CefStreamResourceHandler::CefStreamResourceHandler(
|
||||
@ -96,22 +31,18 @@ CefStreamResourceHandler::CefStreamResourceHandler(
|
||||
status_text_(status_text),
|
||||
mime_type_(mime_type),
|
||||
header_map_(header_map),
|
||||
stream_(stream)
|
||||
#if DCHECK_IS_ON()
|
||||
,
|
||||
buffer_owned_by_file_thread_(false)
|
||||
#endif
|
||||
{
|
||||
stream_(stream) {
|
||||
DCHECK(!mime_type_.empty());
|
||||
DCHECK(stream_.get());
|
||||
read_on_file_thread_ = stream_->MayBlock();
|
||||
}
|
||||
|
||||
CefStreamResourceHandler::~CefStreamResourceHandler() {}
|
||||
bool CefStreamResourceHandler::Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) {
|
||||
DCHECK(!CefCurrentlyOn(TID_UI) && !CefCurrentlyOn(TID_IO));
|
||||
|
||||
bool CefStreamResourceHandler::ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) {
|
||||
callback->Continue();
|
||||
// Continue the request immediately.
|
||||
handle_request = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -119,6 +50,8 @@ void CefStreamResourceHandler::GetResponseHeaders(
|
||||
CefRefPtr<CefResponse> response,
|
||||
int64& response_length,
|
||||
CefString& redirectUrl) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
response->SetStatus(status_code_);
|
||||
response->SetStatusText(status_text_);
|
||||
response->SetMimeType(mime_type_);
|
||||
@ -129,70 +62,26 @@ void CefStreamResourceHandler::GetResponseHeaders(
|
||||
response_length = -1;
|
||||
}
|
||||
|
||||
bool CefStreamResourceHandler::ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) {
|
||||
bool CefStreamResourceHandler::Read(
|
||||
void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) {
|
||||
DCHECK(!CefCurrentlyOn(TID_UI) && !CefCurrentlyOn(TID_IO));
|
||||
DCHECK_GT(bytes_to_read, 0);
|
||||
|
||||
if (read_on_file_thread_) {
|
||||
#if DCHECK_IS_ON()
|
||||
DCHECK(!buffer_owned_by_file_thread_);
|
||||
#endif
|
||||
if (buffer_ && (buffer_->CanRead() || buffer_->IsEmpty())) {
|
||||
if (buffer_->CanRead()) {
|
||||
// Provide data from the buffer.
|
||||
bytes_read = buffer_->WriteTo(data_out, bytes_to_read);
|
||||
return (bytes_read > 0);
|
||||
} else {
|
||||
// End of the steam.
|
||||
bytes_read = 0;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Perform another read on the file thread.
|
||||
bytes_read = 0;
|
||||
#if DCHECK_IS_ON()
|
||||
buffer_owned_by_file_thread_ = true;
|
||||
#endif
|
||||
CefPostTask(TID_FILE,
|
||||
base::Bind(&CefStreamResourceHandler::ReadOnFileThread, this,
|
||||
bytes_to_read, callback));
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// Read until the buffer is full or until Read() returns 0 to indicate no
|
||||
// more data.
|
||||
bytes_read = 0;
|
||||
int read = 0;
|
||||
do {
|
||||
read = static_cast<int>(
|
||||
stream_->Read(static_cast<char*>(data_out) + bytes_read, 1,
|
||||
bytes_to_read - bytes_read));
|
||||
bytes_read += read;
|
||||
} while (read != 0 && bytes_read < bytes_to_read);
|
||||
// Read until the buffer is full or until Read() returns 0 to indicate no
|
||||
// more data.
|
||||
bytes_read = 0;
|
||||
int read = 0;
|
||||
do {
|
||||
read = static_cast<int>(
|
||||
stream_->Read(static_cast<char*>(data_out) + bytes_read, 1,
|
||||
bytes_to_read - bytes_read));
|
||||
bytes_read += read;
|
||||
} while (read != 0 && bytes_read < bytes_to_read);
|
||||
|
||||
return (bytes_read > 0);
|
||||
}
|
||||
return (bytes_read > 0);
|
||||
}
|
||||
|
||||
void CefStreamResourceHandler::Cancel() {}
|
||||
|
||||
void CefStreamResourceHandler::ReadOnFileThread(
|
||||
int bytes_to_read,
|
||||
CefRefPtr<CefCallback> callback) {
|
||||
CEF_REQUIRE_FILE_THREAD();
|
||||
#if DCHECK_IS_ON()
|
||||
DCHECK(buffer_owned_by_file_thread_);
|
||||
#endif
|
||||
|
||||
if (!buffer_)
|
||||
buffer_.reset(new Buffer());
|
||||
buffer_->Reset(bytes_to_read);
|
||||
buffer_->ReadFrom(stream_);
|
||||
|
||||
#if DCHECK_IS_ON()
|
||||
buffer_owned_by_file_thread_ = false;
|
||||
#endif
|
||||
callback->Continue();
|
||||
}
|
||||
|
@ -28,9 +28,13 @@ class ClientSchemeHandler : public CefResourceHandler {
|
||||
public:
|
||||
ClientSchemeHandler() : offset_(0) {}
|
||||
|
||||
virtual bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) OVERRIDE {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
bool Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) OVERRIDE {
|
||||
DCHECK(!CefCurrentlyOn(TID_UI) && !CefCurrentlyOn(TID_IO));
|
||||
|
||||
// The request will be continued or canceled based on the return value.
|
||||
handle_request = true;
|
||||
|
||||
bool handled = false;
|
||||
|
||||
@ -70,18 +74,12 @@ class ClientSchemeHandler : public CefResourceHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if (handled) {
|
||||
// Indicate the headers are available.
|
||||
callback->Continue();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return handled;
|
||||
}
|
||||
|
||||
virtual void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
||||
int64& response_length,
|
||||
CefString& redirectUrl) OVERRIDE {
|
||||
void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
||||
int64& response_length,
|
||||
CefString& redirectUrl) OVERRIDE {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
DCHECK(!data_.empty());
|
||||
@ -93,13 +91,13 @@ class ClientSchemeHandler : public CefResourceHandler {
|
||||
response_length = data_.length();
|
||||
}
|
||||
|
||||
virtual void Cancel() OVERRIDE { CEF_REQUIRE_IO_THREAD(); }
|
||||
void Cancel() OVERRIDE { CEF_REQUIRE_IO_THREAD(); }
|
||||
|
||||
virtual bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) OVERRIDE {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
bool Read(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) OVERRIDE {
|
||||
DCHECK(!CefCurrentlyOn(TID_UI) && !CefCurrentlyOn(TID_IO));
|
||||
|
||||
bool has_data = false;
|
||||
bytes_read = 0;
|
||||
@ -124,22 +122,25 @@ class ClientSchemeHandler : public CefResourceHandler {
|
||||
size_t offset_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(ClientSchemeHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(ClientSchemeHandler);
|
||||
};
|
||||
|
||||
// Implementation of the factory for for creating schema handlers.
|
||||
class ClientSchemeHandlerFactory : public CefSchemeHandlerFactory {
|
||||
public:
|
||||
ClientSchemeHandlerFactory() {}
|
||||
|
||||
// Return a new scheme handler instance to handle the request.
|
||||
virtual CefRefPtr<CefResourceHandler> Create(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
const CefString& scheme_name,
|
||||
CefRefPtr<CefRequest> request) OVERRIDE {
|
||||
CefRefPtr<CefResourceHandler> Create(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
const CefString& scheme_name,
|
||||
CefRefPtr<CefRequest> request) OVERRIDE {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
return new ClientSchemeHandler();
|
||||
}
|
||||
|
||||
IMPLEMENT_REFCOUNTING(ClientSchemeHandlerFactory);
|
||||
DISALLOW_COPY_AND_ASSIGN(ClientSchemeHandlerFactory);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -709,8 +709,11 @@ class CookieTestSchemeHandler : public TestHandler {
|
||||
explicit SchemeHandler(CookieTestSchemeHandler* handler)
|
||||
: handler_(handler), offset_(0) {}
|
||||
|
||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
bool Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
std::string url = request->GetURL();
|
||||
if (url == handler_->url1_) {
|
||||
content_ = "<html><body>COOKIE TEST1</body></html>";
|
||||
@ -731,7 +734,9 @@ class CookieTestSchemeHandler : public TestHandler {
|
||||
if (it != headerMap.end() && it->second == "name2=value2")
|
||||
handler_->got_process_request_cookie_.yes();
|
||||
}
|
||||
callback->Continue();
|
||||
|
||||
// Continue immediately.
|
||||
handle_request = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -751,10 +756,12 @@ class CookieTestSchemeHandler : public TestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
bool Read(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
bool has_data = false;
|
||||
bytes_read = 0;
|
||||
|
||||
@ -781,6 +788,7 @@ class CookieTestSchemeHandler : public TestHandler {
|
||||
std::string cookie_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(SchemeHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(SchemeHandler);
|
||||
};
|
||||
|
||||
class SchemeHandlerFactory : public CefSchemeHandlerFactory {
|
||||
@ -810,6 +818,7 @@ class CookieTestSchemeHandler : public TestHandler {
|
||||
CookieTestSchemeHandler* handler_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(SchemeHandlerFactory);
|
||||
DISALLOW_COPY_AND_ASSIGN(SchemeHandlerFactory);
|
||||
};
|
||||
|
||||
CookieTestSchemeHandler(const std::string& scheme,
|
||||
@ -1106,9 +1115,10 @@ class CookieAccessSchemeHandler : public CefResourceHandler {
|
||||
explicit CookieAccessSchemeHandler(CookieAccessData* data)
|
||||
: data_(data), offset_(0) {}
|
||||
|
||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_IO_THREAD();
|
||||
bool Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
CefRequest::HeaderMap headerMap;
|
||||
request->GetHeaderMap(headerMap);
|
||||
@ -1116,7 +1126,7 @@ class CookieAccessSchemeHandler : public CefResourceHandler {
|
||||
TestCookieString(cookie_str, data_->cookie_js_ct_, data_->cookie_net_ct_);
|
||||
|
||||
// Continue immediately.
|
||||
callback->Continue();
|
||||
handle_request = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1136,11 +1146,11 @@ class CookieAccessSchemeHandler : public CefResourceHandler {
|
||||
response_length = data_->response_data.length();
|
||||
}
|
||||
|
||||
bool ReadResponse(void* response_data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_IO_THREAD();
|
||||
bool Read(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
bool has_data = false;
|
||||
bytes_read = 0;
|
||||
@ -1149,8 +1159,7 @@ class CookieAccessSchemeHandler : public CefResourceHandler {
|
||||
if (offset_ < size) {
|
||||
int transfer_size =
|
||||
std::min(bytes_to_read, static_cast<int>(size - offset_));
|
||||
memcpy(response_data_out, data_->response_data.c_str() + offset_,
|
||||
transfer_size);
|
||||
memcpy(data_out, data_->response_data.c_str() + offset_, transfer_size);
|
||||
offset_ += transfer_size;
|
||||
|
||||
bytes_read = transfer_size;
|
||||
@ -1185,6 +1194,7 @@ class CookieAccessSchemeHandler : public CefResourceHandler {
|
||||
size_t offset_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(CookieAccessSchemeHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(CookieAccessSchemeHandler);
|
||||
};
|
||||
|
||||
class CookieAccessSchemeHandlerFactory : public CefSchemeHandlerFactory,
|
||||
|
@ -22,7 +22,7 @@ const char kTestContentDisposition[] =
|
||||
const char kTestMimeType[] = "text/plain";
|
||||
const char kTestContent[] = "Download test text";
|
||||
|
||||
typedef base::Callback<void(CefRefPtr<CefCallback> /*callback*/)> DelayCallback;
|
||||
typedef base::Callback<void(const base::Closure& /*callback*/)> DelayCallback;
|
||||
|
||||
class DownloadSchemeHandler : public CefResourceHandler {
|
||||
public:
|
||||
@ -33,8 +33,11 @@ class DownloadSchemeHandler : public CefResourceHandler {
|
||||
should_delay_(false),
|
||||
offset_(0) {}
|
||||
|
||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
bool Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
std::string url = request->GetURL();
|
||||
if (url == kTestDownloadUrl) {
|
||||
got_download_request_->yes();
|
||||
@ -44,10 +47,14 @@ class DownloadSchemeHandler : public CefResourceHandler {
|
||||
should_delay_ = true;
|
||||
} else {
|
||||
EXPECT_TRUE(false); // Not reached.
|
||||
|
||||
// Cancel immediately.
|
||||
handle_request = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
callback->Continue();
|
||||
// Continue immediately.
|
||||
handle_request = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -68,19 +75,37 @@ class DownloadSchemeHandler : public CefResourceHandler {
|
||||
}
|
||||
}
|
||||
|
||||
bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
bool Read(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
bytes_read = 0;
|
||||
|
||||
if (should_delay_ && !delay_callback_.is_null()) {
|
||||
// Delay the download response a single time.
|
||||
delay_callback_.Run(callback);
|
||||
delay_callback_.Run(base::Bind(&DownloadSchemeHandler::ContinueRead, this,
|
||||
data_out, bytes_to_read, callback));
|
||||
delay_callback_.Reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
return DoRead(data_out, bytes_to_read, bytes_read);
|
||||
}
|
||||
|
||||
void Cancel() override {}
|
||||
|
||||
private:
|
||||
void ContinueRead(void* data_out,
|
||||
int bytes_to_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) {
|
||||
int bytes_read = 0;
|
||||
DoRead(data_out, bytes_to_read, bytes_read);
|
||||
callback->Continue(bytes_read);
|
||||
}
|
||||
|
||||
bool DoRead(void* data_out, int bytes_to_read, int& bytes_read) {
|
||||
bool has_data = false;
|
||||
size_t size = content_.size();
|
||||
if (offset_ < size) {
|
||||
@ -96,9 +121,6 @@ class DownloadSchemeHandler : public CefResourceHandler {
|
||||
return has_data;
|
||||
}
|
||||
|
||||
void Cancel() override {}
|
||||
|
||||
private:
|
||||
DelayCallback delay_callback_;
|
||||
TrackCallback* got_download_request_;
|
||||
bool should_delay_;
|
||||
@ -106,8 +128,10 @@ class DownloadSchemeHandler : public CefResourceHandler {
|
||||
std::string mime_type_;
|
||||
std::string content_disposition_;
|
||||
size_t offset_;
|
||||
CefRefPtr<CefResourceReadCallback> read_callback_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(DownloadSchemeHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(DownloadSchemeHandler);
|
||||
};
|
||||
|
||||
class DownloadSchemeHandlerFactory : public CefSchemeHandlerFactory {
|
||||
@ -129,6 +153,7 @@ class DownloadSchemeHandlerFactory : public CefSchemeHandlerFactory {
|
||||
TrackCallback* got_download_request_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(DownloadSchemeHandlerFactory);
|
||||
DISALLOW_COPY_AND_ASSIGN(DownloadSchemeHandlerFactory);
|
||||
};
|
||||
|
||||
class DownloadTestHandler : public TestHandler {
|
||||
@ -239,7 +264,7 @@ class DownloadTestHandler : public TestHandler {
|
||||
}
|
||||
|
||||
// Callback from the scheme handler when the download request is delayed.
|
||||
void OnDelayCallback(CefRefPtr<CefCallback> callback) {
|
||||
void OnDelayCallback(const base::Closure& callback) {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
CefPostTask(TID_UI, base::Bind(&DownloadTestHandler::OnDelayCallback,
|
||||
this, callback));
|
||||
@ -261,8 +286,9 @@ class DownloadTestHandler : public TestHandler {
|
||||
void ContinueNavigatedIfReady() {
|
||||
EXPECT_EQ(test_mode_, NAVIGATED);
|
||||
if (got_delay_callback_ && got_nav_load_) {
|
||||
delay_callback_->Continue();
|
||||
delay_callback_ = nullptr;
|
||||
EXPECT_FALSE(delay_callback_.is_null());
|
||||
delay_callback_.Run();
|
||||
delay_callback_.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -462,7 +488,7 @@ class DownloadTestHandler : public TestHandler {
|
||||
CefRefPtr<CefRequestContext> request_context_;
|
||||
|
||||
// Used with NAVIGATED and PENDING test modes.
|
||||
CefRefPtr<CefCallback> delay_callback_;
|
||||
base::Closure delay_callback_;
|
||||
|
||||
// Used with PENDING test mode.
|
||||
CefRefPtr<CefDownloadItemCallback> download_item_callback_;
|
||||
|
@ -688,9 +688,10 @@ class RedirectSchemeHandler : public CefResourceHandler {
|
||||
public:
|
||||
RedirectSchemeHandler() : offset_(0), status_(0) {}
|
||||
|
||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_TRUE(CefCurrentlyOn(TID_IO));
|
||||
bool Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
std::string url = request->GetURL();
|
||||
if (url == kRNav1) {
|
||||
@ -711,13 +712,16 @@ class RedirectSchemeHandler : public CefResourceHandler {
|
||||
content_ = "<html><body>Nav4</body></html>";
|
||||
}
|
||||
|
||||
handle_request = true;
|
||||
|
||||
if (status_ != 0) {
|
||||
callback->Continue();
|
||||
// Continue request.
|
||||
return true;
|
||||
} else {
|
||||
g_got_invalid_request = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cancel request.
|
||||
g_got_invalid_request = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
||||
@ -748,11 +752,14 @@ class RedirectSchemeHandler : public CefResourceHandler {
|
||||
|
||||
void Cancel() override { EXPECT_TRUE(CefCurrentlyOn(TID_IO)); }
|
||||
|
||||
bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_TRUE(CefCurrentlyOn(TID_IO));
|
||||
bool Read(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
bytes_read = 0;
|
||||
bool has_data = false;
|
||||
|
||||
size_t size = content_.size();
|
||||
if (offset_ < size) {
|
||||
@ -762,10 +769,10 @@ class RedirectSchemeHandler : public CefResourceHandler {
|
||||
offset_ += transfer_size;
|
||||
|
||||
bytes_read = transfer_size;
|
||||
return true;
|
||||
has_data = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return has_data;
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -775,6 +782,7 @@ class RedirectSchemeHandler : public CefResourceHandler {
|
||||
std::string location_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(RedirectSchemeHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(RedirectSchemeHandler);
|
||||
};
|
||||
|
||||
class RedirectSchemeHandlerFactory : public CefSchemeHandlerFactory {
|
||||
@ -795,6 +803,7 @@ class RedirectSchemeHandlerFactory : public CefSchemeHandlerFactory {
|
||||
}
|
||||
|
||||
IMPLEMENT_REFCOUNTING(RedirectSchemeHandlerFactory);
|
||||
DISALLOW_COPY_AND_ASSIGN(RedirectSchemeHandlerFactory);
|
||||
};
|
||||
|
||||
class RedirectTestHandler : public TestHandler {
|
||||
@ -2843,9 +2852,13 @@ class UnstartedSchemeHandler : public CefResourceHandler {
|
||||
public:
|
||||
UnstartedSchemeHandler() {}
|
||||
|
||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
callback->Continue();
|
||||
bool Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
// Continue immediately.
|
||||
handle_request = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2859,10 +2872,12 @@ class UnstartedSchemeHandler : public CefResourceHandler {
|
||||
|
||||
void Cancel() override { callback_ = nullptr; }
|
||||
|
||||
bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
bool Read(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
callback_ = callback;
|
||||
|
||||
// Pretend that we'll provide the data later.
|
||||
@ -2871,9 +2886,10 @@ class UnstartedSchemeHandler : public CefResourceHandler {
|
||||
}
|
||||
|
||||
protected:
|
||||
CefRefPtr<CefCallback> callback_;
|
||||
CefRefPtr<CefResourceReadCallback> callback_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(UnstartedSchemeHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(UnstartedSchemeHandler);
|
||||
};
|
||||
|
||||
// Browser side.
|
||||
@ -3055,9 +3071,13 @@ class StalledSchemeHandler : public CefResourceHandler {
|
||||
public:
|
||||
StalledSchemeHandler() : offset_(0), write_size_(0) {}
|
||||
|
||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
callback->Continue();
|
||||
bool Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
// Continue immediately.
|
||||
handle_request = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3074,18 +3094,23 @@ class StalledSchemeHandler : public CefResourceHandler {
|
||||
|
||||
void Cancel() override { callback_ = nullptr; }
|
||||
|
||||
bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
bool Read(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
bytes_read = 0;
|
||||
|
||||
size_t size = content_.size();
|
||||
if (offset_ >= write_size_) {
|
||||
// Now stall.
|
||||
bytes_read = 0;
|
||||
callback_ = callback;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool has_data = false;
|
||||
|
||||
if (offset_ < size) {
|
||||
// Write up to |write_size_| bytes.
|
||||
int transfer_size =
|
||||
@ -3095,19 +3120,20 @@ class StalledSchemeHandler : public CefResourceHandler {
|
||||
offset_ += transfer_size;
|
||||
|
||||
bytes_read = transfer_size;
|
||||
return true;
|
||||
has_data = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return has_data;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string content_;
|
||||
size_t offset_;
|
||||
size_t write_size_;
|
||||
CefRefPtr<CefCallback> callback_;
|
||||
CefRefPtr<CefResourceReadCallback> callback_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(StalledSchemeHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(StalledSchemeHandler);
|
||||
};
|
||||
|
||||
// Browser side.
|
||||
|
@ -22,6 +22,7 @@ namespace {
|
||||
|
||||
// Normal stream resource handler implementation that additionally verifies
|
||||
// calls to Cancel.
|
||||
// This also tests the CefStreamResourceHandler implementation.
|
||||
class NormalResourceHandler : public CefStreamResourceHandler {
|
||||
public:
|
||||
NormalResourceHandler(int status_code,
|
||||
@ -50,27 +51,186 @@ class NormalResourceHandler : public CefStreamResourceHandler {
|
||||
private:
|
||||
const base::Closure destroy_callback_;
|
||||
int cancel_ct_ = 0;
|
||||
};
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NormalResourceHandler);
|
||||
// Normal stream resource handler implementation that additionally continues
|
||||
// using the callback object and verifies calls to Cancel.
|
||||
class CallbackResourceHandler : public CefResourceHandler {
|
||||
public:
|
||||
enum Mode {
|
||||
DELAYED_OPEN,
|
||||
DELAYED_READ,
|
||||
IMMEDIATE_OPEN,
|
||||
IMMEDIATE_READ,
|
||||
DELAYED_ALL,
|
||||
IMMEDIATE_ALL,
|
||||
};
|
||||
|
||||
bool IsDelayedOpen() const {
|
||||
return mode_ == DELAYED_OPEN || mode_ == DELAYED_ALL;
|
||||
}
|
||||
|
||||
bool IsDelayedRead() const {
|
||||
return mode_ == DELAYED_READ || mode_ == DELAYED_ALL;
|
||||
}
|
||||
|
||||
bool IsImmediateOpen() const {
|
||||
return mode_ == IMMEDIATE_OPEN || mode_ == IMMEDIATE_ALL;
|
||||
}
|
||||
|
||||
bool IsImmediateRead() const {
|
||||
return mode_ == IMMEDIATE_READ || mode_ == IMMEDIATE_ALL;
|
||||
}
|
||||
|
||||
CallbackResourceHandler(Mode mode,
|
||||
int status_code,
|
||||
const CefString& status_text,
|
||||
const CefString& mime_type,
|
||||
CefResponse::HeaderMap header_map,
|
||||
CefRefPtr<CefStreamReader> stream,
|
||||
const base::Closure& destroy_callback)
|
||||
: mode_(mode),
|
||||
status_code_(status_code),
|
||||
status_text_(status_text),
|
||||
mime_type_(mime_type),
|
||||
header_map_(header_map),
|
||||
stream_(stream),
|
||||
destroy_callback_(destroy_callback) {
|
||||
DCHECK(!mime_type_.empty());
|
||||
DCHECK(stream_.get());
|
||||
}
|
||||
|
||||
~CallbackResourceHandler() override {
|
||||
EXPECT_EQ(1, cancel_ct_);
|
||||
destroy_callback_.Run();
|
||||
}
|
||||
|
||||
bool Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
if (IsDelayedOpen()) {
|
||||
// Continue the request asynchronously by executing the callback.
|
||||
CefPostTask(TID_FILE_USER_VISIBLE,
|
||||
base::Bind(&CefCallback::Continue, callback));
|
||||
handle_request = false;
|
||||
return true;
|
||||
} else if (IsImmediateOpen()) {
|
||||
// Continue the request immediately be executing the callback.
|
||||
callback->Continue();
|
||||
handle_request = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Continue the request immediately in the default manner.
|
||||
handle_request = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
||||
int64& response_length,
|
||||
CefString& redirectUrl) override {
|
||||
response->SetStatus(status_code_);
|
||||
response->SetStatusText(status_text_);
|
||||
response->SetMimeType(mime_type_);
|
||||
|
||||
if (!header_map_.empty())
|
||||
response->SetHeaderMap(header_map_);
|
||||
|
||||
response_length = -1;
|
||||
}
|
||||
|
||||
bool Read(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
EXPECT_GT(bytes_to_read, 0);
|
||||
|
||||
bytes_read = 0;
|
||||
|
||||
if (IsDelayedRead()) {
|
||||
// Continue the request asynchronously by executing the callback.
|
||||
CefPostTask(TID_FILE_USER_VISIBLE,
|
||||
base::Bind(&CallbackResourceHandler::ContinueRead, this,
|
||||
data_out, bytes_to_read, callback));
|
||||
return true;
|
||||
} else if (IsImmediateRead()) {
|
||||
// Continue the request immediately be executing the callback.
|
||||
ContinueRead(data_out, bytes_to_read, callback);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Continue the request immediately in the default manner.
|
||||
return DoRead(data_out, bytes_to_read, bytes_read);
|
||||
}
|
||||
|
||||
void Cancel() override {
|
||||
EXPECT_IO_THREAD();
|
||||
cancel_ct_++;
|
||||
}
|
||||
|
||||
private:
|
||||
void ContinueRead(void* data_out,
|
||||
int bytes_to_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
int bytes_read = 0;
|
||||
DoRead(data_out, bytes_to_read, bytes_read);
|
||||
callback->Continue(bytes_read);
|
||||
}
|
||||
|
||||
bool DoRead(void* data_out, int bytes_to_read, int& bytes_read) {
|
||||
DCHECK_GT(bytes_to_read, 0);
|
||||
|
||||
// Read until the buffer is full or until Read() returns 0 to indicate no
|
||||
// more data.
|
||||
bytes_read = 0;
|
||||
int read = 0;
|
||||
do {
|
||||
read = static_cast<int>(
|
||||
stream_->Read(static_cast<char*>(data_out) + bytes_read, 1,
|
||||
bytes_to_read - bytes_read));
|
||||
bytes_read += read;
|
||||
} while (read != 0 && bytes_read < bytes_to_read);
|
||||
|
||||
return (bytes_read > 0);
|
||||
}
|
||||
|
||||
const Mode mode_;
|
||||
|
||||
const int status_code_;
|
||||
const CefString status_text_;
|
||||
const CefString mime_type_;
|
||||
const CefResponse::HeaderMap header_map_;
|
||||
const CefRefPtr<CefStreamReader> stream_;
|
||||
|
||||
const base::Closure destroy_callback_;
|
||||
int cancel_ct_ = 0;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(CallbackResourceHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(CallbackResourceHandler);
|
||||
};
|
||||
|
||||
// Resource handler implementation that never completes. Used to test
|
||||
// destruction handling behavior for in-progress requests.
|
||||
class IncompleteResourceHandler : public CefResourceHandler {
|
||||
class IncompleteResourceHandlerOld : public CefResourceHandler {
|
||||
public:
|
||||
enum TestMode {
|
||||
BLOCK_PROCESS_REQUEST,
|
||||
BLOCK_READ_RESPONSE,
|
||||
};
|
||||
|
||||
IncompleteResourceHandler(TestMode test_mode,
|
||||
const std::string& mime_type,
|
||||
const base::Closure& destroy_callback)
|
||||
IncompleteResourceHandlerOld(TestMode test_mode,
|
||||
const std::string& mime_type,
|
||||
const base::Closure& destroy_callback)
|
||||
: test_mode_(test_mode),
|
||||
mime_type_(mime_type),
|
||||
destroy_callback_(destroy_callback) {}
|
||||
|
||||
~IncompleteResourceHandler() override {
|
||||
~IncompleteResourceHandlerOld() override {
|
||||
EXPECT_EQ(1, process_request_ct_);
|
||||
|
||||
EXPECT_EQ(1, cancel_ct_);
|
||||
@ -147,6 +307,119 @@ class IncompleteResourceHandler : public CefResourceHandler {
|
||||
|
||||
CefRefPtr<CefCallback> incomplete_callback_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(IncompleteResourceHandlerOld);
|
||||
DISALLOW_COPY_AND_ASSIGN(IncompleteResourceHandlerOld);
|
||||
};
|
||||
|
||||
class IncompleteResourceHandler : public CefResourceHandler {
|
||||
public:
|
||||
enum TestMode {
|
||||
BLOCK_OPEN,
|
||||
BLOCK_READ,
|
||||
};
|
||||
|
||||
IncompleteResourceHandler(TestMode test_mode,
|
||||
const std::string& mime_type,
|
||||
const base::Closure& destroy_callback)
|
||||
: test_mode_(test_mode),
|
||||
mime_type_(mime_type),
|
||||
destroy_callback_(destroy_callback) {}
|
||||
|
||||
~IncompleteResourceHandler() override {
|
||||
EXPECT_EQ(1, open_ct_);
|
||||
|
||||
EXPECT_EQ(1, cancel_ct_);
|
||||
|
||||
if (test_mode_ == BLOCK_READ) {
|
||||
EXPECT_EQ(1, get_response_headers_ct_);
|
||||
EXPECT_EQ(1, read_ct_);
|
||||
} else {
|
||||
EXPECT_EQ(0, get_response_headers_ct_);
|
||||
EXPECT_EQ(0, read_ct_);
|
||||
}
|
||||
|
||||
destroy_callback_.Run();
|
||||
}
|
||||
|
||||
bool Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
open_ct_++;
|
||||
|
||||
if (test_mode_ == BLOCK_OPEN) {
|
||||
// Never release or execute this callback.
|
||||
incomplete_open_callback_ = callback;
|
||||
} else {
|
||||
// Continue immediately.
|
||||
handle_request = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_TRUE(false); // Not reached.
|
||||
return false;
|
||||
}
|
||||
|
||||
void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
||||
int64& response_length,
|
||||
CefString& redirectUrl) override {
|
||||
EXPECT_IO_THREAD();
|
||||
EXPECT_EQ(test_mode_, BLOCK_READ);
|
||||
|
||||
get_response_headers_ct_++;
|
||||
|
||||
response->SetStatus(200);
|
||||
response->SetStatusText("OK");
|
||||
response->SetMimeType(mime_type_);
|
||||
response_length = 100;
|
||||
}
|
||||
|
||||
bool Read(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
EXPECT_EQ(test_mode_, BLOCK_READ);
|
||||
|
||||
read_ct_++;
|
||||
|
||||
// Never release or execute this callback.
|
||||
incomplete_read_callback_ = callback;
|
||||
bytes_read = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_TRUE(false); // Not reached.
|
||||
bytes_read = -2;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Cancel() override {
|
||||
EXPECT_IO_THREAD();
|
||||
cancel_ct_++;
|
||||
}
|
||||
|
||||
private:
|
||||
const TestMode test_mode_;
|
||||
const std::string mime_type_;
|
||||
const base::Closure destroy_callback_;
|
||||
|
||||
int open_ct_ = 0;
|
||||
int get_response_headers_ct_ = 0;
|
||||
int read_ct_ = 0;
|
||||
int cancel_ct_ = 0;
|
||||
|
||||
CefRefPtr<CefCallback> incomplete_open_callback_;
|
||||
CefRefPtr<CefResourceReadCallback> incomplete_read_callback_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(IncompleteResourceHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(IncompleteResourceHandler);
|
||||
};
|
||||
@ -175,11 +448,23 @@ class BasicResponseTest : public TestHandler {
|
||||
// Redirect the request (change the URL) in OnBeforeResourceLoad.
|
||||
REDIRECT_BEFORE_RESOURCE_LOAD,
|
||||
|
||||
// Return a CefResourceHandler from GetResourceHandler that continues
|
||||
// immediately by using the callback object instead of the return value.
|
||||
IMMEDIATE_REQUEST_HANDLER_OPEN,
|
||||
IMMEDIATE_REQUEST_HANDLER_READ,
|
||||
IMMEDIATE_REQUEST_HANDLER_ALL,
|
||||
|
||||
// Return a CefResourceHandler from GetResourceHandler that continues with
|
||||
// a delay by using the callback object.
|
||||
DELAYED_REQUEST_HANDLER_OPEN,
|
||||
DELAYED_REQUEST_HANDLER_READ,
|
||||
DELAYED_REQUEST_HANDLER_ALL,
|
||||
|
||||
// Return a CefResourceHandler from GetResourceHandler that never completes,
|
||||
// then close the browser to verify destruction handling of in-progress
|
||||
// requests.
|
||||
INCOMPLETE_REQUEST_HANDLER_PROCESS_REQUEST,
|
||||
INCOMPLETE_REQUEST_HANDLER_READ_RESPONSE,
|
||||
INCOMPLETE_REQUEST_HANDLER_OPEN,
|
||||
INCOMPLETE_REQUEST_HANDLER_READ,
|
||||
|
||||
// Redirect the request using a CefResourceHandler returned from
|
||||
// GetResourceHandler.
|
||||
@ -552,24 +837,7 @@ class BasicResponseTest : public TestHandler {
|
||||
}
|
||||
|
||||
void DestroyTest() override {
|
||||
if (mode_ == LOAD || mode_ == MODIFY_BEFORE_RESOURCE_LOAD) {
|
||||
EXPECT_EQ(1, on_before_browse_ct_);
|
||||
EXPECT_EQ(1, get_resource_request_handler_ct_);
|
||||
EXPECT_EQ(1, get_cookie_access_filter_ct_);
|
||||
EXPECT_EQ(1, on_before_resource_load_ct_);
|
||||
EXPECT_EQ(1, get_resource_handler_ct_);
|
||||
EXPECT_EQ(0, on_resource_redirect_ct_);
|
||||
|
||||
// Unhandled requests won't see a call to GetResourceResponseFilter
|
||||
// or OnResourceResponse.
|
||||
if (unhandled_) {
|
||||
EXPECT_EQ(0, get_resource_response_filter_ct_);
|
||||
EXPECT_EQ(0, on_resource_response_ct_);
|
||||
} else {
|
||||
EXPECT_EQ(1, get_resource_response_filter_ct_);
|
||||
EXPECT_EQ(1, on_resource_response_ct_);
|
||||
}
|
||||
} else if (mode_ == RESTART_RESOURCE_RESPONSE) {
|
||||
if (mode_ == RESTART_RESOURCE_RESPONSE) {
|
||||
EXPECT_EQ(1, on_before_browse_ct_);
|
||||
EXPECT_EQ(2, get_resource_request_handler_ct_);
|
||||
EXPECT_EQ(2, get_cookie_access_filter_ct_);
|
||||
@ -586,6 +854,23 @@ class BasicResponseTest : public TestHandler {
|
||||
EXPECT_EQ(1, get_resource_response_filter_ct_);
|
||||
EXPECT_EQ(2, on_resource_response_ct_);
|
||||
}
|
||||
} else if (IsLoad()) {
|
||||
EXPECT_EQ(1, on_before_browse_ct_);
|
||||
EXPECT_EQ(1, get_resource_request_handler_ct_);
|
||||
EXPECT_EQ(1, get_cookie_access_filter_ct_);
|
||||
EXPECT_EQ(1, on_before_resource_load_ct_);
|
||||
EXPECT_EQ(1, get_resource_handler_ct_);
|
||||
EXPECT_EQ(0, on_resource_redirect_ct_);
|
||||
|
||||
// Unhandled requests won't see a call to GetResourceResponseFilter
|
||||
// or OnResourceResponse.
|
||||
if (unhandled_) {
|
||||
EXPECT_EQ(0, get_resource_response_filter_ct_);
|
||||
EXPECT_EQ(0, on_resource_response_ct_);
|
||||
} else {
|
||||
EXPECT_EQ(1, get_resource_response_filter_ct_);
|
||||
EXPECT_EQ(1, on_resource_response_ct_);
|
||||
}
|
||||
} else if (IsRedirect()) {
|
||||
EXPECT_EQ(2, on_before_browse_ct_);
|
||||
EXPECT_EQ(2, get_resource_request_handler_ct_);
|
||||
@ -634,7 +919,7 @@ class BasicResponseTest : public TestHandler {
|
||||
|
||||
EXPECT_EQ(0, on_resource_redirect_ct_);
|
||||
|
||||
if (mode_ == INCOMPLETE_REQUEST_HANDLER_READ_RESPONSE) {
|
||||
if (mode_ == INCOMPLETE_REQUEST_HANDLER_READ) {
|
||||
EXPECT_EQ(1, get_resource_response_filter_ct_);
|
||||
EXPECT_EQ(1, on_resource_response_ct_);
|
||||
} else {
|
||||
@ -739,46 +1024,96 @@ class BasicResponseTest : public TestHandler {
|
||||
return base::Bind(&BasicResponseTest::MaybeDestroyTest, this, true);
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> GetOKResource() {
|
||||
const std::string& body = GetResponseBody();
|
||||
bool GetCallbackResourceHandlerMode(CallbackResourceHandler::Mode& mode) {
|
||||
switch (mode_) {
|
||||
case IMMEDIATE_REQUEST_HANDLER_OPEN:
|
||||
mode = CallbackResourceHandler::IMMEDIATE_OPEN;
|
||||
return true;
|
||||
case IMMEDIATE_REQUEST_HANDLER_READ:
|
||||
mode = CallbackResourceHandler::IMMEDIATE_READ;
|
||||
return true;
|
||||
case IMMEDIATE_REQUEST_HANDLER_ALL:
|
||||
mode = CallbackResourceHandler::IMMEDIATE_ALL;
|
||||
return true;
|
||||
case DELAYED_REQUEST_HANDLER_OPEN:
|
||||
mode = CallbackResourceHandler::DELAYED_OPEN;
|
||||
return true;
|
||||
case DELAYED_REQUEST_HANDLER_READ:
|
||||
mode = CallbackResourceHandler::DELAYED_READ;
|
||||
return true;
|
||||
case DELAYED_REQUEST_HANDLER_ALL:
|
||||
mode = CallbackResourceHandler::DELAYED_ALL;
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> GetResource(int status_code,
|
||||
const CefString& status_text,
|
||||
const CefString& mime_type,
|
||||
CefResponse::HeaderMap header_map,
|
||||
const std::string& body) {
|
||||
CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
|
||||
const_cast<char*>(body.c_str()), body.size());
|
||||
|
||||
return new NormalResourceHandler(200, "OK", "text/html",
|
||||
CefResponse::HeaderMap(), stream,
|
||||
CallbackResourceHandler::Mode handler_mode;
|
||||
if (GetCallbackResourceHandlerMode(handler_mode)) {
|
||||
return new CallbackResourceHandler(handler_mode, status_code, status_text,
|
||||
mime_type, header_map, stream,
|
||||
GetResourceDestroyCallback());
|
||||
}
|
||||
|
||||
return new NormalResourceHandler(status_code, status_text, mime_type,
|
||||
header_map, stream,
|
||||
GetResourceDestroyCallback());
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> GetOKResource() {
|
||||
return GetResource(200, "OK", "text/html", CefResponse::HeaderMap(),
|
||||
GetResponseBody());
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> GetRedirectResource(
|
||||
const std::string& redirect_url) {
|
||||
const std::string& body = GetRedirectBody();
|
||||
CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
|
||||
const_cast<char*>(body.c_str()), body.size());
|
||||
|
||||
CefResponse::HeaderMap headerMap;
|
||||
headerMap.insert(std::make_pair("Location", redirect_url));
|
||||
|
||||
return new NormalResourceHandler(307, "Temporary Redirect", "text/html",
|
||||
headerMap, stream,
|
||||
GetResourceDestroyCallback());
|
||||
return GetResource(307, "Temporary Redirect", "text/html", headerMap,
|
||||
GetRedirectBody());
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> GetIncompleteResource() {
|
||||
if (TestOldResourceAPI()) {
|
||||
return new IncompleteResourceHandlerOld(
|
||||
mode_ == INCOMPLETE_REQUEST_HANDLER_OPEN
|
||||
? IncompleteResourceHandlerOld::BLOCK_PROCESS_REQUEST
|
||||
: IncompleteResourceHandlerOld::BLOCK_READ_RESPONSE,
|
||||
"text/html", GetResourceDestroyCallback());
|
||||
}
|
||||
|
||||
return new IncompleteResourceHandler(
|
||||
mode_ == INCOMPLETE_REQUEST_HANDLER_PROCESS_REQUEST
|
||||
? IncompleteResourceHandler::BLOCK_PROCESS_REQUEST
|
||||
: IncompleteResourceHandler::BLOCK_READ_RESPONSE,
|
||||
mode_ == INCOMPLETE_REQUEST_HANDLER_OPEN
|
||||
? IncompleteResourceHandler::BLOCK_OPEN
|
||||
: IncompleteResourceHandler::BLOCK_READ,
|
||||
"text/html", GetResourceDestroyCallback());
|
||||
}
|
||||
|
||||
bool IsLoad() const {
|
||||
return mode_ == LOAD || mode_ == MODIFY_BEFORE_RESOURCE_LOAD ||
|
||||
mode_ == RESTART_RESOURCE_RESPONSE;
|
||||
mode_ == RESTART_RESOURCE_RESPONSE ||
|
||||
mode_ == IMMEDIATE_REQUEST_HANDLER_OPEN ||
|
||||
mode_ == IMMEDIATE_REQUEST_HANDLER_READ ||
|
||||
mode_ == IMMEDIATE_REQUEST_HANDLER_ALL ||
|
||||
mode_ == DELAYED_REQUEST_HANDLER_OPEN ||
|
||||
mode_ == DELAYED_REQUEST_HANDLER_READ ||
|
||||
mode_ == DELAYED_REQUEST_HANDLER_ALL;
|
||||
}
|
||||
|
||||
bool IsIncompleteRequestHandler() const {
|
||||
return mode_ == INCOMPLETE_REQUEST_HANDLER_PROCESS_REQUEST ||
|
||||
mode_ == INCOMPLETE_REQUEST_HANDLER_READ_RESPONSE;
|
||||
return mode_ == INCOMPLETE_REQUEST_HANDLER_OPEN ||
|
||||
mode_ == INCOMPLETE_REQUEST_HANDLER_READ;
|
||||
}
|
||||
|
||||
bool IsIncomplete() const {
|
||||
@ -916,7 +1251,7 @@ class BasicResponseTest : public TestHandler {
|
||||
// response.
|
||||
const bool incomplete_unhandled =
|
||||
(mode_ == INCOMPLETE_BEFORE_RESOURCE_LOAD ||
|
||||
mode_ == INCOMPLETE_REQUEST_HANDLER_PROCESS_REQUEST ||
|
||||
mode_ == INCOMPLETE_REQUEST_HANDLER_OPEN ||
|
||||
(IsAborted() && !custom_scheme_));
|
||||
|
||||
if ((unhandled_ && !override_unhandled) || incomplete_unhandled) {
|
||||
@ -932,7 +1267,7 @@ class BasicResponseTest : public TestHandler {
|
||||
EXPECT_STREQ("", response->GetMimeType().ToString().c_str()) << callback;
|
||||
EXPECT_STREQ("", response->GetCharset().ToString().c_str()) << callback;
|
||||
} else {
|
||||
if ((mode_ == INCOMPLETE_REQUEST_HANDLER_READ_RESPONSE || IsAborted()) &&
|
||||
if ((mode_ == INCOMPLETE_REQUEST_HANDLER_READ || IsAborted()) &&
|
||||
callback == kOnResourceLoadComplete) {
|
||||
// We got a response, but we also got aborted.
|
||||
EXPECT_EQ(ERR_ABORTED, response->GetError()) << callback;
|
||||
@ -1059,13 +1394,25 @@ class BasicResponseTest : public TestHandler {
|
||||
unhandled)
|
||||
|
||||
// Tests only supported in handled mode.
|
||||
#define BASIC_TEST_HANDLED_MODES(name, custom) \
|
||||
BASIC_TEST(name##IncompleteBeforeResourceLoad, \
|
||||
INCOMPLETE_BEFORE_RESOURCE_LOAD, custom, false) \
|
||||
BASIC_TEST(name##IncompleteRequestHandlerProcessRequest, \
|
||||
INCOMPLETE_REQUEST_HANDLER_PROCESS_REQUEST, custom, false) \
|
||||
BASIC_TEST(name##IncompleteRequestHandlerReadResponse, \
|
||||
INCOMPLETE_REQUEST_HANDLER_READ_RESPONSE, custom, false)
|
||||
#define BASIC_TEST_HANDLED_MODES(name, custom) \
|
||||
BASIC_TEST(name##ImmediateRequestHandlerOpen, \
|
||||
IMMEDIATE_REQUEST_HANDLER_OPEN, custom, false) \
|
||||
BASIC_TEST(name##ImmediateRequestHandlerRead, \
|
||||
IMMEDIATE_REQUEST_HANDLER_READ, custom, false) \
|
||||
BASIC_TEST(name##ImmediateRequestHandlerAll, IMMEDIATE_REQUEST_HANDLER_ALL, \
|
||||
custom, false) \
|
||||
BASIC_TEST(name##DelayedRequestHandlerOpen, DELAYED_REQUEST_HANDLER_OPEN, \
|
||||
custom, false) \
|
||||
BASIC_TEST(name##DelayedRequestHandlerRead, DELAYED_REQUEST_HANDLER_READ, \
|
||||
custom, false) \
|
||||
BASIC_TEST(name##DelayedRequestHandlerAll, DELAYED_REQUEST_HANDLER_ALL, \
|
||||
custom, false) \
|
||||
BASIC_TEST(name##IncompleteBeforeResourceLoad, \
|
||||
INCOMPLETE_BEFORE_RESOURCE_LOAD, custom, false) \
|
||||
BASIC_TEST(name##IncompleteRequestHandlerOpen, \
|
||||
INCOMPLETE_REQUEST_HANDLER_OPEN, custom, false) \
|
||||
BASIC_TEST(name##IncompleteRequestHandlerRead, \
|
||||
INCOMPLETE_REQUEST_HANDLER_READ, custom, false)
|
||||
|
||||
BASIC_TEST_ALL_MODES(StandardHandled, false, false)
|
||||
BASIC_TEST_ALL_MODES(StandardUnhandled, false, true)
|
||||
@ -1095,11 +1442,23 @@ class SubresourceResponseTest : public RoutingTestHandler {
|
||||
// Redirect the request (change the URL) in OnBeforeResourceLoad.
|
||||
REDIRECT_BEFORE_RESOURCE_LOAD,
|
||||
|
||||
// Return a CefResourceHandler from GetResourceHandler that continues
|
||||
// immediately by using the callback object instead of the return value.
|
||||
IMMEDIATE_REQUEST_HANDLER_OPEN,
|
||||
IMMEDIATE_REQUEST_HANDLER_READ,
|
||||
IMMEDIATE_REQUEST_HANDLER_ALL,
|
||||
|
||||
// Return a CefResourceHandler from GetResourceHandler that continues with
|
||||
// a delay by using the callback object.
|
||||
DELAYED_REQUEST_HANDLER_OPEN,
|
||||
DELAYED_REQUEST_HANDLER_READ,
|
||||
DELAYED_REQUEST_HANDLER_ALL,
|
||||
|
||||
// Return a CefResourceHandler from GetResourceHandler that never completes,
|
||||
// then close the browser to verify destruction handling of in-progress
|
||||
// requests.
|
||||
INCOMPLETE_REQUEST_HANDLER_PROCESS_REQUEST,
|
||||
INCOMPLETE_REQUEST_HANDLER_READ_RESPONSE,
|
||||
INCOMPLETE_REQUEST_HANDLER_OPEN,
|
||||
INCOMPLETE_REQUEST_HANDLER_READ,
|
||||
|
||||
// Redirect the request using a CefResourceHandler returned from
|
||||
// GetResourceHandler.
|
||||
@ -1581,22 +1940,7 @@ class SubresourceResponseTest : public RoutingTestHandler {
|
||||
EXPECT_EQ(1, on_before_browse_ct_);
|
||||
}
|
||||
|
||||
if (mode_ == LOAD || mode_ == MODIFY_BEFORE_RESOURCE_LOAD) {
|
||||
EXPECT_EQ(1, get_resource_request_handler_ct_);
|
||||
EXPECT_EQ(1, get_cookie_access_filter_ct_);
|
||||
EXPECT_EQ(1, on_before_resource_load_ct_);
|
||||
EXPECT_EQ(1, get_resource_handler_ct_);
|
||||
EXPECT_EQ(0, on_resource_redirect_ct_);
|
||||
// Unhandled requests won't see a call to GetResourceResponseFilter or
|
||||
// OnResourceResponse.
|
||||
if (unhandled_) {
|
||||
EXPECT_EQ(0, get_resource_response_filter_ct_);
|
||||
EXPECT_EQ(0, on_resource_response_ct_);
|
||||
} else {
|
||||
EXPECT_EQ(1, get_resource_response_filter_ct_);
|
||||
EXPECT_EQ(1, on_resource_response_ct_);
|
||||
}
|
||||
} else if (mode_ == RESTART_RESOURCE_RESPONSE) {
|
||||
if (mode_ == RESTART_RESOURCE_RESPONSE) {
|
||||
EXPECT_EQ(2, get_resource_request_handler_ct_);
|
||||
EXPECT_EQ(2, get_cookie_access_filter_ct_);
|
||||
EXPECT_EQ(2, on_before_resource_load_ct_);
|
||||
@ -1612,6 +1956,21 @@ class SubresourceResponseTest : public RoutingTestHandler {
|
||||
EXPECT_EQ(1, get_resource_response_filter_ct_);
|
||||
EXPECT_EQ(2, on_resource_response_ct_);
|
||||
}
|
||||
} else if (IsLoad()) {
|
||||
EXPECT_EQ(1, get_resource_request_handler_ct_);
|
||||
EXPECT_EQ(1, get_cookie_access_filter_ct_);
|
||||
EXPECT_EQ(1, on_before_resource_load_ct_);
|
||||
EXPECT_EQ(1, get_resource_handler_ct_);
|
||||
EXPECT_EQ(0, on_resource_redirect_ct_);
|
||||
// Unhandled requests won't see a call to GetResourceResponseFilter or
|
||||
// OnResourceResponse.
|
||||
if (unhandled_) {
|
||||
EXPECT_EQ(0, get_resource_response_filter_ct_);
|
||||
EXPECT_EQ(0, on_resource_response_ct_);
|
||||
} else {
|
||||
EXPECT_EQ(1, get_resource_response_filter_ct_);
|
||||
EXPECT_EQ(1, on_resource_response_ct_);
|
||||
}
|
||||
} else if (IsRedirect()) {
|
||||
EXPECT_EQ(2, get_resource_request_handler_ct_);
|
||||
EXPECT_EQ(2, get_cookie_access_filter_ct_);
|
||||
@ -1655,7 +2014,7 @@ class SubresourceResponseTest : public RoutingTestHandler {
|
||||
|
||||
EXPECT_EQ(0, on_resource_redirect_ct_);
|
||||
|
||||
if (mode_ == INCOMPLETE_REQUEST_HANDLER_READ_RESPONSE) {
|
||||
if (mode_ == INCOMPLETE_REQUEST_HANDLER_READ) {
|
||||
EXPECT_EQ(1, get_resource_response_filter_ct_);
|
||||
EXPECT_EQ(1, on_resource_response_ct_);
|
||||
} else {
|
||||
@ -1812,66 +2171,106 @@ class SubresourceResponseTest : public RoutingTestHandler {
|
||||
return base::Bind(&SubresourceResponseTest::MaybeDestroyTest, this, true);
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> GetMainResource() {
|
||||
const std::string& body = GetMainResponseBody();
|
||||
bool GetCallbackResourceHandlerMode(CallbackResourceHandler::Mode& mode) {
|
||||
switch (mode_) {
|
||||
case IMMEDIATE_REQUEST_HANDLER_OPEN:
|
||||
mode = CallbackResourceHandler::IMMEDIATE_OPEN;
|
||||
return true;
|
||||
case IMMEDIATE_REQUEST_HANDLER_READ:
|
||||
mode = CallbackResourceHandler::IMMEDIATE_READ;
|
||||
return true;
|
||||
case IMMEDIATE_REQUEST_HANDLER_ALL:
|
||||
mode = CallbackResourceHandler::IMMEDIATE_ALL;
|
||||
return true;
|
||||
case DELAYED_REQUEST_HANDLER_OPEN:
|
||||
mode = CallbackResourceHandler::DELAYED_OPEN;
|
||||
return true;
|
||||
case DELAYED_REQUEST_HANDLER_READ:
|
||||
mode = CallbackResourceHandler::DELAYED_READ;
|
||||
return true;
|
||||
case DELAYED_REQUEST_HANDLER_ALL:
|
||||
mode = CallbackResourceHandler::DELAYED_ALL;
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> GetResource(int status_code,
|
||||
const CefString& status_text,
|
||||
const CefString& mime_type,
|
||||
CefResponse::HeaderMap header_map,
|
||||
const std::string& body) {
|
||||
CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
|
||||
const_cast<char*>(body.c_str()), body.size());
|
||||
|
||||
return new NormalResourceHandler(200, "OK", "text/html",
|
||||
CefResponse::HeaderMap(), stream,
|
||||
CallbackResourceHandler::Mode handler_mode;
|
||||
if (GetCallbackResourceHandlerMode(handler_mode)) {
|
||||
return new CallbackResourceHandler(handler_mode, status_code, status_text,
|
||||
mime_type, header_map, stream,
|
||||
GetResourceDestroyCallback());
|
||||
}
|
||||
|
||||
return new NormalResourceHandler(status_code, status_text, mime_type,
|
||||
header_map, stream,
|
||||
GetResourceDestroyCallback());
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> GetMainResource() {
|
||||
return GetResource(200, "OK", "text/html", CefResponse::HeaderMap(),
|
||||
GetMainResponseBody());
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> GetSubResource() {
|
||||
const std::string& body = GetSubResponseBody();
|
||||
CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
|
||||
const_cast<char*>(body.c_str()), body.size());
|
||||
|
||||
return new NormalResourceHandler(200, "OK", "text/html",
|
||||
CefResponse::HeaderMap(), stream,
|
||||
GetResourceDestroyCallback());
|
||||
return GetResource(200, "OK", "text/html", CefResponse::HeaderMap(),
|
||||
GetSubResponseBody());
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> GetOKResource() {
|
||||
const std::string& body = GetResponseBody();
|
||||
CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
|
||||
const_cast<char*>(body.c_str()), body.size());
|
||||
|
||||
return new NormalResourceHandler(200, "OK", "text/javascript",
|
||||
CefResponse::HeaderMap(), stream,
|
||||
GetResourceDestroyCallback());
|
||||
return GetResource(200, "OK", "text/javascript", CefResponse::HeaderMap(),
|
||||
GetResponseBody());
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> GetRedirectResource(
|
||||
const std::string& redirect_url) {
|
||||
const std::string& body = GetRedirectBody();
|
||||
CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
|
||||
const_cast<char*>(body.c_str()), body.size());
|
||||
|
||||
CefResponse::HeaderMap headerMap;
|
||||
headerMap.insert(std::make_pair("Location", redirect_url));
|
||||
|
||||
return new NormalResourceHandler(307, "Temporary Redirect",
|
||||
"text/javascript", headerMap, stream,
|
||||
GetResourceDestroyCallback());
|
||||
return GetResource(307, "Temporary Redirect", "text/javascript", headerMap,
|
||||
GetRedirectBody());
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> GetIncompleteResource() {
|
||||
if (TestOldResourceAPI()) {
|
||||
return new IncompleteResourceHandlerOld(
|
||||
mode_ == INCOMPLETE_REQUEST_HANDLER_OPEN
|
||||
? IncompleteResourceHandlerOld::BLOCK_PROCESS_REQUEST
|
||||
: IncompleteResourceHandlerOld::BLOCK_READ_RESPONSE,
|
||||
"text/javascript", GetResourceDestroyCallback());
|
||||
}
|
||||
|
||||
return new IncompleteResourceHandler(
|
||||
mode_ == INCOMPLETE_REQUEST_HANDLER_PROCESS_REQUEST
|
||||
? IncompleteResourceHandler::BLOCK_PROCESS_REQUEST
|
||||
: IncompleteResourceHandler::BLOCK_READ_RESPONSE,
|
||||
mode_ == INCOMPLETE_REQUEST_HANDLER_OPEN
|
||||
? IncompleteResourceHandler::BLOCK_OPEN
|
||||
: IncompleteResourceHandler::BLOCK_READ,
|
||||
"text/javascript", GetResourceDestroyCallback());
|
||||
}
|
||||
|
||||
bool IsLoad() const {
|
||||
return mode_ == LOAD || mode_ == MODIFY_BEFORE_RESOURCE_LOAD ||
|
||||
mode_ == RESTART_RESOURCE_RESPONSE;
|
||||
mode_ == RESTART_RESOURCE_RESPONSE ||
|
||||
mode_ == IMMEDIATE_REQUEST_HANDLER_OPEN ||
|
||||
mode_ == IMMEDIATE_REQUEST_HANDLER_READ ||
|
||||
mode_ == IMMEDIATE_REQUEST_HANDLER_ALL ||
|
||||
mode_ == DELAYED_REQUEST_HANDLER_OPEN ||
|
||||
mode_ == DELAYED_REQUEST_HANDLER_READ ||
|
||||
mode_ == DELAYED_REQUEST_HANDLER_ALL;
|
||||
}
|
||||
|
||||
bool IsIncompleteRequestHandler() const {
|
||||
return mode_ == INCOMPLETE_REQUEST_HANDLER_PROCESS_REQUEST ||
|
||||
mode_ == INCOMPLETE_REQUEST_HANDLER_READ_RESPONSE;
|
||||
return mode_ == INCOMPLETE_REQUEST_HANDLER_OPEN ||
|
||||
mode_ == INCOMPLETE_REQUEST_HANDLER_READ;
|
||||
}
|
||||
|
||||
bool IsIncomplete() const {
|
||||
@ -2010,7 +2409,7 @@ class SubresourceResponseTest : public RoutingTestHandler {
|
||||
// response.
|
||||
const bool incomplete_unhandled =
|
||||
(mode_ == INCOMPLETE_BEFORE_RESOURCE_LOAD ||
|
||||
mode_ == INCOMPLETE_REQUEST_HANDLER_PROCESS_REQUEST);
|
||||
mode_ == INCOMPLETE_REQUEST_HANDLER_OPEN);
|
||||
|
||||
if ((unhandled_ && !override_unhandled) || incomplete_unhandled) {
|
||||
if (incomplete_unhandled) {
|
||||
@ -2025,7 +2424,7 @@ class SubresourceResponseTest : public RoutingTestHandler {
|
||||
EXPECT_STREQ("", response->GetMimeType().ToString().c_str()) << callback;
|
||||
EXPECT_STREQ("", response->GetCharset().ToString().c_str()) << callback;
|
||||
} else {
|
||||
if (mode_ == INCOMPLETE_REQUEST_HANDLER_READ_RESPONSE &&
|
||||
if (mode_ == INCOMPLETE_REQUEST_HANDLER_READ &&
|
||||
callback == kOnResourceLoadComplete) {
|
||||
// We got a response, but we also got aborted.
|
||||
EXPECT_EQ(ERR_ABORTED, response->GetError()) << callback;
|
||||
@ -2156,15 +2555,25 @@ class SubresourceResponseTest : public RoutingTestHandler {
|
||||
custom, unhandled, subframe)
|
||||
|
||||
// Tests only supported in handled mode.
|
||||
#define SUBRESOURCE_TEST_HANDLED_MODES(name, custom, subframe) \
|
||||
SUBRESOURCE_TEST(name##IncompleteBeforeResourceLoad, \
|
||||
INCOMPLETE_BEFORE_RESOURCE_LOAD, custom, false, subframe) \
|
||||
SUBRESOURCE_TEST(name##IncompleteRequestHandlerProcessRequest, \
|
||||
INCOMPLETE_REQUEST_HANDLER_PROCESS_REQUEST, custom, false, \
|
||||
subframe) \
|
||||
SUBRESOURCE_TEST(name##IncompleteRequestHandlerReadResponse, \
|
||||
INCOMPLETE_REQUEST_HANDLER_READ_RESPONSE, custom, false, \
|
||||
subframe)
|
||||
#define SUBRESOURCE_TEST_HANDLED_MODES(name, custom, subframe) \
|
||||
SUBRESOURCE_TEST(name##ImmediateRequestHandlerOpen, \
|
||||
IMMEDIATE_REQUEST_HANDLER_OPEN, custom, false, subframe) \
|
||||
SUBRESOURCE_TEST(name##ImmediateRequestHandlerRead, \
|
||||
IMMEDIATE_REQUEST_HANDLER_READ, custom, false, subframe) \
|
||||
SUBRESOURCE_TEST(name##ImmediateRequestHandlerAll, \
|
||||
IMMEDIATE_REQUEST_HANDLER_ALL, custom, false, subframe) \
|
||||
SUBRESOURCE_TEST(name##DelayedRequestHandlerOpen, \
|
||||
DELAYED_REQUEST_HANDLER_OPEN, custom, false, subframe) \
|
||||
SUBRESOURCE_TEST(name##DelayedRequestHandlerRead, \
|
||||
DELAYED_REQUEST_HANDLER_READ, custom, false, subframe) \
|
||||
SUBRESOURCE_TEST(name##DelayedRequestHandlerAll, \
|
||||
DELAYED_REQUEST_HANDLER_ALL, custom, false, subframe) \
|
||||
SUBRESOURCE_TEST(name##IncompleteBeforeResourceLoad, \
|
||||
INCOMPLETE_BEFORE_RESOURCE_LOAD, custom, false, subframe) \
|
||||
SUBRESOURCE_TEST(name##IncompleteRequestHandlerOpen, \
|
||||
INCOMPLETE_REQUEST_HANDLER_OPEN, custom, false, subframe) \
|
||||
SUBRESOURCE_TEST(name##IncompleteRequestHandlerRead, \
|
||||
INCOMPLETE_REQUEST_HANDLER_READ, custom, false, subframe)
|
||||
|
||||
SUBRESOURCE_TEST_ALL_MODES(StandardHandledMainFrame, false, false, false)
|
||||
SUBRESOURCE_TEST_ALL_MODES(StandardUnhandledMainFrame, false, true, false)
|
||||
|
@ -212,9 +212,9 @@ class TestSchemeHandler : public TestHandler {
|
||||
IMPLEMENT_REFCOUNTING(TestSchemeHandler);
|
||||
};
|
||||
|
||||
class ClientSchemeHandler : public CefResourceHandler {
|
||||
class ClientSchemeHandlerOld : public CefResourceHandler {
|
||||
public:
|
||||
explicit ClientSchemeHandler(TestResults* tr)
|
||||
explicit ClientSchemeHandlerOld(TestResults* tr)
|
||||
: test_results_(tr), offset_(0), is_sub_(false), has_delayed_(false) {}
|
||||
|
||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
@ -329,10 +329,11 @@ class ClientSchemeHandler : public CefResourceHandler {
|
||||
if (test_results_->delay > 0) {
|
||||
if (!has_delayed_) {
|
||||
// Continue after a delay.
|
||||
CefPostDelayedTask(TID_IO,
|
||||
base::Bind(&ClientSchemeHandler::ContinueAfterDelay,
|
||||
this, callback),
|
||||
test_results_->delay);
|
||||
CefPostDelayedTask(
|
||||
TID_IO,
|
||||
base::Bind(&ClientSchemeHandlerOld::ContinueAfterDelay, this,
|
||||
callback),
|
||||
test_results_->delay);
|
||||
bytes_read = 0;
|
||||
return true;
|
||||
}
|
||||
@ -378,7 +379,206 @@ class ClientSchemeHandler : public CefResourceHandler {
|
||||
bool is_sub_;
|
||||
bool has_delayed_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(ClientSchemeHandlerOld);
|
||||
DISALLOW_COPY_AND_ASSIGN(ClientSchemeHandlerOld);
|
||||
};
|
||||
|
||||
class ClientSchemeHandler : public CefResourceHandler {
|
||||
public:
|
||||
explicit ClientSchemeHandler(TestResults* tr)
|
||||
: test_results_(tr), offset_(0), is_sub_(false), has_delayed_(false) {}
|
||||
|
||||
bool Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
bool handled = false;
|
||||
|
||||
std::string url = request->GetURL();
|
||||
is_sub_ =
|
||||
(!test_results_->sub_url.empty() && test_results_->sub_url == url);
|
||||
|
||||
if (is_sub_) {
|
||||
test_results_->got_sub_request.yes();
|
||||
|
||||
if (!test_results_->sub_html.empty())
|
||||
handled = true;
|
||||
} else {
|
||||
EXPECT_EQ(url, test_results_->url);
|
||||
|
||||
test_results_->got_request.yes();
|
||||
|
||||
if (!test_results_->html.empty())
|
||||
handled = true;
|
||||
}
|
||||
|
||||
std::string accept_language;
|
||||
CefRequest::HeaderMap headerMap;
|
||||
CefRequest::HeaderMap::iterator headerIter;
|
||||
request->GetHeaderMap(headerMap);
|
||||
headerIter = headerMap.find("Accept-Language");
|
||||
if (headerIter != headerMap.end())
|
||||
accept_language = headerIter->second;
|
||||
EXPECT_TRUE(!accept_language.empty());
|
||||
|
||||
if (!test_results_->accept_language.empty()) {
|
||||
// Value from CefBrowserSettings.accept_language set in
|
||||
// PopulateBrowserSettings().
|
||||
EXPECT_STREQ(test_results_->accept_language.data(),
|
||||
accept_language.data());
|
||||
} else {
|
||||
// CEF_SETTINGS_ACCEPT_LANGUAGE value from
|
||||
// CefSettings.accept_language_list set in CefTestSuite::GetSettings()
|
||||
// and expanded internally by ComputeAcceptLanguageFromPref.
|
||||
EXPECT_STREQ("en-GB,en;q=0.9", accept_language.data());
|
||||
}
|
||||
|
||||
// Continue or cancel the request immediately based on the return value.
|
||||
handle_request = true;
|
||||
|
||||
if (handled) {
|
||||
if (test_results_->delay > 0) {
|
||||
// Continue after the delay.
|
||||
handle_request = false;
|
||||
CefPostDelayedTask(TID_FILE_USER_BLOCKING,
|
||||
base::Bind(&CefCallback::Continue, callback.get()),
|
||||
test_results_->delay);
|
||||
}
|
||||
return true;
|
||||
} else if (test_results_->response_error_code != ERR_NONE) {
|
||||
// Propagate the error code.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Response was canceled.
|
||||
if (g_current_handler)
|
||||
g_current_handler->DestroyTest();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_TRUE(false); // Not reached.
|
||||
return false;
|
||||
}
|
||||
|
||||
void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
||||
int64& response_length,
|
||||
CefString& redirectUrl) override {
|
||||
if (is_sub_) {
|
||||
response->SetStatus(test_results_->sub_status_code);
|
||||
|
||||
if (!test_results_->sub_allow_origin.empty()) {
|
||||
// Set the Access-Control-Allow-Origin header to allow cross-domain
|
||||
// scripting.
|
||||
CefResponse::HeaderMap headers;
|
||||
headers.insert(std::make_pair("Access-Control-Allow-Origin",
|
||||
test_results_->sub_allow_origin));
|
||||
response->SetHeaderMap(headers);
|
||||
}
|
||||
|
||||
if (!test_results_->sub_html.empty()) {
|
||||
response->SetMimeType("text/html");
|
||||
response_length = test_results_->sub_html.size();
|
||||
}
|
||||
} else if (!test_results_->redirect_url.empty()) {
|
||||
redirectUrl = test_results_->redirect_url;
|
||||
} else if (test_results_->response_error_code != ERR_NONE) {
|
||||
response->SetError(test_results_->response_error_code);
|
||||
} else {
|
||||
response->SetStatus(test_results_->status_code);
|
||||
|
||||
if (!test_results_->html.empty()) {
|
||||
response->SetMimeType("text/html");
|
||||
response_length = test_results_->html.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cancel() override { EXPECT_TRUE(CefCurrentlyOn(TID_IO)); }
|
||||
|
||||
bool Read(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
if (test_results_->delay > 0) {
|
||||
if (!has_delayed_) {
|
||||
// Continue after a delay.
|
||||
CefPostDelayedTask(TID_FILE_USER_BLOCKING,
|
||||
base::Bind(&ClientSchemeHandler::ContinueAfterDelay,
|
||||
this, data_out, bytes_to_read, callback),
|
||||
test_results_->delay);
|
||||
bytes_read = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
has_delayed_ = false;
|
||||
}
|
||||
|
||||
return GetData(data_out, bytes_to_read, bytes_read);
|
||||
}
|
||||
|
||||
bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_TRUE(false); // Not reached.
|
||||
bytes_read = -2;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
void ContinueAfterDelay(void* data_out,
|
||||
int bytes_to_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
has_delayed_ = true;
|
||||
|
||||
int bytes_read = 0;
|
||||
GetData(data_out, bytes_to_read, bytes_read);
|
||||
callback->Continue(bytes_read);
|
||||
}
|
||||
|
||||
bool GetData(void* data_out, int bytes_to_read, int& bytes_read) {
|
||||
std::string* data;
|
||||
|
||||
if (is_sub_) {
|
||||
test_results_->got_sub_read.yes();
|
||||
data = &test_results_->sub_html;
|
||||
} else {
|
||||
test_results_->got_read.yes();
|
||||
data = &test_results_->html;
|
||||
}
|
||||
|
||||
// Default to response complete.
|
||||
bool has_data = false;
|
||||
bytes_read = 0;
|
||||
|
||||
size_t size = data->size();
|
||||
if (offset_ < size) {
|
||||
int transfer_size =
|
||||
std::min(bytes_to_read, static_cast<int>(size - offset_));
|
||||
memcpy(data_out, data->c_str() + offset_, transfer_size);
|
||||
offset_ += transfer_size;
|
||||
|
||||
bytes_read = transfer_size;
|
||||
has_data = true;
|
||||
}
|
||||
|
||||
return has_data;
|
||||
}
|
||||
|
||||
TestResults* test_results_;
|
||||
size_t offset_;
|
||||
bool is_sub_;
|
||||
bool has_delayed_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(ClientSchemeHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(ClientSchemeHandler);
|
||||
};
|
||||
|
||||
class ClientSchemeHandlerFactory : public CefSchemeHandlerFactory {
|
||||
@ -390,12 +590,16 @@ class ClientSchemeHandlerFactory : public CefSchemeHandlerFactory {
|
||||
const CefString& scheme_name,
|
||||
CefRefPtr<CefRequest> request) override {
|
||||
EXPECT_TRUE(CefCurrentlyOn(TID_IO));
|
||||
if (TestOldResourceAPI()) {
|
||||
return new ClientSchemeHandlerOld(test_results_);
|
||||
}
|
||||
return new ClientSchemeHandler(test_results_);
|
||||
}
|
||||
|
||||
TestResults* test_results_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(ClientSchemeHandlerFactory);
|
||||
DISALLOW_COPY_AND_ASSIGN(ClientSchemeHandlerFactory);
|
||||
};
|
||||
|
||||
// Global test results object.
|
||||
|
@ -3,6 +3,7 @@
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "tests/ceftests/test_util.h"
|
||||
#include "include/cef_command_line.h"
|
||||
#include "include/cef_request_context_handler.h"
|
||||
#include "tests/gtest/include/gtest/gtest.h"
|
||||
|
||||
@ -266,6 +267,16 @@ void TestStringVectorEqual(const std::vector<CefString>& val1,
|
||||
EXPECT_STREQ(val1[i].ToString().c_str(), val2[i].ToString().c_str());
|
||||
}
|
||||
|
||||
bool TestOldResourceAPI() {
|
||||
static int state = -1;
|
||||
if (state == -1) {
|
||||
CefRefPtr<CefCommandLine> command_line =
|
||||
CefCommandLine::GetGlobalCommandLine();
|
||||
state = command_line->HasSwitch("test-old-resource-api") ? 1 : 0;
|
||||
}
|
||||
return state ? true : false;
|
||||
}
|
||||
|
||||
CefRefPtr<CefRequestContext> CreateTestRequestContext(
|
||||
TestRequestContextMode mode,
|
||||
const std::string& cache_path) {
|
||||
|
@ -78,6 +78,9 @@ inline bool IsTestRequestContextModeCustom(TestRequestContextMode mode) {
|
||||
mode == TEST_RC_MODE_CUSTOM_WITH_HANDLER;
|
||||
}
|
||||
|
||||
// Returns true if the old CefResourceHandler API should be tested.
|
||||
bool TestOldResourceAPI();
|
||||
|
||||
// Return a RequestContext object matching the specified |mode|.
|
||||
// |cache_path| may be specified for CUSTOM modes.
|
||||
// Use the RC_TEST_GROUP_BASE macro to test all valid combinations.
|
||||
|
@ -546,13 +546,13 @@ bool IsAuthorized(CefRefPtr<CefRequest> request,
|
||||
// SCHEME HANDLER BACKEND
|
||||
|
||||
// Serves request responses.
|
||||
class RequestSchemeHandler : public CefResourceHandler {
|
||||
class RequestSchemeHandlerOld : public CefResourceHandler {
|
||||
public:
|
||||
RequestSchemeHandler(RequestRunSettings* settings,
|
||||
const base::Closure& destroy_callback)
|
||||
RequestSchemeHandlerOld(RequestRunSettings* settings,
|
||||
const base::Closure& destroy_callback)
|
||||
: settings_(settings), destroy_callback_(destroy_callback) {}
|
||||
|
||||
~RequestSchemeHandler() override {
|
||||
~RequestSchemeHandlerOld() override {
|
||||
EXPECT_EQ(1, cancel_ct_);
|
||||
destroy_callback_.Run();
|
||||
}
|
||||
@ -580,7 +580,7 @@ class RequestSchemeHandler : public CefResourceHandler {
|
||||
response_length = response_data_.length();
|
||||
}
|
||||
|
||||
bool ReadResponse(void* response_data_out,
|
||||
bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
@ -593,8 +593,7 @@ class RequestSchemeHandler : public CefResourceHandler {
|
||||
if (offset_ < size) {
|
||||
int transfer_size =
|
||||
std::min(bytes_to_read, static_cast<int>(size - offset_));
|
||||
memcpy(response_data_out, response_data_.c_str() + offset_,
|
||||
transfer_size);
|
||||
memcpy(data_out, response_data_.c_str() + offset_, transfer_size);
|
||||
offset_ += transfer_size;
|
||||
|
||||
bytes_read = transfer_size;
|
||||
@ -609,6 +608,99 @@ class RequestSchemeHandler : public CefResourceHandler {
|
||||
cancel_ct_++;
|
||||
}
|
||||
|
||||
private:
|
||||
// |settings_| is not owned by this object.
|
||||
RequestRunSettings* settings_;
|
||||
base::Closure destroy_callback_;
|
||||
|
||||
std::string response_data_;
|
||||
size_t offset_ = 0;
|
||||
|
||||
int cancel_ct_ = 0;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(RequestSchemeHandlerOld);
|
||||
DISALLOW_COPY_AND_ASSIGN(RequestSchemeHandlerOld);
|
||||
};
|
||||
|
||||
class RequestSchemeHandler : public CefResourceHandler {
|
||||
public:
|
||||
RequestSchemeHandler(RequestRunSettings* settings,
|
||||
const base::Closure& destroy_callback)
|
||||
: settings_(settings), destroy_callback_(destroy_callback) {}
|
||||
|
||||
~RequestSchemeHandler() override {
|
||||
EXPECT_EQ(1, cancel_ct_);
|
||||
destroy_callback_.Run();
|
||||
}
|
||||
|
||||
bool Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
VerifyNormalRequest(settings_, request, false);
|
||||
|
||||
// HEAD requests are identical to GET requests except no response data is
|
||||
// sent.
|
||||
if (request->GetMethod() != "HEAD")
|
||||
response_data_ = settings_->response_data;
|
||||
|
||||
// Continue immediately.
|
||||
handle_request = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_TRUE(false); // Not reached.
|
||||
return false;
|
||||
}
|
||||
|
||||
void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
||||
int64& response_length,
|
||||
CefString& redirectUrl) override {
|
||||
EXPECT_IO_THREAD();
|
||||
GetNormalResponse(settings_, response);
|
||||
response_length = response_data_.length();
|
||||
}
|
||||
|
||||
bool Read(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
// Default to response complete.
|
||||
bool has_data = false;
|
||||
bytes_read = 0;
|
||||
|
||||
size_t size = response_data_.length();
|
||||
if (offset_ < size) {
|
||||
int transfer_size =
|
||||
std::min(bytes_to_read, static_cast<int>(size - offset_));
|
||||
memcpy(data_out, response_data_.c_str() + offset_, transfer_size);
|
||||
offset_ += transfer_size;
|
||||
|
||||
bytes_read = transfer_size;
|
||||
has_data = true;
|
||||
}
|
||||
|
||||
return has_data;
|
||||
}
|
||||
|
||||
bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_TRUE(false); // Not reached.
|
||||
bytes_read = -2;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Cancel() override {
|
||||
EXPECT_IO_THREAD();
|
||||
cancel_ct_++;
|
||||
}
|
||||
|
||||
private:
|
||||
// |settings_| is not owned by this object.
|
||||
RequestRunSettings* settings_;
|
||||
@ -620,19 +712,20 @@ class RequestSchemeHandler : public CefResourceHandler {
|
||||
int cancel_ct_ = 0;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(RequestSchemeHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(RequestSchemeHandler);
|
||||
};
|
||||
|
||||
// Serves redirect request responses.
|
||||
class RequestRedirectSchemeHandler : public CefResourceHandler {
|
||||
class RequestRedirectSchemeHandlerOld : public CefResourceHandler {
|
||||
public:
|
||||
RequestRedirectSchemeHandler(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefResponse> response,
|
||||
const base::Closure& destroy_callback)
|
||||
RequestRedirectSchemeHandlerOld(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefResponse> response,
|
||||
const base::Closure& destroy_callback)
|
||||
: request_(request),
|
||||
response_(response),
|
||||
destroy_callback_(destroy_callback) {}
|
||||
|
||||
~RequestRedirectSchemeHandler() override {
|
||||
~RequestRedirectSchemeHandlerOld() override {
|
||||
EXPECT_EQ(1, cancel_ct_);
|
||||
destroy_callback_.Run();
|
||||
}
|
||||
@ -679,6 +772,89 @@ class RequestRedirectSchemeHandler : public CefResourceHandler {
|
||||
cancel_ct_++;
|
||||
}
|
||||
|
||||
private:
|
||||
CefRefPtr<CefRequest> request_;
|
||||
CefRefPtr<CefResponse> response_;
|
||||
base::Closure destroy_callback_;
|
||||
|
||||
int cancel_ct_ = 0;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(RequestRedirectSchemeHandlerOld);
|
||||
DISALLOW_COPY_AND_ASSIGN(RequestRedirectSchemeHandlerOld);
|
||||
};
|
||||
|
||||
class RequestRedirectSchemeHandler : public CefResourceHandler {
|
||||
public:
|
||||
RequestRedirectSchemeHandler(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefResponse> response,
|
||||
const base::Closure& destroy_callback)
|
||||
: request_(request),
|
||||
response_(response),
|
||||
destroy_callback_(destroy_callback) {}
|
||||
|
||||
~RequestRedirectSchemeHandler() override {
|
||||
EXPECT_EQ(1, cancel_ct_);
|
||||
destroy_callback_.Run();
|
||||
}
|
||||
|
||||
bool Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
// Verify that the request was sent correctly.
|
||||
TestRequestEqual(request_, request, true);
|
||||
|
||||
// Continue immediately.
|
||||
handle_request = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_TRUE(false); // Not reached.
|
||||
return false;
|
||||
}
|
||||
|
||||
void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
||||
int64& response_length,
|
||||
CefString& redirectUrl) override {
|
||||
EXPECT_IO_THREAD();
|
||||
|
||||
response->SetStatus(response_->GetStatus());
|
||||
response->SetStatusText(response_->GetStatusText());
|
||||
response->SetMimeType(response_->GetMimeType());
|
||||
|
||||
CefResponse::HeaderMap headerMap;
|
||||
response_->GetHeaderMap(headerMap);
|
||||
response->SetHeaderMap(headerMap);
|
||||
|
||||
response_length = 0;
|
||||
}
|
||||
|
||||
bool Read(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) override {
|
||||
EXPECT_TRUE(false); // Not reached.
|
||||
bytes_read = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_TRUE(false); // Not reached.
|
||||
bytes_read = -2;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Cancel() override {
|
||||
EXPECT_IO_THREAD();
|
||||
cancel_ct_++;
|
||||
}
|
||||
|
||||
private:
|
||||
CefRefPtr<CefRequest> request_;
|
||||
CefRefPtr<CefResponse> response_;
|
||||
@ -687,19 +863,20 @@ class RequestRedirectSchemeHandler : public CefResourceHandler {
|
||||
int cancel_ct_ = 0;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(RequestRedirectSchemeHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(RequestRedirectSchemeHandler);
|
||||
};
|
||||
|
||||
// Resource handler implementation that never completes. Used to test
|
||||
// destruction handling behavior for in-progress requests.
|
||||
class IncompleteSchemeHandler : public CefResourceHandler {
|
||||
class IncompleteSchemeHandlerOld : public CefResourceHandler {
|
||||
public:
|
||||
IncompleteSchemeHandler(RequestRunSettings* settings,
|
||||
const base::Closure& destroy_callback)
|
||||
IncompleteSchemeHandlerOld(RequestRunSettings* settings,
|
||||
const base::Closure& destroy_callback)
|
||||
: settings_(settings), destroy_callback_(destroy_callback) {
|
||||
EXPECT_NE(settings_->incomplete_type, RequestRunSettings::INCOMPLETE_NONE);
|
||||
}
|
||||
|
||||
~IncompleteSchemeHandler() override {
|
||||
~IncompleteSchemeHandlerOld() override {
|
||||
EXPECT_EQ(1, process_request_ct_);
|
||||
EXPECT_EQ(1, cancel_ct_);
|
||||
|
||||
@ -783,6 +960,120 @@ class IncompleteSchemeHandler : public CefResourceHandler {
|
||||
|
||||
CefRefPtr<CefCallback> incomplete_callback_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(IncompleteSchemeHandlerOld);
|
||||
DISALLOW_COPY_AND_ASSIGN(IncompleteSchemeHandlerOld);
|
||||
};
|
||||
|
||||
class IncompleteSchemeHandler : public CefResourceHandler {
|
||||
public:
|
||||
IncompleteSchemeHandler(RequestRunSettings* settings,
|
||||
const base::Closure& destroy_callback)
|
||||
: settings_(settings), destroy_callback_(destroy_callback) {
|
||||
EXPECT_NE(settings_->incomplete_type, RequestRunSettings::INCOMPLETE_NONE);
|
||||
}
|
||||
|
||||
~IncompleteSchemeHandler() override {
|
||||
EXPECT_EQ(1, open_ct_);
|
||||
EXPECT_EQ(1, cancel_ct_);
|
||||
|
||||
if (settings_->incomplete_type ==
|
||||
RequestRunSettings::INCOMPLETE_READ_RESPONSE) {
|
||||
EXPECT_EQ(1, get_response_headers_ct_);
|
||||
EXPECT_EQ(1, read_ct_);
|
||||
} else {
|
||||
EXPECT_EQ(0, get_response_headers_ct_);
|
||||
EXPECT_EQ(0, read_ct_);
|
||||
}
|
||||
|
||||
destroy_callback_.Run();
|
||||
}
|
||||
|
||||
bool Open(CefRefPtr<CefRequest> request,
|
||||
bool& handle_request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
|
||||
open_ct_++;
|
||||
|
||||
if (settings_->incomplete_type ==
|
||||
RequestRunSettings::INCOMPLETE_PROCESS_REQUEST) {
|
||||
// Never release or execute this callback.
|
||||
incomplete_open_callback_ = callback;
|
||||
} else {
|
||||
// Continue immediately.
|
||||
handle_request = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_TRUE(false); // Not reached.
|
||||
return false;
|
||||
}
|
||||
|
||||
void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
||||
int64& response_length,
|
||||
CefString& redirectUrl) override {
|
||||
EXPECT_IO_THREAD();
|
||||
EXPECT_EQ(settings_->incomplete_type,
|
||||
RequestRunSettings::INCOMPLETE_READ_RESPONSE);
|
||||
|
||||
get_response_headers_ct_++;
|
||||
|
||||
response->SetStatus(settings_->response->GetStatus());
|
||||
response->SetStatusText(settings_->response->GetStatusText());
|
||||
response->SetMimeType(settings_->response->GetMimeType());
|
||||
|
||||
CefResponse::HeaderMap headerMap;
|
||||
settings_->response->GetHeaderMap(headerMap);
|
||||
settings_->response->SetHeaderMap(headerMap);
|
||||
|
||||
response_length = static_cast<int64>(settings_->response_data.size());
|
||||
}
|
||||
|
||||
bool Read(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefResourceReadCallback> callback) override {
|
||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||
EXPECT_EQ(settings_->incomplete_type,
|
||||
RequestRunSettings::INCOMPLETE_READ_RESPONSE);
|
||||
|
||||
read_ct_++;
|
||||
|
||||
// Never release or execute this callback.
|
||||
incomplete_read_callback_ = callback;
|
||||
bytes_read = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
EXPECT_TRUE(false); // Not reached.
|
||||
bytes_read = -2;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Cancel() override {
|
||||
EXPECT_IO_THREAD();
|
||||
cancel_ct_++;
|
||||
}
|
||||
|
||||
private:
|
||||
RequestRunSettings* const settings_;
|
||||
const base::Closure destroy_callback_;
|
||||
|
||||
int open_ct_ = 0;
|
||||
int get_response_headers_ct_ = 0;
|
||||
int read_ct_ = 0;
|
||||
int cancel_ct_ = 0;
|
||||
|
||||
CefRefPtr<CefCallback> incomplete_open_callback_;
|
||||
CefRefPtr<CefResourceReadCallback> incomplete_read_callback_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(IncompleteSchemeHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(IncompleteSchemeHandler);
|
||||
};
|
||||
@ -805,10 +1096,21 @@ class RequestSchemeHandlerFactory : public CefSchemeHandlerFactory {
|
||||
if (entry.type == RequestDataMap::Entry::TYPE_NORMAL) {
|
||||
if (entry.settings->incomplete_type ==
|
||||
RequestRunSettings::INCOMPLETE_NONE) {
|
||||
if (TestOldResourceAPI()) {
|
||||
return new RequestSchemeHandlerOld(entry.settings, destroy_callback);
|
||||
}
|
||||
return new RequestSchemeHandler(entry.settings, destroy_callback);
|
||||
}
|
||||
|
||||
if (TestOldResourceAPI()) {
|
||||
return new IncompleteSchemeHandlerOld(entry.settings, destroy_callback);
|
||||
}
|
||||
return new IncompleteSchemeHandler(entry.settings, destroy_callback);
|
||||
} else if (entry.type == RequestDataMap::Entry::TYPE_REDIRECT) {
|
||||
if (TestOldResourceAPI()) {
|
||||
return new RequestRedirectSchemeHandlerOld(
|
||||
entry.redirect_request, entry.redirect_response, destroy_callback);
|
||||
}
|
||||
return new RequestRedirectSchemeHandler(
|
||||
entry.redirect_request, entry.redirect_response, destroy_callback);
|
||||
}
|
||||
@ -882,6 +1184,7 @@ class RequestSchemeHandlerFactory : public CefSchemeHandlerFactory {
|
||||
base::Closure shutdown_callback_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(RequestSchemeHandlerFactory);
|
||||
DISALLOW_COPY_AND_ASSIGN(RequestSchemeHandlerFactory);
|
||||
};
|
||||
|
||||
// SERVER BACKEND
|
||||
|
Loading…
x
Reference in New Issue
Block a user