Add support for response filtering (issue #515).

- Add a new CefRequestHandler::GetResourceResponseFilter method and
  CefResponseFilter class.
This commit is contained in:
Marshall Greenblatt
2015-12-04 21:58:56 -05:00
parent 864db71f6b
commit f207a555a3
40 changed files with 1765 additions and 6 deletions

View File

@@ -492,6 +492,17 @@ CefRefPtr<CefResourceHandler> ClientHandler::GetResourceHandler(
return resource_manager_->GetResourceHandler(browser, frame, request);
}
CefRefPtr<CefResponseFilter> ClientHandler::GetResourceResponseFilter(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response) {
CEF_REQUIRE_IO_THREAD();
return test_runner::GetResourceResponseFilter(browser, frame, request,
response);
}
bool ClientHandler::OnQuotaRequest(CefRefPtr<CefBrowser> browser,
const CefString& origin_url,
int64 new_size,

View File

@@ -227,6 +227,11 @@ class ClientHandler : public CefClient,
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) OVERRIDE;
CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response) OVERRIDE;
bool OnQuotaRequest(CefRefPtr<CefBrowser> browser,
const CefString& origin_url,
int64 new_size,

View File

@@ -54,10 +54,11 @@
#define IDS_PERFORMANCE_HTML 1008
#define IDS_PERFORMANCE2_HTML 1009
#define IDS_PREFERENCES_HTML 1010
#define IDS_TRANSPARENCY_HTML 1011
#define IDS_URLREQUEST_HTML 1012
#define IDS_WINDOW_HTML 1013
#define IDS_XMLHTTPREQUEST_HTML 1014
#define IDS_RESPONSE_FILTER_HTML 1011
#define IDS_TRANSPARENCY_HTML 1012
#define IDS_URLREQUEST_HTML 1013
#define IDS_WINDOW_HTML 1014
#define IDS_XMLHTTPREQUEST_HTML 1015
// Next default values for new objects
//

View File

@@ -48,6 +48,7 @@ int GetResourceId(const char* resource_name) {
{"performance.html", IDS_PERFORMANCE_HTML},
{"performance2.html", IDS_PERFORMANCE2_HTML},
{"preferences.html", IDS_PREFERENCES_HTML},
{"response_filter.html", IDS_RESPONSE_FILTER_HTML},
{"transparency.html", IDS_TRANSPARENCY_HTML},
{"urlrequest.html", IDS_URLREQUEST_HTML},
{"window.html", IDS_WINDOW_HTML},

View File

@@ -0,0 +1,242 @@
// 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 "cefclient/browser/response_filter_test.h"
#include <algorithm>
#include <sstream>
#include <string>
#include "include/base/cef_logging.h"
#include "include/cef_command_line.h"
#include "cefclient/common/client_switches.h"
namespace client {
namespace response_filter_test {
namespace {
const char kTestUrl[] = "http://tests/response_filter";
const char kFindString[] = "REPLACE_THIS_STRING";
const char kReplaceString[] = "This is the replaced string!";
// Helper for passing params to Write().
#define WRITE_PARAMS data_out_ptr, data_out_size, data_out_written
// Filter the contents of response_filter.html by replacing all instances of
// |kFindString| with |kReplaceString|. Pass the `--enable-filter-testing`
// command-line flag (which shrinks the buffer size to 32 bytes) to better test
// the logic in this implementation.
class FindReplaceResponseFilter : public CefResponseFilter {
public:
FindReplaceResponseFilter()
: find_match_offset_(0U),
replace_overflow_size_(0U),
replace_count_(0U) {
}
bool InitFilter() OVERRIDE {
const size_t find_size = sizeof(kFindString) - 1;
const size_t replace_size = sizeof(kReplaceString) - 1;
// Determine a reasonable amount of space for find/replace overflow. For
// example, the amount of space required if the search string is
// found/replaced 10 times (plus space for the count).
if (replace_size > find_size)
replace_overflow_size_ = (replace_size - find_size + 3) * 10;
return true;
}
FilterStatus Filter(void* data_in,
size_t data_in_size,
size_t& data_in_read,
void* data_out,
size_t data_out_size,
size_t& data_out_written) OVERRIDE {
DCHECK((data_in_size == 0U && !data_in) || (data_in_size > 0U && data_in));
DCHECK_EQ(data_in_read, 0U);
DCHECK(data_out);
DCHECK_GT(data_out_size, 0U);
DCHECK_EQ(data_out_written, 0U);
// All data will be read.
data_in_read = data_in_size;
const size_t find_size = sizeof(kFindString) - 1;
const char* data_in_ptr = static_cast<char*>(data_in);
char* data_out_ptr = static_cast<char*>(data_out);
// Reset the overflow.
std::string old_overflow;
if (!overflow_.empty()) {
old_overflow = overflow_;
overflow_.clear();
}
const size_t likely_out_size =
data_in_size + replace_overflow_size_ + old_overflow.size();
if (data_out_size < likely_out_size) {
// We'll likely need to use the overflow buffer. Size it appropriately.
overflow_.reserve(likely_out_size - data_out_size);
}
if (!old_overflow.empty()) {
// Write the overflow from last time.
Write(old_overflow.c_str(), old_overflow.size(), WRITE_PARAMS);
}
// Evaluate each character in the input buffer. Track how many characters in
// a row match kFindString. If kFindString is completely matched then write
// kReplaceString. Otherwise, write the input characters as-is.
for (size_t i = 0U; i < data_in_size; ++i) {
if (data_in_ptr[i] == kFindString[find_match_offset_]) {
// Matched the next character in the find string.
if (++find_match_offset_ == find_size) {
// Complete match of the find string. Write the replace string.
std::stringstream ss;
ss << ++replace_count_ << ". " << kReplaceString;
const std::string& replace_str = ss.str();
Write(replace_str.c_str(), replace_str.size(), WRITE_PARAMS);
// Start over looking for a match.
find_match_offset_ = 0;
}
continue;
}
// Character did not match the find string.
if (find_match_offset_ > 0) {
// Write the portion of the find string that has matched so far.
Write(kFindString, find_match_offset_, WRITE_PARAMS);
// Start over looking for a match.
find_match_offset_ = 0;
}
// Write the current character.
Write(&data_in_ptr[i], 1, WRITE_PARAMS);
}
// If a match is currently in-progress we need more data. Otherwise, we're
// done.
return find_match_offset_ > 0 ?
RESPONSE_FILTER_NEED_MORE_DATA : RESPONSE_FILTER_DONE;
}
private:
inline void Write(const char* str,
size_t str_size,
char*& data_out_ptr,
size_t data_out_size,
size_t& data_out_written) {
// Number of bytes remaining in the output buffer.
const size_t remaining_space = data_out_size - data_out_written;
// Maximum number of bytes we can write into the output buffer.
const size_t max_write = std::min(str_size, remaining_space);
// Write the maximum portion that fits in the output buffer.
if (max_write == 1) {
// Small optimization for single character writes.
*data_out_ptr = str[0];
data_out_ptr += 1;
data_out_written += 1;
} else if (max_write > 1) {
memcpy(data_out_ptr, str, max_write);
data_out_ptr += max_write;
data_out_written += max_write;
}
if (max_write < str_size) {
// Need to write more bytes than will fit in the output buffer. Store the
// remainder in the overflow buffer.
overflow_ += std::string(str + max_write, str_size - max_write);
}
}
// The portion of the find string that is currently matching.
size_t find_match_offset_;
// The likely amount of overflow.
size_t replace_overflow_size_;
// Overflow from the output buffer.
std::string overflow_;
// Number of times the the string was found/replaced.
size_t replace_count_;
IMPLEMENT_REFCOUNTING(FindReplaceResponseFilter);
};
// Filter that writes out all of the contents unchanged.
class PassThruResponseFilter : public CefResponseFilter {
public:
PassThruResponseFilter() {}
bool InitFilter() OVERRIDE {
return true;
}
FilterStatus Filter(void* data_in,
size_t data_in_size,
size_t& data_in_read,
void* data_out,
size_t data_out_size,
size_t& data_out_written) OVERRIDE {
DCHECK((data_in_size == 0U && !data_in) || (data_in_size > 0U && data_in));
DCHECK_EQ(data_in_read, 0U);
DCHECK(data_out);
DCHECK_GT(data_out_size, 0U);
DCHECK_EQ(data_out_written, 0U);
// All data will be read.
data_in_read = data_in_size;
// Write out the contents unchanged.
data_out_written = std::min(data_in_read, data_out_size);
if (data_out_written > 0)
memcpy(data_out, data_in, data_out_written);
return RESPONSE_FILTER_DONE;
}
private:
IMPLEMENT_REFCOUNTING(PassThruResponseFilter);
};
// Returns true if |url| starts with the value specified via the `--filter-url`
// command-line flag.
bool MatchesFilterURL(const std::string& url) {
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
if (command_line->HasSwitch(switches::kFilterURL)) {
const std::string& filter_url =
command_line->GetSwitchValue(switches::kFilterURL);
return url.find(filter_url) == 0;
}
return false;
}
} // namespace
CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response) {
// Use the find/replace filter on the test URL.
const std::string& url = request->GetURL();
if (url.find(kTestUrl) == 0)
return new FindReplaceResponseFilter();
if (MatchesFilterURL(url))
return new PassThruResponseFilter();
return NULL;
}
} // namespace response_filter_test
} // namespace client

View File

@@ -0,0 +1,27 @@
// 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.
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_RESPONSE_FILTER_TEST_H_
#define CEF_TESTS_CEFCLIENT_BROWSER_RESPONSE_FILTER_TEST_H_
#pragma once
#include "include/cef_browser.h"
#include "include/cef_request.h"
#include "include/cef_response.h"
#include "include/cef_response_filter.h"
namespace client {
namespace response_filter_test {
// Create a resource response filter. Called from test_runner.cc.
CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response);
} // namespace response_filter_test
} // namespace client
#endif // CEF_TESTS_CEFCLIENT_BROWSER_RESPONSE_FILTER_TEST_H_

