| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include <windows.h> | |
| 6 #include <wininet.h> | |
| 7 | |
| 8 #include "base/basictypes.h" | |
| 9 #include "base/bind.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/base/request_priority.h" | |
| 15 #include "net/cookies/cookie_monster.h" | |
| 16 #include "net/disk_cache/disk_cache.h" | |
| 17 #include "net/dns/host_resolver_proc.h" | |
| 18 #include "net/http/http_auth_handler_factory.h" | |
| 19 #include "net/http/http_cache.h" | |
| 20 #include "net/http/http_network_session.h" | |
| 21 #include "net/proxy/proxy_service.h" | |
| 22 #include "net/url_request/url_request.h" | |
| 23 #include "net/url_request/url_request_test_util.h" | |
| 24 #include "testing/gtest/include/gtest/gtest.h" | |
| 25 | |
| 26 class TestServerTest: public testing::Test { | |
| 27 protected: | |
| 28 virtual void SetUp() { | |
| 29 PathService::Get(base::DIR_SOURCE_ROOT, &source_path_); | |
| 30 source_path_ = source_path_.Append(FILE_PATH_LITERAL("chrome_frame")); | |
| 31 } | |
| 32 virtual void TearDown() { | |
| 33 } | |
| 34 | |
| 35 public: | |
| 36 const base::FilePath& source_path() const { | |
| 37 return source_path_; | |
| 38 } | |
| 39 | |
| 40 protected: | |
| 41 base::FilePath source_path_; | |
| 42 }; | |
| 43 | |
| 44 namespace { | |
| 45 | |
| 46 class ScopedInternet { | |
| 47 public: | |
| 48 explicit ScopedInternet(HINTERNET handle) | |
| 49 : h_(handle) { | |
| 50 } | |
| 51 ~ScopedInternet() { | |
| 52 if (h_) { | |
| 53 InternetCloseHandle(h_); | |
| 54 } | |
| 55 } | |
| 56 | |
| 57 operator HINTERNET() { | |
| 58 return h_; | |
| 59 } | |
| 60 | |
| 61 protected: | |
| 62 HINTERNET h_; | |
| 63 }; | |
| 64 | |
| 65 class TestURLRequest : public net::URLRequest { | |
| 66 public: | |
| 67 TestURLRequest(const GURL& url, | |
| 68 net::RequestPriority priority, | |
| 69 Delegate* delegate, | |
| 70 const net::TestURLRequestContext* context) | |
| 71 : net::URLRequest(url, priority, delegate, context) {} | |
| 72 }; | |
| 73 | |
| 74 class UrlTaskChain { | |
| 75 public: | |
| 76 UrlTaskChain(const std::string& url, UrlTaskChain* next) | |
| 77 : url_(url), next_(next) { | |
| 78 } | |
| 79 | |
| 80 void Run() { | |
| 81 EXPECT_EQ(0, delegate_.response_started_count()); | |
| 82 | |
| 83 base::MessageLoopForIO loop; | |
| 84 | |
| 85 net::TestURLRequestContext context; | |
| 86 TestURLRequest r(GURL(url_), net::DEFAULT_PRIORITY, &delegate_, &context); | |
| 87 r.Start(); | |
| 88 EXPECT_TRUE(r.is_pending()); | |
| 89 | |
| 90 base::MessageLoop::current()->Run(); | |
| 91 | |
| 92 EXPECT_EQ(1, delegate_.response_started_count()); | |
| 93 EXPECT_FALSE(delegate_.received_data_before_response()); | |
| 94 EXPECT_NE(0, delegate_.bytes_received()); | |
| 95 } | |
| 96 | |
| 97 UrlTaskChain* next() const { | |
| 98 return next_; | |
| 99 } | |
| 100 | |
| 101 const std::string& response() const { | |
| 102 return delegate_.data_received(); | |
| 103 } | |
| 104 | |
| 105 protected: | |
| 106 std::string url_; | |
| 107 net::TestDelegate delegate_; | |
| 108 UrlTaskChain* next_; | |
| 109 }; | |
| 110 | |
| 111 DWORD WINAPI FetchUrl(void* param) { | |
| 112 UrlTaskChain* task = reinterpret_cast<UrlTaskChain*>(param); | |
| 113 while (task != NULL) { | |
| 114 task->Run(); | |
| 115 task = task->next(); | |
| 116 } | |
| 117 | |
| 118 return 0; | |
| 119 } | |
| 120 | |
| 121 struct QuitMessageHit { | |
| 122 explicit QuitMessageHit(base::MessageLoopForUI* loop) | |
| 123 : loop_(loop), hit_(false) {} | |
| 124 | |
| 125 base::MessageLoopForUI* loop_; | |
| 126 bool hit_; | |
| 127 }; | |
| 128 | |
| 129 void QuitMessageLoop(QuitMessageHit* msg) { | |
| 130 msg->hit_ = true; | |
| 131 msg->loop_->PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); | |
| 132 } | |
| 133 | |
| 134 } // end namespace | |
| 135 | |
| 136 TEST_F(TestServerTest, TestServer) { | |
| 137 // The web server needs a loop to exist on this thread during construction | |
| 138 // the loop must be created before we construct the server. | |
| 139 base::MessageLoopForUI loop; | |
| 140 | |
| 141 test_server::SimpleWebServer server(1337); | |
| 142 test_server::SimpleWebServer redirected_server(server.host(), 1338); | |
| 143 test_server::SimpleResponse person("/person", "Guthrie Govan!"); | |
| 144 server.AddResponse(&person); | |
| 145 test_server::FileResponse file("/file", source_path().Append( | |
| 146 FILE_PATH_LITERAL("CFInstance.js"))); | |
| 147 server.AddResponse(&file); | |
| 148 test_server::RedirectResponse redir( | |
| 149 "/redir", | |
| 150 base::StringPrintf("http://%s:1338/dest", | |
| 151 redirected_server.host().c_str())); | |
| 152 server.AddResponse(&redir); | |
| 153 | |
| 154 test_server::SimpleResponse dest("/dest", "Destination"); | |
| 155 redirected_server.AddResponse(&dest); | |
| 156 | |
| 157 // We should never hit this, but it's our way to break out of the test if | |
| 158 // things start hanging. | |
| 159 QuitMessageHit quit_msg(&loop); | |
| 160 loop.PostDelayedTask(FROM_HERE, base::Bind(QuitMessageLoop, &quit_msg), | |
| 161 base::TimeDelta::FromSeconds(10)); | |
| 162 | |
| 163 UrlTaskChain quit_task( | |
| 164 base::StringPrintf("http://%s:1337/quit", server.host().c_str()), NULL); | |
| 165 UrlTaskChain fnf_task( | |
| 166 base::StringPrintf("http://%s:1337/404", server.host().c_str()), | |
| 167 &quit_task); | |
| 168 UrlTaskChain person_task( | |
| 169 base::StringPrintf("http://%s:1337/person", server.host().c_str()), | |
| 170 &fnf_task); | |
| 171 UrlTaskChain file_task( | |
| 172 base::StringPrintf("http://%s:1337/file", server.host().c_str()), | |
| 173 &person_task); | |
| 174 UrlTaskChain redir_task( | |
| 175 base::StringPrintf("http://%s:1337/redir", server.host().c_str()), | |
| 176 &file_task); | |
| 177 | |
| 178 DWORD tid = 0; | |
| 179 base::win::ScopedHandle worker(::CreateThread( | |
| 180 NULL, 0, FetchUrl, &redir_task, 0, &tid)); | |
| 181 loop.base::MessageLoop::Run(); | |
| 182 | |
| 183 EXPECT_FALSE(quit_msg.hit_); | |
| 184 if (!quit_msg.hit_) { | |
| 185 EXPECT_EQ(::WaitForSingleObject(worker, 10 * 1000), WAIT_OBJECT_0); | |
| 186 | |
| 187 EXPECT_EQ(person.accessed(), 1); | |
| 188 EXPECT_EQ(file.accessed(), 1); | |
| 189 EXPECT_EQ(redir.accessed(), 1); | |
| 190 | |
| 191 EXPECT_TRUE(person_task.response().find("Guthrie") != std::string::npos); | |
| 192 EXPECT_TRUE(file_task.response().find("function") != std::string::npos); | |
| 193 EXPECT_TRUE(redir_task.response().find("Destination") != std::string::npos); | |
| 194 } else { | |
| 195 ::TerminateThread(worker, ~0); | |
| 196 } | |
| 197 } | |
| OLD | NEW |