OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome_frame/http_negotiate.h" | 5 #include "chrome_frame/http_negotiate.h" |
6 | 6 |
7 #include <atlbase.h> | 7 #include <atlbase.h> |
8 #include <atlcom.h> | 8 #include <atlcom.h> |
9 #include <htiframe.h> | 9 #include <htiframe.h> |
10 | 10 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
76 STDMETHOD(OnDataAvailable)(DWORD flags, DWORD size, FORMATETC* formatetc, | 76 STDMETHOD(OnDataAvailable)(DWORD flags, DWORD size, FORMATETC* formatetc, |
77 STGMEDIUM* storage) { | 77 STGMEDIUM* storage) { |
78 return E_NOTIMPL; | 78 return E_NOTIMPL; |
79 } | 79 } |
80 STDMETHOD(OnObjectAvailable)(REFIID iid, IUnknown* object) { | 80 STDMETHOD(OnObjectAvailable)(REFIID iid, IUnknown* object) { |
81 return E_NOTIMPL; | 81 return E_NOTIMPL; |
82 } | 82 } |
83 }; | 83 }; |
84 } // end namespace | 84 } // end namespace |
85 | 85 |
86 std::string AppendCFUserAgentString(LPCWSTR headers, | 86 |
87 LPCWSTR additional_headers) { | 87 std::string ExtractUserAgentFromHeaders(LPCWSTR headers, |
grt (UTC plus 2)
2012/03/20 17:27:45
the name of this method doesn't make its behavior
robertshield
2012/03/26 02:43:33
Done.
| |
88 LPCWSTR additional_headers) { | |
88 using net::HttpUtil; | 89 using net::HttpUtil; |
89 | 90 |
90 std::string ascii_headers; | 91 std::string ascii_headers; |
91 if (additional_headers) { | 92 if (additional_headers) { |
92 ascii_headers = WideToASCII(additional_headers); | 93 ascii_headers = WideToASCII(additional_headers); |
93 } | 94 } |
94 | 95 |
95 // Extract "User-Agent" from |additional_headers| or |headers|. | 96 // Extract "User-Agent" from |additional_headers| or |headers|. |
96 HttpUtil::HeadersIterator headers_iterator(ascii_headers.begin(), | 97 HttpUtil::HeadersIterator headers_iterator(ascii_headers.begin(), |
97 ascii_headers.end(), "\r\n"); | 98 ascii_headers.end(), "\r\n"); |
98 std::string user_agent_value; | 99 std::string user_agent_value; |
99 if (headers_iterator.AdvanceTo(kLowerCaseUserAgent)) { | 100 if (headers_iterator.AdvanceTo(kLowerCaseUserAgent)) { |
100 user_agent_value = headers_iterator.values(); | 101 user_agent_value = headers_iterator.values(); |
101 } else if (headers != NULL) { | 102 } else if (headers != NULL) { |
102 // See if there's a user-agent header specified in the original headers. | 103 // See if there's a user-agent header specified in the original headers. |
103 std::string original_headers(WideToASCII(headers)); | 104 std::string original_headers(WideToASCII(headers)); |
104 HttpUtil::HeadersIterator original_it(original_headers.begin(), | 105 HttpUtil::HeadersIterator original_it(original_headers.begin(), |
105 original_headers.end(), "\r\n"); | 106 original_headers.end(), "\r\n"); |
106 if (original_it.AdvanceTo(kLowerCaseUserAgent)) | 107 if (original_it.AdvanceTo(kLowerCaseUserAgent)) |
107 user_agent_value = original_it.values(); | 108 user_agent_value = original_it.values(); |
108 } | 109 } |
109 | 110 |
111 return user_agent_value; | |
112 } | |
113 | |
114 std::string FilterHeaders(const std::string& old_headers, | |
grt (UTC plus 2)
2012/03/20 17:27:45
i find "filter" a bit vague. how about ExcludeFie
robertshield
2012/03/26 02:43:33
Done.
| |
115 const char* exclude) { | |
116 using net::HttpUtil; | |
117 std::string new_headers; | |
118 HttpUtil::HeadersIterator headers_iterator(old_headers.begin(), | |
119 old_headers.end(), "\r\n"); | |
120 while (headers_iterator.GetNext()) { | |
121 std::string name(headers_iterator.name()); | |
122 if (!LowerCaseEqualsASCII(name, exclude)) { | |
123 new_headers += name + ": " + headers_iterator.values() + "\r\n"; | |
grt (UTC plus 2)
2012/03/20 17:27:45
these three uses of operator+ involve lots of temp
robertshield
2012/03/26 02:43:33
Done.
| |
124 } | |
125 } | |
126 | |
127 return new_headers; | |
128 } | |
129 | |
130 std::string AppendCFUserAgentString(LPCWSTR headers, | |
131 LPCWSTR additional_headers) { | |
132 std::string user_agent_value(ExtractUserAgentFromHeaders(headers, | |
133 additional_headers)); | |
134 | |
110 // Use the default "User-Agent" if none was provided. | 135 // Use the default "User-Agent" if none was provided. |
111 if (user_agent_value.empty()) | 136 if (user_agent_value.empty()) |
112 user_agent_value = http_utils::GetDefaultUserAgent(); | 137 user_agent_value = http_utils::GetDefaultUserAgent(); |
113 | 138 |
114 // Now add chromeframe to it. | 139 // Now add chromeframe to it. |
115 user_agent_value = http_utils::AddChromeFrameToUserAgentValue( | 140 user_agent_value = |
116 user_agent_value); | 141 http_utils::AddChromeFrameToUserAgentValue(user_agent_value); |
117 | 142 |
118 // Build new headers, skip the existing user agent value from | 143 // Build a new set of additional headers, skipping the existing user agent |
119 // existing headers. | 144 // value if present. |
120 std::string new_headers; | 145 std::string new_headers; |
121 headers_iterator.Reset(); | 146 if (additional_headers) { |
122 while (headers_iterator.GetNext()) { | 147 std::string ascii_headers = WideToASCII(additional_headers); |
grt (UTC plus 2)
2012/03/20 17:27:45
nit: use () rather than =
robertshield
2012/03/26 02:43:33
Done.
| |
123 std::string name(headers_iterator.name()); | 148 new_headers = FilterHeaders(ascii_headers, kLowerCaseUserAgent); |
124 if (!LowerCaseEqualsASCII(name, kLowerCaseUserAgent)) { | |
125 new_headers += name + ": " + headers_iterator.values() + "\r\n"; | |
126 } | |
127 } | 149 } |
128 | 150 |
129 new_headers += "User-Agent: " + user_agent_value; | 151 new_headers += "User-Agent: " + user_agent_value; |
grt (UTC plus 2)
2012/03/20 17:27:45
i'd advocate for .append or += three times here, t
robertshield
2012/03/26 02:43:33
Done.
| |
130 new_headers += "\r\n"; | 152 new_headers += "\r\n"; |
131 return new_headers; | 153 return new_headers; |
132 } | 154 } |
133 | 155 |
156 // Unconditionally adds the specified |user_agent_value| to the given set of | |
157 // |headers|. | |
134 std::string ReplaceOrAddUserAgent(LPCWSTR headers, | 158 std::string ReplaceOrAddUserAgent(LPCWSTR headers, |
135 const std::string& user_agent_value) { | 159 const std::string& user_agent_value) { |
136 using net::HttpUtil; | |
137 | |
138 std::string new_headers; | 160 std::string new_headers; |
139 if (headers) { | 161 if (headers) { |
140 std::string ascii_headers(WideToASCII(headers)); | 162 std::string ascii_headers(WideToASCII(headers)); |
141 | |
142 // Extract "User-Agent" from the headers. | |
143 HttpUtil::HeadersIterator headers_iterator(ascii_headers.begin(), | |
144 ascii_headers.end(), "\r\n"); | |
145 | |
146 // Build new headers, skip the existing user agent value from | 163 // Build new headers, skip the existing user agent value from |
147 // existing headers. | 164 // existing headers. |
148 while (headers_iterator.GetNext()) { | 165 new_headers = FilterHeaders(ascii_headers, kLowerCaseUserAgent); |
149 std::string name(headers_iterator.name()); | |
150 if (!LowerCaseEqualsASCII(name, kLowerCaseUserAgent)) { | |
151 new_headers += name + ": " + headers_iterator.values() + "\r\n"; | |
152 } | |
153 } | |
154 } | 166 } |
155 new_headers += "User-Agent: " + user_agent_value; | 167 new_headers += "User-Agent: " + user_agent_value; |
grt (UTC plus 2)
2012/03/20 17:27:45
use += instead of +
robertshield
2012/03/26 02:43:33
Done.
| |
156 new_headers += "\r\n"; | 168 new_headers += "\r\n"; |
157 return new_headers; | 169 return new_headers; |
158 } | 170 } |
159 | 171 |
172 // Removes CF from any user agent header found in |headers| or | |
173 // |additional_headers| and | |
grt (UTC plus 2)
2012/03/20 17:27:45
and...?
robertshield
2012/03/26 02:43:33
... and this is where I fell asleep :-)
| |
174 std::string RemoveCFUserAgentString(LPCWSTR headers, | |
175 LPCWSTR additional_headers) { | |
176 std::string user_agent_value(ExtractUserAgentFromHeaders(headers, | |
177 additional_headers)); | |
178 | |
179 // Use the default "User-Agent" if none was provided. | |
180 if (user_agent_value.empty()) | |
181 user_agent_value = http_utils::GetDefaultUserAgent(); | |
182 | |
183 // Now remove chromeframe from it. | |
184 user_agent_value = | |
185 http_utils::RemoveChromeFrameFromUserAgentValue(user_agent_value); | |
186 | |
187 // Build a new set of additional headers, skipping the existing user agent | |
188 // value if present. | |
189 std::string new_headers; | |
190 if (additional_headers) { | |
191 std::string ascii_headers = WideToASCII(additional_headers); | |
192 new_headers = FilterHeaders(ascii_headers, kLowerCaseUserAgent); | |
193 } | |
194 | |
195 new_headers += "User-Agent: " + user_agent_value; | |
grt (UTC plus 2)
2012/03/20 17:27:45
use += rather than +
robertshield
2012/03/26 02:43:33
Done.
| |
196 new_headers += "\r\n"; | |
197 return new_headers; | |
198 } | |
199 | |
160 HttpNegotiatePatch::HttpNegotiatePatch() { | 200 HttpNegotiatePatch::HttpNegotiatePatch() { |
161 } | 201 } |
162 | 202 |
163 HttpNegotiatePatch::~HttpNegotiatePatch() { | 203 HttpNegotiatePatch::~HttpNegotiatePatch() { |
164 } | 204 } |
165 | 205 |
166 // static | 206 // static |
167 bool HttpNegotiatePatch::Initialize() { | 207 bool HttpNegotiatePatch::Initialize() { |
168 if (IS_PATCHED(IHttpNegotiate)) { | 208 if (IS_PATCHED(IHttpNegotiate)) { |
169 DLOG(WARNING) << __FUNCTION__ << " called more than once."; | 209 DLOG(WARNING) << __FUNCTION__ << " called more than once."; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
211 DLOG_IF(ERROR, FAILED(hr)) | 251 DLOG_IF(ERROR, FAILED(hr)) |
212 << base::StringPrintf("HttpNegotiate patch failed 0x%08X", hr); | 252 << base::StringPrintf("HttpNegotiate patch failed 0x%08X", hr); |
213 } else { | 253 } else { |
214 DLOG(WARNING) | 254 DLOG(WARNING) |
215 << base::StringPrintf("IHttpNegotiate not supported 0x%08X", hr); | 255 << base::StringPrintf("IHttpNegotiate not supported 0x%08X", hr); |
216 } | 256 } |
217 return hr; | 257 return hr; |
218 } | 258 } |
219 | 259 |
220 // static | 260 // static |
221 HRESULT HttpNegotiatePatch::BeginningTransaction( | 261 HRESULT HttpNegotiatePatch::BeginningTransaction( |
grt (UTC plus 2)
2012/03/20 17:27:45
is it possible to make a test for the changes of b
robertshield
2012/03/26 02:43:33
It is! Test added.
| |
222 IHttpNegotiate_BeginningTransaction_Fn original, IHttpNegotiate* me, | 262 IHttpNegotiate_BeginningTransaction_Fn original, IHttpNegotiate* me, |
223 LPCWSTR url, LPCWSTR headers, DWORD reserved, LPWSTR* additional_headers) { | 263 LPCWSTR url, LPCWSTR headers, DWORD reserved, LPWSTR* additional_headers) { |
224 DVLOG(1) << __FUNCTION__ << " " << url << " headers:\n" << headers; | 264 DVLOG(1) << __FUNCTION__ << " " << url << " headers:\n" << headers; |
225 | 265 |
226 HRESULT hr = original(me, url, headers, reserved, additional_headers); | 266 HRESULT hr = original(me, url, headers, reserved, additional_headers); |
227 | 267 |
228 if (FAILED(hr)) { | 268 if (FAILED(hr)) { |
229 DLOG(WARNING) << __FUNCTION__ << " Delegate returned an error"; | 269 DLOG(WARNING) << __FUNCTION__ << " Delegate returned an error"; |
230 return hr; | 270 return hr; |
231 } | 271 } |
232 if (modify_user_agent_) { | 272 if (modify_user_agent_) { |
233 std::string updated_headers; | 273 std::string updated_headers; |
274 | |
234 if (IsGcfDefaultRenderer() && | 275 if (IsGcfDefaultRenderer() && |
235 RendererTypeForUrl(url) == RENDERER_TYPE_CHROME_DEFAULT_RENDERER) { | 276 RendererTypeForUrl(url) == RENDERER_TYPE_CHROME_DEFAULT_RENDERER) { |
236 // Replace the user-agent header with Chrome's. | 277 // Replace the user-agent header with Chrome's. |
237 updated_headers = ReplaceOrAddUserAgent(*additional_headers, | 278 updated_headers = ReplaceOrAddUserAgent(*additional_headers, |
238 http_utils::GetChromeUserAgent()); | 279 http_utils::GetChromeUserAgent()); |
280 } else if (ShouldRemoveUAForUrl(url) == USER_AGENT_REMOVE) { | |
281 updated_headers = RemoveCFUserAgentString(headers, *additional_headers); | |
239 } else { | 282 } else { |
240 updated_headers = AppendCFUserAgentString(headers, *additional_headers); | 283 updated_headers = AppendCFUserAgentString(headers, *additional_headers); |
241 } | 284 } |
285 | |
242 *additional_headers = reinterpret_cast<wchar_t*>(::CoTaskMemRealloc( | 286 *additional_headers = reinterpret_cast<wchar_t*>(::CoTaskMemRealloc( |
243 *additional_headers, | 287 *additional_headers, |
244 (updated_headers.length() + 1) * sizeof(wchar_t))); | 288 (updated_headers.length() + 1) * sizeof(wchar_t))); |
245 lstrcpyW(*additional_headers, ASCIIToWide(updated_headers).c_str()); | 289 lstrcpyW(*additional_headers, ASCIIToWide(updated_headers).c_str()); |
grt (UTC plus 2)
2012/03/20 17:27:45
the various UserAgentString functions appear to co
robertshield
2012/03/26 02:43:33
The functions in this file use UA code from \net (
| |
246 } else { | 290 } else { |
247 // TODO(erikwright): Remove the user agent if it is present (i.e., because | 291 // TODO(erikwright): Remove the user agent if it is present (i.e., because |
248 // of PostPlatform setting in the registry). | 292 // of PostPlatform setting in the registry). |
249 } | 293 } |
250 return S_OK; | 294 return S_OK; |
251 } | 295 } |
OLD | NEW |