View File

@@ -19,6 +19,7 @@
#include "cefclient/browser/preferences_test.h"
#include "cefclient/browser/resource.h"
#include "cefclient/browser/resource_util.h"
#include "cefclient/browser/response_filter_test.h"
#include "cefclient/browser/root_window_manager.h"
#include "cefclient/browser/scheme_test.h"
#include "cefclient/browser/urlrequest_test.h"
@@ -729,5 +730,15 @@ void RegisterSchemeHandlers() {
scheme_test::RegisterSchemeHandlers();
}
CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response) {
// Create the response filter.
return response_filter_test::GetResourceResponseFilter(browser, frame,
request, response);
}
} // namespace test_runner
} // namespace client

View File

@@ -44,6 +44,13 @@ void CreateMessageHandlers(MessageHandlerSet& handlers);
// Register scheme handlers for tests.
void RegisterSchemeHandlers();
// Create a resource response filter for tests.
CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response);
} // namespace test_runner
} // namespace client

View File

@@ -28,6 +28,7 @@ const char kMouseCursorChangeDisabled[] = "mouse-cursor-change-disabled";
const char kRequestContextPerBrowser[] = "request-context-per-browser";
const char kBackgroundColor[] = "background-color";
const char kEnableGPU[] = "enable-gpu";
const char kFilterURL[] = "filter-url";
} // namespace switches
} // namespace client

