Chromium Code Reviews| 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 |