1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "base/basictypes.h"
10 #include "base/path_service.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/win/scoped_handle.h"
13 #include "chrome_frame/test/test_server.h"
14 #include "net/cookies/cookie_monster.h"
15 #include "net/disk_cache/disk_cache.h"
16 #include "net/dns/host_resolver_proc.h"
17 #include "net/http/http_auth_handler_factory.h"
18 #include "net/http/http_cache.h"
19 #include "net/http/http_network_session.h"
20 #include "net/proxy/proxy_service.h"
21 #include "net/url_request/url_request.h"
22 #include "net/url_request/url_request_test_util.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 class TestServerTest
: public testing::Test
{
27 virtual void SetUp() {
28 PathService::Get(base::DIR_SOURCE_ROOT
, &source_path_
);
29 source_path_
= source_path_
.Append(FILE_PATH_LITERAL("chrome_frame"));
31 virtual void TearDown() {
35 const base::FilePath
& source_path() const {
40 base::FilePath source_path_
;
45 class ScopedInternet
{
47 explicit ScopedInternet(HINTERNET handle
)
52 InternetCloseHandle(h_
);
56 operator HINTERNET() {
64 class TestURLRequest
: public net::URLRequest
{
66 TestURLRequest(const GURL
& url
,
68 net::TestURLRequestContext
* context
)
69 : net::URLRequest(url
, delegate
, context
) {
75 UrlTaskChain(const std::string
& url
, UrlTaskChain
* next
)
76 : url_(url
), next_(next
) {
80 EXPECT_EQ(0, delegate_
.response_started_count());
82 base::MessageLoopForIO loop
;
84 net::TestURLRequestContext context
;
85 TestURLRequest
r(GURL(url_
), &delegate_
, &context
);
87 EXPECT_TRUE(r
.is_pending());
89 base::MessageLoop::current()->Run();
91 EXPECT_EQ(1, delegate_
.response_started_count());
92 EXPECT_FALSE(delegate_
.received_data_before_response());
93 EXPECT_NE(0, delegate_
.bytes_received());
96 UrlTaskChain
* next() const {
100 const std::string
& response() const {
101 return delegate_
.data_received();
106 net::TestDelegate delegate_
;
110 DWORD WINAPI
FetchUrl(void* param
) {
111 UrlTaskChain
* task
= reinterpret_cast<UrlTaskChain
*>(param
);
112 while (task
!= NULL
) {
120 struct QuitMessageHit
{
121 explicit QuitMessageHit(base::MessageLoopForUI
* loop
)
122 : loop_(loop
), hit_(false) {}
124 base::MessageLoopForUI
* loop_
;
128 void QuitMessageLoop(QuitMessageHit
* msg
) {
130 msg
->loop_
->PostTask(FROM_HERE
, base::MessageLoop::QuitClosure());
135 TEST_F(TestServerTest
, TestServer
) {
136 // The web server needs a loop to exist on this thread during construction
137 // the loop must be created before we construct the server.
138 base::MessageLoopForUI loop
;
140 test_server::SimpleWebServer
server(1337);
141 test_server::SimpleWebServer
redirected_server(server
.host(), 1338);
142 test_server::SimpleResponse
person("/person", "Guthrie Govan!");
143 server
.AddResponse(&person
);
144 test_server::FileResponse
file("/file", source_path().Append(
145 FILE_PATH_LITERAL("CFInstance.js")));
146 server
.AddResponse(&file
);
147 test_server::RedirectResponse
redir(
149 base::StringPrintf("http://%s:1338/dest",
150 redirected_server
.host().c_str()));
151 server
.AddResponse(&redir
);
153 test_server::SimpleResponse
dest("/dest", "Destination");
154 redirected_server
.AddResponse(&dest
);
156 // We should never hit this, but it's our way to break out of the test if
157 // things start hanging.
158 QuitMessageHit
quit_msg(&loop
);
159 loop
.PostDelayedTask(FROM_HERE
, base::Bind(QuitMessageLoop
, &quit_msg
),
160 base::TimeDelta::FromSeconds(10));
162 UrlTaskChain
quit_task(
163 base::StringPrintf("http://%s:1337/quit", server
.host().c_str()), NULL
);
164 UrlTaskChain
fnf_task(
165 base::StringPrintf("http://%s:1337/404", server
.host().c_str()),
167 UrlTaskChain
person_task(
168 base::StringPrintf("http://%s:1337/person", server
.host().c_str()),
170 UrlTaskChain
file_task(
171 base::StringPrintf("http://%s:1337/file", server
.host().c_str()),
173 UrlTaskChain
redir_task(
174 base::StringPrintf("http://%s:1337/redir", server
.host().c_str()),
178 base::win::ScopedHandle
worker(::CreateThread(
179 NULL
, 0, FetchUrl
, &redir_task
, 0, &tid
));
180 loop
.base::MessageLoop::Run();
182 EXPECT_FALSE(quit_msg
.hit_
);
183 if (!quit_msg
.hit_
) {
184 EXPECT_EQ(::WaitForSingleObject(worker
, 10 * 1000), WAIT_OBJECT_0
);
186 EXPECT_EQ(person
.accessed(), 1);
187 EXPECT_EQ(file
.accessed(), 1);
188 EXPECT_EQ(redir
.accessed(), 1);
190 EXPECT_TRUE(person_task
.response().find("Guthrie") != std::string::npos
);
191 EXPECT_TRUE(file_task
.response().find("function") != std::string::npos
);
192 EXPECT_TRUE(redir_task
.response().find("Destination") != std::string::npos
);
194 ::TerminateThread(worker
, ~0);