View File

@@ -22,6 +22,7 @@ extern const char kMouseCursorChangeDisabled[];
extern const char kRequestContextPerBrowser[];
extern const char kBackgroundColor[];
extern const char kEnableGPU[];
extern const char kFilterURL[];
} // namespace switches
} // namespace client

View File

@@ -23,6 +23,7 @@
<li><a href="http://tests/pdf">PDF Viewer iframe</a></li>
<li><a href="http://tests/preferences">Preferences</a></li>
<li><a href="http://mrdoob.com/lab/javascript/requestanimationframe/">requestAnimationFrame</a></li>
<li><a href="http://tests/response_filter">Response Filtering</a></li>
<li><a href="client://tests/handler.html">Scheme Handler</a></li>
<li><a href="https://www.google.com/intl/en/chrome/demos/speech.html">Speech Input</a> - requires "enable-speech-input" flag</li>
<li><a href="http://tests/transparency">Transparency</a></li>

View File

@@ -0,0 +1,76 @@
<html>
<head>
<title>Response Filter Test</title>
</head>
<body bgcolor="white">
<p>The text shown below in <font color="red">red</font> has been replaced by the filter. This document is > 32kb in order to exceed the standard output buffer size.</p>
<p><font color="red">REPLACE_THIS_STRING</font></p>
<p>0. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>1. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>2. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>3. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>4. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>5. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>6. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>7. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>8. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>9. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p><font color="red">REPLACE_THIS_STRING</font></p>
<p>0. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>1. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>2. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>3. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>4. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>5. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>6. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>7. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>8. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>9. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p><font color="red">REPLACE_THIS_STRING</font></p>
<p>0. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>1. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>2. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>3. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>4. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>5. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>6. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>7. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>8. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>9. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p><font color="red">REPLACE_THIS_STRING</font></p>
<p>0. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>1. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>2. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>3. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>4. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>5. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>6. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>7. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>8. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>9. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p><font color="red">REPLACE_THIS_STRING</font></p>
<p>0. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>1. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>2. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>3. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>4. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>5. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>6. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>7. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>8. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>9. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p><font color="red">REPLACE_THIS_STRING</font></p>
<p>0. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>1. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>2. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>3. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>4. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>5. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>6. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>7. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>8. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p>9. It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.</p>
<p><font color="red">REPLACE_THIS_STRING</font></p>
<p>End.</p>
</body>
</html>

