cef/tests/unittests/web_urlrequest_unittest.cc

524 lines
14 KiB
C++

// Copyright (c) 2011 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 "include/cef_web_urlrequest.h"
#include "tests/unittests/test_handler.h"
// #define WEB_URLREQUEST_DEBUG
class TestResults {
public:
TestResults()
: errorCode(0),
contentLength(0),
statusCode(0),
redirectCount(0) {
}
int errorCode;
size_t contentLength;
int statusCode;
CefString statusText;
CefString contentLengthHeader;
CefString allHeaders;
CefResponse::HeaderMap headerMap;
int redirectCount;
TrackCallback
got_redirect,
got_deleted,
got_started,
got_headers,
got_loading,
got_done,
got_progress,
got_abort,
got_error;
};
class BrowserTestHandler : public TestHandler {
public:
// Cancel at state WUR_STATE_UNSENT means that no cancellation
// will occur since that state change is never fired.
BrowserTestHandler(TestResults &tr,
cef_weburlrequest_state_t cancelAtState = WUR_STATE_UNSENT)
: cancelAtState_(cancelAtState),
test_results_(tr) {
}
virtual void RunTest() OVERRIDE {
std::stringstream testHtml;
testHtml <<
"<html><body>"
"<h1>Testing Web Url Request...</h1>"
"</body></html>";
AddResource("http://tests/run.html", testHtml.str(), "text/html");
CreateBrowser("http://tests/run.html");
}
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) {
StartTest();
}
void TestCompleted() {
DestroyTest();
}
virtual void StartTest() = 0;
cef_weburlrequest_state_t cancelAtState_;
TestResults& test_results_;
};
class TestWebURLRequestClient : public CefWebURLRequestClient {
public:
TestWebURLRequestClient(TestResults& tr, BrowserTestHandler* browser)
: test_results_(tr),
cancelAtState_(WUR_STATE_UNSENT),
browser_(browser) {
}
virtual ~TestWebURLRequestClient() {
test_results_.got_deleted.yes();
}
bool MaybeCancelRequest(CefRefPtr<CefWebURLRequest> requester,
RequestState state) {
if (cancelAtState_ == state) {
#ifdef WEB_URLREQUEST_DEBUG
printf(" Cancelling at state %d\n", cancelAtState_);
#endif
requester->Cancel();
return true;
}
return false;
}
void OnStateChange(CefRefPtr<CefWebURLRequest> requester,
RequestState state) {
#ifdef WEB_URLREQUEST_DEBUG
printf("OnStateChange(0x%p, %d)\n", requester.get(), state);
#endif
if (MaybeCancelRequest(requester, state))
return;
switch (state) {
case WUR_STATE_STARTED:
test_results_.got_started.yes();
break;
case WUR_STATE_HEADERS_RECEIVED:
test_results_.got_headers.yes();
break;
case WUR_STATE_LOADING:
test_results_.got_loading.yes();
break;
case WUR_STATE_DONE:
test_results_.got_done.yes();
if ( contents_.length() ) {
size_t len = contents_.length();
test_results_.contentLength = len;
#ifdef WEB_URLREQUEST_DEBUG
printf("Response: %lu - %s\n", len, contents_.c_str());
#endif
}
TestCompleted();
break;
case WUR_STATE_ABORT:
test_results_.got_abort.yes();
TestCompleted();
break;
default:
break;
}
}
void OnRedirect(CefRefPtr<CefWebURLRequest> requester,
CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response) {
#ifdef WEB_URLREQUEST_DEBUG
printf("OnRedirect(0x%p, 0x%p, 0x%p)\n",
requester.get(), request.get(), response.get());
#endif
test_results_.got_redirect.yes();
++test_results_.redirectCount;
CefString url = request->GetURL();
#ifdef WEB_URLREQUEST_DEBUG
printf("URL = %s\n", url.ToString().c_str());
#endif
}
void OnHeadersReceived(CefRefPtr<CefWebURLRequest> requester,
CefRefPtr<CefResponse> response) {
#ifdef WEB_URLREQUEST_DEBUG
printf("OnHeadersReceived(0x%p, 0x%p)\n", requester.get(), response.get());
#endif
test_results_.statusCode = response->GetStatus();
test_results_.statusText = response->GetStatusText();
test_results_.contentLengthHeader = response->GetHeader("Content-Length");
response->GetHeaderMap(test_results_.headerMap);
}
void OnData(CefRefPtr<CefWebURLRequest> requester, const void *data,
int dataLength) {
#ifdef WEB_URLREQUEST_DEBUG
printf("OnData(0x%p, 0x%p, %d)\n", requester.get(), data, dataLength);
#endif
// Add data to buffer, create if not already
contents_.append(static_cast<const char*>(data), dataLength);
}
void TestCompleted() {
browser_->TestCompleted();
browser_ = NULL;
requester_ = NULL;
Release();
}
void OnProgress(CefRefPtr<CefWebURLRequest> requester,
uint64 bytesSent,
uint64 totalBytesToBeSent) {
#ifdef WEB_URLREQUEST_DEBUG
printf("OnProgress(0x%p, %d, %d)\n", requester.get(),
(unsigned int)bytesSent, (unsigned int)totalBytesToBeSent);
#endif
test_results_.got_progress.yes();
}
void OnError(CefRefPtr<CefWebURLRequest> requester,
CefWebURLRequestClient::ErrorCode errorCode) {
#ifdef WEB_URLREQUEST_DEBUG
printf("Error(0x%p, %d)\n", requester.get(), errorCode);
#endif
test_results_.errorCode = static_cast<int>(errorCode);
test_results_.got_error.yes();
TestCompleted();
}
bool Run(CefRefPtr<CefRequest> req, RequestState
cancelAtState = WUR_STATE_UNSENT) {
if ( requester_.get() )
return false;
cancelAtState_ = cancelAtState;
request_ = req;
// Keep ourselves alive... blanced in TestCompleted() when done.
AddRef();
requester_ = CefWebURLRequest::CreateWebURLRequest(request_, this);
#ifdef WEB_URLREQUEST_DEBUG
printf("Created requester at address 0x%p\n", requester_.get());
#endif
return requester_.get() != NULL;
}
protected:
TestResults& test_results_;
RequestState cancelAtState_;
CefRefPtr<BrowserTestHandler> browser_;
CefRefPtr<CefWebURLRequest> requester_;
CefRefPtr<CefRequest> request_;
std::string contents_;
IMPLEMENT_REFCOUNTING(TestWebURLRequestClient);
};
TEST(WebURLRequestTest, GET) {
class BrowserForTest : public BrowserTestHandler {
public:
explicit BrowserForTest(TestResults &tr) : BrowserTestHandler(tr) { }
void StartTest() {
CefRefPtr<CefRequest> req;
CefRefPtr<CefPostData> postdata;
CefRequest::HeaderMap headers;
req = CefRequest::CreateRequest();
CefString url(
"http://search.twitter.com/search.json?result_type=popular&q=webkit");
CefString method("GET");
req->Set(url, method, postdata, headers);
CefRefPtr<TestWebURLRequestClient> handler =
new TestWebURLRequestClient(test_results_, this);
req->SetFlags((CefRequest::RequestFlags)(
WUR_FLAG_SKIP_CACHE |
WUR_FLAG_REPORT_LOAD_TIMING |
WUR_FLAG_REPORT_RAW_HEADERS |
WUR_FLAG_REPORT_UPLOAD_PROGRESS));
ASSERT_TRUE(handler->Run(req));
}
};
TestResults tr;
CefRefPtr<BrowserTestHandler> browser = new BrowserForTest(tr);
browser->ExecuteTest();
EXPECT_TRUE(tr.got_started);
EXPECT_TRUE(tr.got_headers);
EXPECT_TRUE(tr.got_loading);
EXPECT_TRUE(tr.got_done);
EXPECT_TRUE(tr.got_deleted);
EXPECT_FALSE(tr.got_abort);
EXPECT_FALSE(tr.got_error);
EXPECT_FALSE(tr.got_redirect);
EXPECT_FALSE(tr.got_progress);
EXPECT_GT(tr.contentLength, static_cast<size_t>(0));
EXPECT_EQ(200, tr.statusCode);
}
TEST(WebURLRequestTest, POST) {
class BrowserForTest : public BrowserTestHandler {
public:
explicit BrowserForTest(TestResults &tr) : BrowserTestHandler(tr) { }
void StartTest() {
CefRefPtr<CefRequest> req;
CefRefPtr<CefPostData> postdata;
CefRefPtr<CefPostDataElement> postitem;
CefRequest::HeaderMap headers;
headers.insert(std::make_pair("Content-Type",
"application/x-www-form-urlencoded"));
req = CefRequest::CreateRequest();
CefString url("http://pastebin.com/api_public.php");
CefString method("POST");
postdata = CefPostData::CreatePostData();
postitem = CefPostDataElement::CreatePostDataElement();
static char posttext[] =
"paste_name=CEF%20Test%20Post&paste_code=testing a post call."
"&paste_expire_date=10M";
postitem->SetToBytes(strlen(posttext), posttext);
postdata->AddElement(postitem);
req->Set(url, method, postdata, headers);
CefRefPtr<TestWebURLRequestClient> handler =
new TestWebURLRequestClient(test_results_, this);
req->SetFlags((CefRequest::RequestFlags)(
WUR_FLAG_SKIP_CACHE |
WUR_FLAG_REPORT_LOAD_TIMING |
WUR_FLAG_REPORT_RAW_HEADERS |
WUR_FLAG_REPORT_UPLOAD_PROGRESS));
ASSERT_TRUE(handler->Run(req));
}
};
TestResults tr;
CefRefPtr<BrowserTestHandler> browser = new BrowserForTest(tr);
browser->ExecuteTest();
EXPECT_TRUE(tr.got_started);
EXPECT_TRUE(tr.got_headers);
EXPECT_TRUE(tr.got_loading);
EXPECT_TRUE(tr.got_done);
EXPECT_TRUE(tr.got_deleted);
EXPECT_FALSE(tr.got_redirect);
EXPECT_TRUE(tr.got_progress);
EXPECT_FALSE(tr.got_error);
EXPECT_FALSE(tr.got_abort);
EXPECT_GT(tr.contentLength, static_cast<size_t>(0));
EXPECT_EQ(200, tr.statusCode);
}
TEST(WebURLRequestTest, BADHOST) {
class BrowserForTest : public BrowserTestHandler {
public:
explicit BrowserForTest(TestResults &tr) : BrowserTestHandler(tr) { }
void StartTest() {
CefRefPtr<CefRequest> req;
CefRefPtr<CefPostData> postdata;
CefRefPtr<CefPostDataElement> postitem;
CefRequest::HeaderMap headers;
req = CefRequest::CreateRequest();
CefString url("http://this.host.does.not.exist/not/really/here");
CefString method("GET");
req->Set(url, method, postdata, headers);
CefRefPtr<TestWebURLRequestClient> handler =
new TestWebURLRequestClient(test_results_, this);
req->SetFlags((CefRequest::RequestFlags)(
WUR_FLAG_SKIP_CACHE |
WUR_FLAG_REPORT_LOAD_TIMING |
WUR_FLAG_REPORT_RAW_HEADERS |
WUR_FLAG_REPORT_UPLOAD_PROGRESS));
ASSERT_TRUE(handler->Run(req));
}
};
TestResults tr;
CefRefPtr<BrowserTestHandler> browser = new BrowserForTest(tr);
browser->ExecuteTest();
// NOTE: THIS TEST WILL FAIL IF YOUR ISP REDIRECTS YOU TO
// THEIR SEARCH PAGE ON NXDOMAIN ERRORS.
EXPECT_TRUE(tr.got_started);
EXPECT_FALSE(tr.got_headers);
EXPECT_FALSE(tr.got_loading);
EXPECT_FALSE(tr.got_done);
EXPECT_TRUE(tr.got_deleted);
EXPECT_FALSE(tr.got_redirect);
EXPECT_FALSE(tr.got_progress);
EXPECT_FALSE(tr.got_abort);
EXPECT_TRUE(tr.got_error);
EXPECT_EQ(ERR_NAME_NOT_RESOLVED, tr.errorCode);
EXPECT_EQ(static_cast<size_t>(0), tr.contentLength);
EXPECT_EQ(0, tr.statusCode);
}
#define COUNTOF_(ar) (sizeof(ar)/sizeof(ar[0]))
TEST(WebURLRequestTest, CANCEL) {
class BrowserForTest : public BrowserTestHandler {
public:
BrowserForTest(TestResults &tr, cef_weburlrequest_state_t cancelAtState)
: BrowserTestHandler(tr, cancelAtState) {
}
void StartTest() {
CefRefPtr<CefRequest> req;
CefRefPtr<CefPostData> postdata;
CefRefPtr<CefPostDataElement> postitem;
CefRequest::HeaderMap headers;
req = CefRequest::CreateRequest();
CefString url(
"http://search.twitter.com/search.json?result_type=popular&q=webkit");
CefString method("GET");
req->Set(url, method, postdata, headers);
CefRefPtr<TestWebURLRequestClient> handler =
new TestWebURLRequestClient(test_results_, this);
req->SetFlags((CefRequest::RequestFlags)(
WUR_FLAG_SKIP_CACHE |
WUR_FLAG_REPORT_LOAD_TIMING |
WUR_FLAG_REPORT_RAW_HEADERS |
WUR_FLAG_REPORT_UPLOAD_PROGRESS));
ASSERT_TRUE(handler->Run(req, cancelAtState_));
}
};
cef_weburlrequest_state_t cancelAt[] = {
WUR_STATE_STARTED,
WUR_STATE_HEADERS_RECEIVED
};
for (unsigned int i = 0; i < COUNTOF_(cancelAt); ++i) {
TestResults tr;
CefRefPtr<BrowserTestHandler> browser = new BrowserForTest(tr, cancelAt[i]);
browser->ExecuteTest();
EXPECT_TRUE(tr.got_abort) << "i = " << i;
EXPECT_TRUE(tr.got_deleted);
}
}
// Enable this test if you have installed the php test page.
#if 0
TEST(WebURLRequestTest, REDIRECT) {
/* // PHP Script for a local server to test this:
// You can run a zwamp server on windows to run this.
// http://sourceforge.net/projects/zwamp/
<?php
$max = isset($_GET['max']) ? $_GET['max'] : 2;
$step = isset($_GET['step']) ? $_GET['step'] : 1;
if ($step < $max)
{
$url = $_SERVER['PHP_SELF'];
++$step;
header( $_SERVER["SERVER_PROTOCOL"] . " 301 Permanently moved");
header("Location: $url?max=$max&step=$step", true, 301);
}
else
{
header("Content: text/plain");
echo "Redirect completed after $max times.";
}
?>
*/
class BrowserForTest : public BrowserTestHandler {
public:
explicit BrowserForTest(TestResults &tr) : BrowserTestHandler(tr) { }
void StartTest() {
CefRefPtr<CefRequest> req;
CefRefPtr<CefPostData> postdata;
CefRefPtr<CefPostDataElement> postitem;
CefRequest::HeaderMap headers;
req = CefRequest::CreateRequest();
CefString url("http://localhost/cef/redirect.php?max=4");
CefString method("GET");
req->Set(url, method, postdata, headers);
CefRefPtr<TestWebURLRequestClient> handler =
new TestWebURLRequestClient(test_results_, this);
req->SetFlags((CefRequest::RequestFlags)(
WUR_FLAG_SKIP_CACHE |
WUR_FLAG_REPORT_LOAD_TIMING |
WUR_FLAG_REPORT_RAW_HEADERS |
WUR_FLAG_REPORT_UPLOAD_PROGRESS));
ASSERT_TRUE(handler->Run(req, cancelAtState_));
}
};
TestResults tr;
CefRefPtr<BrowserForTest> browser = new BrowserForTest(tr);
browser->ExecuteTest();
EXPECT_TRUE(tr.got_started);
EXPECT_TRUE(tr.got_headers);
EXPECT_TRUE(tr.got_loading);
EXPECT_TRUE(tr.got_done);
EXPECT_TRUE(tr.got_deleted);
EXPECT_TRUE(tr.got_redirect);
EXPECT_FALSE(tr.got_progress);
EXPECT_FALSE(tr.got_error);
EXPECT_FALSE(tr.got_abort);
EXPECT_GT(tr.contentLength, static_cast<size_t>(0));
EXPECT_EQ(200, tr.statusCode);
EXPECT_EQ(3, tr.redirectCount);
}
#endif // 0