Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: chrome_frame/http_negotiate.cc

Issue 9720001: Add a setting to CF to remove 'chromeframe' from the UserAgent on a per-pattern basis. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Minor tweak to UA building. Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698