| OLD | NEW |
| (Empty) |
| 1 // Copyright 2007-2009 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 | |
| 16 // Since the net code is linked in as a lib, force the registration code to | |
| 17 // be a dependency, otherwise the linker is optimizing in out. | |
| 18 #pragma comment(linker, "/INCLUDE:_kRegisterWinHttp") | |
| 19 | |
| 20 #include <vector> | |
| 21 #include "base/basictypes.h" | |
| 22 #include "base/scoped_ptr.h" | |
| 23 #include "omaha/base/omaha_version.h" | |
| 24 #include "omaha/net/http_client.h" | |
| 25 #include "omaha/testing/unit_test.h" | |
| 26 | |
| 27 namespace omaha { | |
| 28 | |
| 29 // Test fixture, perhaps we need it later. | |
| 30 class HttpClientTest : public testing::Test { | |
| 31 protected: | |
| 32 HttpClientTest() {} | |
| 33 | |
| 34 static void SetUpTestCase() {} | |
| 35 | |
| 36 virtual void SetUp() { | |
| 37 http_client_.reset( | |
| 38 HttpClient::GetFactory().CreateObject(HttpClient::WINHTTP)); | |
| 39 ASSERT_TRUE(http_client_.get()); | |
| 40 ASSERT_SUCCEEDED(http_client_->Initialize()); | |
| 41 } | |
| 42 | |
| 43 virtual void TearDown() { | |
| 44 http_client_.reset(); | |
| 45 } | |
| 46 | |
| 47 void GetUrl(const TCHAR* url, bool use_proxy); | |
| 48 | |
| 49 scoped_ptr<HttpClient> http_client_; | |
| 50 }; | |
| 51 | |
| 52 CString BuildUserAgent() { | |
| 53 CString user_agent; | |
| 54 user_agent.Format(_T("HttpClientTest version %s"), omaha::GetVersionString()); | |
| 55 return user_agent; | |
| 56 } | |
| 57 | |
| 58 const TCHAR kTestUrlGet[] = _T("http://www.google.com/robots.txt"); | |
| 59 const TCHAR kTestSecureUrlGet[] = _T("https://www.google.com/robots.txt"); | |
| 60 | |
| 61 // If using a proxy is specified, the function does WPAD detection to get the | |
| 62 // name of the proxy to be used. The request goes direct if the WPAD fails. | |
| 63 void HttpClientTest::GetUrl(const TCHAR* url, bool use_proxy) { | |
| 64 ASSERT_TRUE(url); | |
| 65 | |
| 66 CString server, path; | |
| 67 int port = 0; | |
| 68 ASSERT_SUCCEEDED(http_client_->CrackUrl(url, | |
| 69 ICU_DECODE, | |
| 70 NULL, | |
| 71 &server, | |
| 72 &port, | |
| 73 &path, | |
| 74 NULL)); | |
| 75 ASSERT_STREQ(server, _T("www.google.com")); | |
| 76 ASSERT_STREQ(path, _T("/robots.txt")); | |
| 77 | |
| 78 HINTERNET session_handle = NULL; | |
| 79 ASSERT_SUCCEEDED(http_client_->Open(BuildUserAgent(), | |
| 80 HttpClient::kAccessTypeNoProxy, | |
| 81 NULL, | |
| 82 NULL, | |
| 83 0, // Synchronous mode. | |
| 84 &session_handle)); | |
| 85 if (use_proxy) { | |
| 86 HttpClient::AutoProxyOptions autoproxy_options = {0}; | |
| 87 autoproxy_options.flags = WINHTTP_AUTOPROXY_AUTO_DETECT; | |
| 88 autoproxy_options.auto_detect_flags = WINHTTP_AUTO_DETECT_TYPE_DHCP | | |
| 89 WINHTTP_AUTO_DETECT_TYPE_DNS_A; | |
| 90 autoproxy_options.auto_logon_if_challenged = true; | |
| 91 HttpClient::ProxyInfo proxy_info = {0}; | |
| 92 http_client_->GetProxyForUrl(session_handle, | |
| 93 url, | |
| 94 &autoproxy_options, | |
| 95 &proxy_info); | |
| 96 if (proxy_info.proxy && wcslen(proxy_info.proxy)) { | |
| 97 proxy_info.access_type = WINHTTP_ACCESS_TYPE_NAMED_PROXY; | |
| 98 EXPECT_SUCCEEDED(http_client_->SetOption(session_handle, | |
| 99 WINHTTP_OPTION_PROXY, | |
| 100 &proxy_info, | |
| 101 sizeof(proxy_info))); | |
| 102 } | |
| 103 ::GlobalFree(const_cast<wchar_t*>(proxy_info.proxy)); | |
| 104 ::GlobalFree(const_cast<wchar_t*>(proxy_info.proxy_bypass)); | |
| 105 } | |
| 106 | |
| 107 HINTERNET connection_handle = NULL; | |
| 108 ASSERT_SUCCEEDED(http_client_->Connect(session_handle, | |
| 109 server, | |
| 110 port, | |
| 111 &connection_handle)); | |
| 112 uint32 flags = port == 443 ? WINHTTP_FLAG_SECURE : 0; | |
| 113 HINTERNET request_handle = NULL; | |
| 114 ASSERT_SUCCEEDED(http_client_->OpenRequest(connection_handle, | |
| 115 _T("GET"), | |
| 116 path, | |
| 117 NULL, // HTTP 1.1 | |
| 118 NULL, // Referrer. | |
| 119 NULL, // Default accept types. | |
| 120 flags, | |
| 121 &request_handle)); | |
| 122 ASSERT_SUCCEEDED(http_client_->SendRequest(request_handle, | |
| 123 NULL, 0, NULL, 0, 0, 0)); | |
| 124 ASSERT_SUCCEEDED(http_client_->ReceiveResponse(request_handle)); | |
| 125 CString content_type; | |
| 126 EXPECT_SUCCEEDED(http_client_->QueryHeadersString(request_handle, | |
| 127 WINHTTP_QUERY_CONTENT_TYPE, | |
| 128 NULL, | |
| 129 &content_type, | |
| 130 NULL)); | |
| 131 EXPECT_STREQ(content_type, _T("text/plain")); | |
| 132 CString server_header; | |
| 133 EXPECT_SUCCEEDED(http_client_->QueryHeadersString(request_handle, | |
| 134 WINHTTP_QUERY_SERVER, | |
| 135 NULL, | |
| 136 &server_header, | |
| 137 NULL)); | |
| 138 CString response; | |
| 139 DWORD size = 0; | |
| 140 do { | |
| 141 // Use ReadData to determine when a response has been completely read. | |
| 142 // Always allocate a buffer for ReadData even though QueryDataAvailable | |
| 143 // might return 0 bytes available. | |
| 144 ASSERT_SUCCEEDED(http_client_->QueryDataAvailable(request_handle, &size)); | |
| 145 std::vector<uint8> buf(size + 1); | |
| 146 ASSERT_SUCCEEDED(http_client_->ReadData(request_handle, | |
| 147 &buf.front(), | |
| 148 buf.size(), | |
| 149 &size)); | |
| 150 buf.resize(size); | |
| 151 if (size) { | |
| 152 response += CString(reinterpret_cast<char*>(&buf.front()), buf.size()); | |
| 153 } | |
| 154 } while (size > 0); | |
| 155 | |
| 156 // Compare a little bit of the body. | |
| 157 response.Truncate(10); | |
| 158 ASSERT_STREQ(response, _T("User-agent")); | |
| 159 | |
| 160 ASSERT_SUCCEEDED(http_client_->Close(request_handle)); | |
| 161 ASSERT_SUCCEEDED(http_client_->Close(connection_handle)); | |
| 162 ASSERT_SUCCEEDED(http_client_->Close(session_handle)); | |
| 163 } | |
| 164 | |
| 165 TEST_F(HttpClientTest, Get) { | |
| 166 if (IsTestRunByLocalSystem()) { | |
| 167 return; | |
| 168 } | |
| 169 | |
| 170 GetUrl(kTestUrlGet, false); | |
| 171 } | |
| 172 | |
| 173 TEST_F(HttpClientTest, SecureGet) { | |
| 174 if (IsTestRunByLocalSystem()) { | |
| 175 return; | |
| 176 } | |
| 177 | |
| 178 GetUrl(kTestSecureUrlGet, false); | |
| 179 } | |
| 180 | |
| 181 TEST_F(HttpClientTest, ProxyGet) { | |
| 182 GetUrl(kTestUrlGet, true); | |
| 183 } | |
| 184 | |
| 185 TEST_F(HttpClientTest, ProxySecureGet) { | |
| 186 GetUrl(kTestSecureUrlGet, true); | |
| 187 } | |
| 188 | |
| 189 TEST_F(HttpClientTest, BuildRequestHeader) { | |
| 190 ASSERT_STREQ(HttpClient::BuildRequestHeader(_T("foo"), _T("bar")), | |
| 191 _T("foo: bar\r\n")); | |
| 192 } | |
| 193 | |
| 194 TEST_F(HttpClientTest, GetStatusCodeClass) { | |
| 195 EXPECT_EQ(HttpClient::GetStatusCodeClass(HTTP_STATUS_CONTINUE), | |
| 196 HttpClient::STATUS_CODE_INFORMATIONAL); | |
| 197 | |
| 198 EXPECT_EQ(HttpClient::GetStatusCodeClass(HTTP_STATUS_OK), | |
| 199 HttpClient::STATUS_CODE_SUCCESSFUL); | |
| 200 | |
| 201 EXPECT_EQ(HttpClient::GetStatusCodeClass(HTTP_STATUS_PARTIAL_CONTENT), | |
| 202 HttpClient::STATUS_CODE_SUCCESSFUL); | |
| 203 | |
| 204 EXPECT_EQ(HttpClient::GetStatusCodeClass(HTTP_STATUS_AMBIGUOUS), | |
| 205 HttpClient::STATUS_CODE_REDIRECTION); | |
| 206 | |
| 207 EXPECT_EQ(HttpClient::GetStatusCodeClass(HTTP_STATUS_REDIRECT), | |
| 208 HttpClient::STATUS_CODE_REDIRECTION); | |
| 209 | |
| 210 EXPECT_EQ(HttpClient::GetStatusCodeClass(HTTP_STATUS_BAD_REQUEST), | |
| 211 HttpClient::STATUS_CODE_CLIENT_ERROR); | |
| 212 | |
| 213 EXPECT_EQ(HttpClient::GetStatusCodeClass(HTTP_STATUS_SERVICE_UNAVAIL), | |
| 214 HttpClient::STATUS_CODE_SERVER_ERROR); | |
| 215 } | |
| 216 | |
| 217 TEST_F(HttpClientTest, CrackUrl) { | |
| 218 CString scheme, server, path, query; | |
| 219 int port = 0; | |
| 220 ASSERT_SUCCEEDED(http_client_->CrackUrl(_T("http://host/path?query"), | |
| 221 0, | |
| 222 &scheme, | |
| 223 &server, | |
| 224 &port, | |
| 225 &path, | |
| 226 &query)); | |
| 227 ASSERT_STREQ(scheme, _T("http")); | |
| 228 ASSERT_STREQ(server, _T("host")); | |
| 229 ASSERT_EQ(port, INTERNET_DEFAULT_HTTP_PORT); | |
| 230 ASSERT_STREQ(path, _T("/path")); | |
| 231 ASSERT_STREQ(query, _T("?query")); | |
| 232 | |
| 233 ASSERT_SUCCEEDED(http_client_->CrackUrl(_T("http://host"), | |
| 234 0, | |
| 235 NULL, | |
| 236 NULL, | |
| 237 NULL, | |
| 238 &path, | |
| 239 &query)); | |
| 240 ASSERT_STREQ(path, _T("")); | |
| 241 ASSERT_STREQ(query, _T("")); | |
| 242 } | |
| 243 | |
| 244 } // namespace omaha | |
| 245 | |
| OLD | NEW |