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 |