View File

@@ -40,6 +40,7 @@ IDS_PDF_PDF BINARY "..\\pdf.pdf"
IDS_PERFORMANCE_HTML BINARY "..\\performance.html"
IDS_PERFORMANCE2_HTML BINARY "..\\performance2.html"
IDS_PREFERENCES_HTML BINARY "..\\preferences.html"
IDS_RESPONSE_FILTER_HTML BINARY "..\\response_filter.html"
IDS_TRANSPARENCY_HTML BINARY "..\\transparency.html"
IDS_URLREQUEST_HTML BINARY "..\\urlrequest.html"
IDS_WINDOW_HTML BINARY "..\\window.html"

View File

@@ -5,6 +5,9 @@
// Include this first to avoid type conflicts with CEF headers.
#include "tests/unittests/chromium_includes.h"
#include <algorithm>
#include <string>
#include "base/strings/stringprintf.h"
#include "include/base/cef_bind.h"
@@ -1178,6 +1181,535 @@ TEST(RequestHandlerTest, BeforeResourceLoadContinueAsync) {
}
namespace {
// For response filtering we need to test:
// - Passing through content unchanged.
// - Not reading all of the input buffer.
// - Needing more input and getting it.
// - Needing more input and not getting it.
// - Filter error.
const char kResponseFilterTestUrl[] = "http://tests.com/response_filter.html";
const size_t kResponseBufferSize = 1024 * 32; // 32kb
const char kInputHeader[] = "<html><head></head><body>";
const char kInputFooter[] = "</body></html>";
// Repeat |content| the minimum number of times necessary to satisfy
// |desired_min_size|. If |calculated_repeat_ct| is non-NULL it will be set to
// the number of times that |content| was repeated.
std::string CreateInput(const std::string& content,
size_t desired_min_size,
size_t* calculated_repeat_ct = nullptr) {
const size_t header_footer_size =
sizeof(kInputHeader) + sizeof(kInputFooter) - 2;
EXPECT_GE(desired_min_size, header_footer_size + content.size());
desired_min_size -= header_footer_size;
size_t repeat_ct = static_cast<size_t>(
std::ceil(static_cast<double>(desired_min_size) /
static_cast<double>(content.size())));
if (calculated_repeat_ct)
*calculated_repeat_ct = repeat_ct;
std::string result;
result.reserve(header_footer_size + (content.size() * repeat_ct));
result = kInputHeader;
while (repeat_ct--)
result += content;
result += kInputFooter;
return result;
}
std::string CreateOutput(const std::string& content,
size_t repeat_ct) {
const size_t header_footer_size =
sizeof(kInputHeader) + sizeof(kInputFooter) - 2;
std::string result;
result.reserve(header_footer_size + (content.size() * repeat_ct));
result = kInputHeader;
while (repeat_ct--)
result += content;
result += kInputFooter;
return result;
}
// Base class for test filters.
class ResponseFilterTestBase : public CefResponseFilter {
public:
ResponseFilterTestBase()
: filter_count_(0U) {
}
bool InitFilter() override {
EXPECT_FALSE(got_init_filter_);
got_init_filter_.yes();
return true;
}
FilterStatus Filter(void* data_in,
size_t data_in_size,
size_t& data_in_read,
void* data_out,
size_t data_out_size,
size_t& data_out_written) override {
if (data_in_size == 0U)
EXPECT_FALSE(data_in);
else
EXPECT_TRUE(data_in);
EXPECT_EQ(data_in_read, 0U);
EXPECT_TRUE(data_out);
EXPECT_GT(data_out_size, 0U);
EXPECT_EQ(data_out_written, 0U);
filter_count_++;
return RESPONSE_FILTER_ERROR;
}
// Returns the input that will be fed into the filter.
virtual std::string GetInput() = 0;
// Verify the output from the filter.
virtual void VerifyOutput(cef_urlrequest_status_t status,
int64 received_content_length,
const std::string& received_content) {
EXPECT_TRUE(got_init_filter_);
EXPECT_GT(filter_count_, 0U);
}
protected:
TrackCallback got_init_filter_;
size_t filter_count_;
IMPLEMENT_REFCOUNTING(ResponseFilterTestBase);
};
// Pass through the contents unchanged.
class ResponseFilterPassThru : public ResponseFilterTestBase {
public:
explicit ResponseFilterPassThru(bool limit_read)
: limit_read_(limit_read) {
}
FilterStatus Filter(void* data_in,
size_t data_in_size,
size_t& data_in_read,
void* data_out,
size_t data_out_size,
size_t& data_out_written) override {
ResponseFilterTestBase::Filter(data_in, data_in_size, data_in_read,
data_out, data_out_size, data_out_written);
if (limit_read_) {
// Read at most 1k bytes.
data_in_read = std::min(data_in_size, static_cast<size_t>(1024U));
} else {
// Read all available bytes.
data_in_read = data_in_size;
}
data_out_written = std::min(data_in_read, data_out_size);
memcpy(data_out, data_in, data_out_written);
return RESPONSE_FILTER_DONE;
}
std::string GetInput() override {
input_ = CreateInput("FOOBAR ", kResponseBufferSize * 2U);
return input_;
}
void VerifyOutput(cef_urlrequest_status_t status,
int64 received_content_length,
const std::string& received_content) override {
ResponseFilterTestBase::VerifyOutput(status, received_content_length,
received_content);
if (limit_read_)
// Expected to read 2 full buffers of kResponseBufferSize at 1kb
// increments (2 * 32) and one partial buffer.
EXPECT_EQ(filter_count_, 2U * 32U + 1U);
else {
// Expected to read 2 full buffers of kResponseBufferSize and one partial
// buffer.
EXPECT_EQ(filter_count_, 3U);
}
EXPECT_STREQ(input_.c_str(), received_content.c_str());
// Input size and content size should match.
EXPECT_EQ(input_.size(), static_cast<size_t>(received_content_length));
EXPECT_EQ(input_.size(), received_content.size());
}
private:
std::string input_;
bool limit_read_;
};
const char kFindString[] = "REPLACE_THIS_STRING";
const char kReplaceString[] = "This is the replaced string!";
// Helper for passing params to Write().
#define WRITE_PARAMS data_out_ptr, data_out_size, data_out_written
// Replace all instances of |kFindString| with |kReplaceString|.
// This implementation is similar to the example in
// tests/cefclient/response_filter_test.cc.
class ResponseFilterNeedMore : public ResponseFilterTestBase {
public:
ResponseFilterNeedMore()
: find_match_offset_(0U),
replace_overflow_size_(0U),
input_size_(0U),
repeat_ct_(0U) {
}
FilterStatus Filter(void* data_in,
size_t data_in_size,
size_t& data_in_read,
void* data_out,
size_t data_out_size,
size_t& data_out_written) override {
ResponseFilterTestBase::Filter(data_in, data_in_size, data_in_read,
data_out, data_out_size, data_out_written);
// All data will be read.
data_in_read = data_in_size;
const size_t find_size = sizeof(kFindString) - 1;
const char* data_in_ptr = static_cast<char*>(data_in);
char* data_out_ptr = static_cast<char*>(data_out);
// Reset the overflow.
std::string old_overflow;
if (!overflow_.empty()) {
old_overflow = overflow_;
overflow_.clear();
}
const size_t likely_out_size =
data_in_size + replace_overflow_size_ + old_overflow.size();
if (data_out_size < likely_out_size) {
// We'll likely need to use the overflow buffer. Size it appropriately.
overflow_.reserve(likely_out_size - data_out_size);
}
if (!old_overflow.empty()) {
// Write the overflow from last time.
Write(old_overflow.c_str(), old_overflow.size(), WRITE_PARAMS);
}
// Evaluate each character in the input buffer. Track how many characters in
// a row match kFindString. If kFindString is completely matched then write
// kReplaceString. Otherwise, write the input characters as-is.
for (size_t i = 0U; i < data_in_size; ++i) {
if (data_in_ptr[i] == kFindString[find_match_offset_]) {
// Matched the next character in the find string.
if (++find_match_offset_ == find_size) {
// Complete match of the find string. Write the replace string.
Write(kReplaceString, sizeof(kReplaceString) - 1, WRITE_PARAMS);
// Start over looking for a match.
find_match_offset_ = 0;
}
continue;
}
// Character did not match the find string.
if (find_match_offset_ > 0) {
// Write the portion of the find string that has matched so far.
Write(kFindString, find_match_offset_, WRITE_PARAMS);
// Start over looking for a match.
find_match_offset_ = 0;
}
// Write the current character.
Write(&data_in_ptr[i], 1, WRITE_PARAMS);
}
// If a match is currently in-progress we need more data. Otherwise, we're
// done.
return find_match_offset_ > 0 ?
RESPONSE_FILTER_NEED_MORE_DATA : RESPONSE_FILTER_DONE;
}
std::string GetInput() override {
const std::string& input =
CreateInput(std::string(kFindString) + " ", kResponseBufferSize * 2U,
&repeat_ct_);
input_size_ = input.size();
const size_t find_size = sizeof(kFindString) - 1;
const size_t replace_size = sizeof(kReplaceString) - 1;
// Determine a reasonable amount of space for find/replace overflow.
if (replace_size > find_size)
replace_overflow_size_ = (replace_size - find_size) * repeat_ct_;
return input;
}
void VerifyOutput(cef_urlrequest_status_t status,
int64 received_content_length,
const std::string& received_content) override {
ResponseFilterTestBase::VerifyOutput(status, received_content_length,
received_content);
const std::string& output =
CreateOutput(std::string(kReplaceString) + " ", repeat_ct_);
EXPECT_STREQ(output.c_str(), received_content.c_str());
// Pre-filter content length should be the original input size.
EXPECT_EQ(input_size_, static_cast<size_t>(received_content_length));
// Filtered content length should be the output size.
EXPECT_EQ(output.size(), received_content.size());
// Expected to read 2 full buffers of kResponseBufferSize and one partial
// buffer, and then one additional call to drain the overflow.
EXPECT_EQ(filter_count_, 4U);
}
private:
inline void Write(const char* str,
size_t str_size,
char*& data_out_ptr,
size_t data_out_size,
size_t& data_out_written) {
// Number of bytes remaining in the output buffer.
const size_t remaining_space = data_out_size - data_out_written;
// Maximum number of bytes we can write into the output buffer.
const size_t max_write = std::min(str_size, remaining_space);
// Write the maximum portion that fits in the output buffer.
if (max_write == 1) {
// Small optimization for single character writes.
*data_out_ptr = str[0];
data_out_ptr += 1;
data_out_written += 1;
} else if (max_write > 1) {
memcpy(data_out_ptr, str, max_write);
data_out_ptr += max_write;
data_out_written += max_write;
}
if (max_write < str_size) {
// Need to write more bytes than will fit in the output buffer. Store the
// remainder in the overflow buffer.
overflow_ += std::string(str + max_write, str_size - max_write);
}
}
// The portion of the find string that is currently matching.
size_t find_match_offset_;
// The likely amount of overflow.
size_t replace_overflow_size_;
// Overflow from the output buffer.
std::string overflow_;
// The original input size.
size_t input_size_;
// The number of times the find string was repeated.
size_t repeat_ct_;
};
// Return a filter error.
class ResponseFilterError : public ResponseFilterTestBase {
public:
ResponseFilterError() {
}
FilterStatus Filter(void* data_in,
size_t data_in_size,
size_t& data_in_read,
void* data_out,
size_t data_out_size,
size_t& data_out_written) override {
ResponseFilterTestBase::Filter(data_in, data_in_size, data_in_read,
data_out, data_out_size, data_out_written);
return RESPONSE_FILTER_ERROR;
}
std::string GetInput() override {
return kInputHeader + std::string("ERROR") + kInputFooter;
}
void VerifyOutput(cef_urlrequest_status_t status,
int64 received_content_length,
const std::string& received_content) override {
ResponseFilterTestBase::VerifyOutput(status, received_content_length,
received_content);
EXPECT_EQ(UR_FAILED, status);
// Expect empty content.
const std::string& output = std::string(kInputHeader) + kInputFooter;
EXPECT_STREQ(output.c_str(), received_content.c_str());
EXPECT_EQ(0U, received_content_length);
// Expect to only be called one time.
EXPECT_EQ(filter_count_, 1U);
}
};
// Browser side.
class ResponseFilterTestHandler : public TestHandler {
public:
explicit ResponseFilterTestHandler(
CefRefPtr<ResponseFilterTestBase> response_filter)
: response_filter_(response_filter) {}
void RunTest() override {
const std::string& resource = response_filter_->GetInput();
AddResource(kResponseFilterTestUrl, resource, "text/html");
// Create the browser.
CreateBrowser(kResponseFilterTestUrl);
// Time out the test after a reasonable period of time.
SetTestTimeout();
}
CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response) override {
EXPECT_IO_THREAD();
DCHECK(!got_resource_response_filter_);
got_resource_response_filter_.yes();
return response_filter_;
}
void OnResourceLoadComplete(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response,
URLRequestStatus status,
int64 received_content_length) override {
EXPECT_IO_THREAD();
DCHECK(!got_resource_load_complete_);
got_resource_load_complete_.yes();
status_ = status;
received_content_length_ = received_content_length;
}
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) override {
DCHECK(!got_load_end_);
got_load_end_.yes();
EXPECT_EQ(200, httpStatusCode);
GetOutputContent(frame);
}
private:
// Retrieve the output content using a StringVisitor. This effectively
// serializes the DOM from the renderer process so any comparison to the
// filter output is somewhat error-prone.
void GetOutputContent(CefRefPtr<CefFrame> frame) {
class StringVisitor : public CefStringVisitor {
public:
typedef base::Callback<void(const std::string& /*received_content*/)>
VisitorCallback;
explicit StringVisitor(const VisitorCallback& callback)
: callback_(callback) {}
void Visit(const CefString& string) override {
callback_.Run(string);
callback_.Reset();
}
private:
VisitorCallback callback_;
IMPLEMENT_REFCOUNTING(StringVisitor);
};
frame->GetSource(new StringVisitor(
base::Bind(&ResponseFilterTestHandler::VerifyOutput, this)));
}
void VerifyOutput(const std::string& received_content) {
response_filter_->VerifyOutput(status_, received_content_length_,
received_content);
response_filter_ = nullptr;
DestroyTest();
}
void DestroyTest() override {
EXPECT_TRUE(got_resource_response_filter_);
EXPECT_TRUE(got_resource_load_complete_);
EXPECT_TRUE(got_load_end_);
TestHandler::DestroyTest();
}
CefRefPtr<ResponseFilterTestBase> response_filter_;
TrackCallback got_resource_response_filter_;
TrackCallback got_resource_load_complete_;
TrackCallback got_load_end_;
URLRequestStatus status_;
int64 received_content_length_;
IMPLEMENT_REFCOUNTING(ResponseFilterTestHandler);
};
} // namespace
// Pass through contents unchanged. Read all available input.
TEST(RequestHandlerTest, ResponseFilterPassThruReadAll) {
CefRefPtr<ResponseFilterTestHandler> handler =
new ResponseFilterTestHandler(new ResponseFilterPassThru(false));
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
// Pass through contents unchanged. Read limited input.
TEST(RequestHandlerTest, ResponseFilterPassThruReadLimited) {
CefRefPtr<ResponseFilterTestHandler> handler =
new ResponseFilterTestHandler(new ResponseFilterPassThru(true));
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
// Find/replace contents such that we occasionally need more data.
TEST(RequestHandlerTest, ResponseFilterNeedMore) {
CefRefPtr<ResponseFilterTestHandler> handler =
new ResponseFilterTestHandler(new ResponseFilterNeedMore());
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
// Error during filtering.
TEST(RequestHandlerTest, ResponseFilterError) {
CefRefPtr<ResponseFilterTestHandler> handler =
new ResponseFilterTestHandler(new ResponseFilterError());
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
// Entry point for creating request handler browser test objects.
// Called from client_app_delegates.cc.
void CreateRequestHandlerBrowserTests(

View File

@@ -231,6 +231,22 @@ class RequestSendRecvTestHandler : public TestHandler {
return false;
}
CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response) override {
EXPECT_IO_THREAD();
TestRequest(request);
EXPECT_TRUE(request->IsReadOnly());
TestResponse(response);
EXPECT_TRUE(response->IsReadOnly());
got_resource_response_filter_.yes();
return NULL;
}
void OnResourceLoadComplete(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
@@ -269,6 +285,7 @@ class RequestSendRecvTestHandler : public TestHandler {
EXPECT_TRUE(got_before_resource_load_);
EXPECT_TRUE(got_resource_handler_);
EXPECT_TRUE(got_resource_response_);
EXPECT_TRUE(got_resource_response_filter_);
EXPECT_TRUE(got_resource_load_complete_);
TestHandler::DestroyTest();
@@ -281,6 +298,7 @@ class RequestSendRecvTestHandler : public TestHandler {
TrackCallback got_before_resource_load_;
TrackCallback got_resource_handler_;
TrackCallback got_resource_response_;
TrackCallback got_resource_response_filter_;
TrackCallback got_resource_load_complete_;
IMPLEMENT_REFCOUNTING(RequestSendRecvTestHandler);