524 lines
14 KiB
C++
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
|