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

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: In the end. Created 8 years, 8 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
« no previous file with comments | « chrome_frame/html_utils.cc ('k') | chrome_frame/registry_list_preferences_holder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 } 74 }
75 75
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
85 84
86 std::string AppendCFUserAgentString(LPCWSTR headers, 85 // Returns the full user agent header from the HTTP header strings passed to
86 // IHttpNegotiate::BeginningTransaction. Looks first in |additional_headers|
87 // and if it can't be found there looks in |headers|.
88 std::string GetUserAgentFromHeaders(LPCWSTR headers,
87 LPCWSTR additional_headers) { 89 LPCWSTR additional_headers) {
88 using net::HttpUtil; 90 using net::HttpUtil;
89 91
90 std::string ascii_headers; 92 std::string ascii_headers;
91 if (additional_headers) { 93 if (additional_headers) {
92 ascii_headers = WideToASCII(additional_headers); 94 ascii_headers = WideToASCII(additional_headers);
93 } 95 }
94 96
95 // Extract "User-Agent" from |additional_headers| or |headers|. 97 // Extract "User-Agent" from |additional_headers| or |headers|.
96 HttpUtil::HeadersIterator headers_iterator(ascii_headers.begin(), 98 HttpUtil::HeadersIterator headers_iterator(ascii_headers.begin(),
97 ascii_headers.end(), "\r\n"); 99 ascii_headers.end(), "\r\n");
98 std::string user_agent_value; 100 std::string user_agent_value;
99 if (headers_iterator.AdvanceTo(kLowerCaseUserAgent)) { 101 if (headers_iterator.AdvanceTo(kLowerCaseUserAgent)) {
100 user_agent_value = headers_iterator.values(); 102 user_agent_value = headers_iterator.values();
101 } else if (headers != NULL) { 103 } else if (headers != NULL) {
102 // See if there's a user-agent header specified in the original headers. 104 // See if there's a user-agent header specified in the original headers.
103 std::string original_headers(WideToASCII(headers)); 105 std::string original_headers(WideToASCII(headers));
104 HttpUtil::HeadersIterator original_it(original_headers.begin(), 106 HttpUtil::HeadersIterator original_it(original_headers.begin(),
105 original_headers.end(), "\r\n"); 107 original_headers.end(), "\r\n");
106 if (original_it.AdvanceTo(kLowerCaseUserAgent)) 108 if (original_it.AdvanceTo(kLowerCaseUserAgent))
107 user_agent_value = original_it.values(); 109 user_agent_value = original_it.values();
108 } 110 }
109 111
112 return user_agent_value;
113 }
114
115 // Removes the named header |field| from a set of headers. |field| must be
116 // lower-case.
117 std::string ExcludeFieldFromHeaders(const std::string& old_headers,
118 const char* field) {
119 using net::HttpUtil;
120 std::string new_headers;
121 new_headers.reserve(old_headers.size());
122 HttpUtil::HeadersIterator headers_iterator(old_headers.begin(),
123 old_headers.end(), "\r\n");
124 while (headers_iterator.GetNext()) {
125 if (!LowerCaseEqualsASCII(headers_iterator.name_begin(),
126 headers_iterator.name_end(),
127 field)) {
128 new_headers.append(headers_iterator.name_begin(),
129 headers_iterator.name_end());
130 new_headers += ": ";
131 new_headers.append(headers_iterator.values_begin(),
132 headers_iterator.values_end());
133 new_headers += "\r\n";
134 }
135 }
136
137 return new_headers;
138 }
139
140 std::string MutateCFUserAgentString(LPCWSTR headers,
141 LPCWSTR additional_headers,
142 bool add_user_agent) {
143 std::string user_agent_value(GetUserAgentFromHeaders(headers,
144 additional_headers));
145
110 // Use the default "User-Agent" if none was provided. 146 // Use the default "User-Agent" if none was provided.
111 if (user_agent_value.empty()) 147 if (user_agent_value.empty())
112 user_agent_value = http_utils::GetDefaultUserAgent(); 148 user_agent_value = http_utils::GetDefaultUserAgent();
113 149
114 // Now add chromeframe to it. 150 // Now add chromeframe to it.
115 user_agent_value = http_utils::AddChromeFrameToUserAgentValue( 151 user_agent_value = add_user_agent ?
116 user_agent_value); 152 http_utils::AddChromeFrameToUserAgentValue(user_agent_value) :
153 http_utils::RemoveChromeFrameFromUserAgentValue(user_agent_value);
117 154
118 // Build new headers, skip the existing user agent value from 155 // Build a new set of additional headers, skipping the existing user agent
119 // existing headers. 156 // value if present.
157 return ReplaceOrAddUserAgent(additional_headers, user_agent_value);
158 }
159
160 } // end namespace
161
162
163 std::string AppendCFUserAgentString(LPCWSTR headers,
164 LPCWSTR additional_headers) {
165 return MutateCFUserAgentString(headers, additional_headers, true);
166 }
167
168
169 // Looks for a user agent header found in |headers| or |additional_headers|
170 // then returns |additional_headers| with a modified user agent header that does
171 // not include the chromeframe token.
172 std::string RemoveCFUserAgentString(LPCWSTR headers,
173 LPCWSTR additional_headers) {
174 return MutateCFUserAgentString(headers, additional_headers, false);
175 }
176
177
178 // Unconditionally adds the specified |user_agent_value| to the given set of
179 // |headers|, removing any that were already there.
180 std::string ReplaceOrAddUserAgent(LPCWSTR headers,
181 const std::string& user_agent_value) {
120 std::string new_headers; 182 std::string new_headers;
121 headers_iterator.Reset(); 183 if (headers) {
122 while (headers_iterator.GetNext()) { 184 std::string ascii_headers(WideToASCII(headers));
123 std::string name(headers_iterator.name()); 185 // Build new headers, skip the existing user agent value from
124 if (!LowerCaseEqualsASCII(name, kLowerCaseUserAgent)) { 186 // existing headers.
125 new_headers += name + ": " + headers_iterator.values() + "\r\n"; 187 new_headers = ExcludeFieldFromHeaders(ascii_headers, kLowerCaseUserAgent);
126 }
127 } 188 }
128 189 new_headers += "User-Agent: ";
129 new_headers += "User-Agent: " + user_agent_value; 190 new_headers += user_agent_value;
130 new_headers += "\r\n"; 191 new_headers += "\r\n";
131 return new_headers; 192 return new_headers;
132 } 193 }
133
134 std::string ReplaceOrAddUserAgent(LPCWSTR headers,
135 const std::string& user_agent_value) {
136 using net::HttpUtil;
137
138 std::string new_headers;
139 if (headers) {
140 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
147 // existing headers.
148 while (headers_iterator.GetNext()) {
149 std::string name(headers_iterator.name());
150 if (!LowerCaseEqualsASCII(name, kLowerCaseUserAgent)) {
151 new_headers += name + ": " + headers_iterator.values() + "\r\n";
152 }
153 }
154 }
155 new_headers += "User-Agent: " + user_agent_value;
156 new_headers += "\r\n";
157 return new_headers;
158 }
159 194
160 HttpNegotiatePatch::HttpNegotiatePatch() { 195 HttpNegotiatePatch::HttpNegotiatePatch() {
161 } 196 }
162 197
163 HttpNegotiatePatch::~HttpNegotiatePatch() { 198 HttpNegotiatePatch::~HttpNegotiatePatch() {
164 } 199 }
165 200
166 // static 201 // static
167 bool HttpNegotiatePatch::Initialize() { 202 bool HttpNegotiatePatch::Initialize() {
168 if (IS_PATCHED(IHttpNegotiate)) { 203 if (IS_PATCHED(IHttpNegotiate)) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 DVLOG(1) << __FUNCTION__ << " " << url << " headers:\n" << headers; 259 DVLOG(1) << __FUNCTION__ << " " << url << " headers:\n" << headers;
225 260
226 HRESULT hr = original(me, url, headers, reserved, additional_headers); 261 HRESULT hr = original(me, url, headers, reserved, additional_headers);
227 262
228 if (FAILED(hr)) { 263 if (FAILED(hr)) {
229 DLOG(WARNING) << __FUNCTION__ << " Delegate returned an error"; 264 DLOG(WARNING) << __FUNCTION__ << " Delegate returned an error";
230 return hr; 265 return hr;
231 } 266 }
232 if (modify_user_agent_) { 267 if (modify_user_agent_) {
233 std::string updated_headers; 268 std::string updated_headers;
269
234 if (IsGcfDefaultRenderer() && 270 if (IsGcfDefaultRenderer() &&
235 RendererTypeForUrl(url) == RENDERER_TYPE_CHROME_DEFAULT_RENDERER) { 271 RendererTypeForUrl(url) == RENDERER_TYPE_CHROME_DEFAULT_RENDERER) {
236 // Replace the user-agent header with Chrome's. 272 // Replace the user-agent header with Chrome's.
237 updated_headers = ReplaceOrAddUserAgent(*additional_headers, 273 updated_headers = ReplaceOrAddUserAgent(*additional_headers,
238 http_utils::GetChromeUserAgent()); 274 http_utils::GetChromeUserAgent());
275 } else if (ShouldRemoveUAForUrl(url)) {
276 updated_headers = RemoveCFUserAgentString(headers, *additional_headers);
239 } else { 277 } else {
240 updated_headers = AppendCFUserAgentString(headers, *additional_headers); 278 updated_headers = AppendCFUserAgentString(headers, *additional_headers);
241 } 279 }
280
242 *additional_headers = reinterpret_cast<wchar_t*>(::CoTaskMemRealloc( 281 *additional_headers = reinterpret_cast<wchar_t*>(::CoTaskMemRealloc(
243 *additional_headers, 282 *additional_headers,
244 (updated_headers.length() + 1) * sizeof(wchar_t))); 283 (updated_headers.length() + 1) * sizeof(wchar_t)));
245 lstrcpyW(*additional_headers, ASCIIToWide(updated_headers).c_str()); 284 lstrcpyW(*additional_headers, ASCIIToWide(updated_headers).c_str());
246 } else { 285 } else {
247 // TODO(erikwright): Remove the user agent if it is present (i.e., because 286 // TODO(erikwright): Remove the user agent if it is present (i.e., because
248 // of PostPlatform setting in the registry). 287 // of PostPlatform setting in the registry).
249 } 288 }
250 return S_OK; 289 return S_OK;
251 } 290 }
OLDNEW
« no previous file with comments | « chrome_frame/html_utils.cc ('k') | chrome_frame/registry_list_preferences_holder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698