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

Side by Side Diff: chrome_frame/http_negotiate.cc

Issue 259025: Add the chromeframe tag to the user agent header at runtime instead of static... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 2 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/http_negotiate.h ('k') | chrome_frame/protocol_sink_wrap.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome_frame/http_negotiate.h"
6
7 #include <atlbase.h>
8 #include <atlcom.h>
9
10 #include "base/logging.h"
11 #include "base/scoped_ptr.h"
12 #include "base/string_util.h"
13
14 #include "chrome_frame/html_utils.h"
15 #include "chrome_frame/urlmon_url_request.h"
16 #include "chrome_frame/utils.h"
17 #include "chrome_frame/vtable_patch_manager.h"
18
19 static const int kHttpNegotiateBeginningTransactionIndex = 3;
20 static const int kHttpNegotiateOnResponseTransactionIndex = 4;
21
22 BEGIN_VTABLE_PATCHES(IHttpNegotiate)
23 VTABLE_PATCH_ENTRY(kHttpNegotiateBeginningTransactionIndex,
24 HttpNegotiatePatch::BeginningTransaction)
25 VTABLE_PATCH_ENTRY(kHttpNegotiateOnResponseTransactionIndex,
26 HttpNegotiatePatch::OnResponse)
27 END_VTABLE_PATCHES()
28
29 HttpNegotiatePatch::HttpNegotiatePatch() {
30 }
31
32 HttpNegotiatePatch::~HttpNegotiatePatch() {
33 }
34
35 // static
36 bool HttpNegotiatePatch::Initialize() {
37 if (IS_PATCHED(IHttpNegotiate)) {
38 DLOG(WARNING) << __FUNCTION__ << " called more than once.";
39 return true;
40 }
41
42 // Use our UrlmonUrlRequest class as we need a temporary object that
43 // implements IBindStatusCallback.
44 CComObjectStackEx<UrlmonUrlRequest> request;
45 ScopedComPtr<IBindCtx> bind_ctx;
46 HRESULT hr = CreateAsyncBindCtx(0, &request, NULL, bind_ctx.Receive());
47 DCHECK(SUCCEEDED(hr)) << "CreateAsyncBindCtx";
48 if (bind_ctx) {
49 ScopedComPtr<IUnknown> bscb_holder;
50 bind_ctx->GetObjectParam(L"_BSCB_Holder_", bscb_holder.Receive());
51 if (bscb_holder) {
52 hr = PatchHttpNegotiate(bscb_holder);
53 } else {
54 NOTREACHED() << "Failed to get _BSCB_Holder_";
55 hr = E_UNEXPECTED;
56 }
57 bind_ctx.Release();
58 }
59
60 return SUCCEEDED(hr);
61 }
62
63 // static
64 void HttpNegotiatePatch::Uninitialize() {
65 vtable_patch::UnpatchInterfaceMethods(IHttpNegotiate_PatchInfo);
66 }
67
68 // static
69 HRESULT HttpNegotiatePatch::PatchHttpNegotiate(IUnknown* to_patch) {
70 DCHECK(to_patch);
71 DCHECK_IS_NOT_PATCHED(IHttpNegotiate);
72
73 ScopedComPtr<IHttpNegotiate> http;
74 HRESULT hr = http.QueryFrom(to_patch);
75 if (FAILED(hr)) {
76 hr = DoQueryService(IID_IHttpNegotiate, to_patch, http.Receive());
77 }
78
79 if (http) {
80 hr = vtable_patch::PatchInterfaceMethods(http, IHttpNegotiate_PatchInfo);
81 DLOG_IF(ERROR, FAILED(hr))
82 << StringPrintf("HttpNegotiate patch failed 0x%08X", hr);
83 } else {
84 DLOG(WARNING)
85 << StringPrintf("IHttpNegotiate not supported 0x%08X", hr);
86 }
87
88 return hr;
89 }
90
91 // static
92 HRESULT HttpNegotiatePatch::BeginningTransaction(
93 IHttpNegotiate_BeginningTransaction_Fn original, IHttpNegotiate* me,
94 LPCWSTR url, LPCWSTR headers, DWORD reserved, LPWSTR* additional_headers) {
95 DLOG(INFO) << __FUNCTION__ << " " << url;
96
97 HRESULT hr = original(me, url, headers, reserved, additional_headers);
98
99 if (FAILED(hr)) {
100 DLOG(WARNING) << __FUNCTION__ << " Delegate returned an error";
101 return hr;
102 }
103
104 static const char kLowerCaseUserAgent[] = "user-agent";
105
106 using net::HttpUtil;
107
108 std::string ascii_headers;
109 if (*additional_headers)
110 ascii_headers = WideToASCII(*additional_headers);
111
112 HttpUtil::HeadersIterator headers_iterator(ascii_headers.begin(),
113 ascii_headers.end(), "\r\n");
114 std::string user_agent_value;
115 if (headers_iterator.AdvanceTo(kLowerCaseUserAgent)) {
116 user_agent_value = headers_iterator.values();
117 } else if (headers != NULL) {
118 // See if there's a user-agent header specified in the original headers.
119 std::string original_headers(WideToASCII(headers));
120 HttpUtil::HeadersIterator original_it(original_headers.begin(),
121 original_headers.end(), "\r\n");
122 if (original_it.AdvanceTo(kLowerCaseUserAgent))
123 user_agent_value = original_it.values();
124 }
125
126 // Use the default one if none was provided.
127 if (user_agent_value.empty())
128 user_agent_value = http_utils::GetDefaultUserAgent();
129
130 // Now add chromeframe to it.
131 user_agent_value = http_utils::AddChromeFrameToUserAgentValue(
132 user_agent_value);
133
134 // Build new headers, skip the existing user agent value from
135 // existing headers.
136 std::string new_headers;
137 headers_iterator.Reset();
138 while (headers_iterator.GetNext()) {
139 std::string name(headers_iterator.name());
140 if (!LowerCaseEqualsASCII(name, kLowerCaseUserAgent)) {
141 new_headers += name + ": " + headers_iterator.values() + "\r\n";
142 }
143 }
144
145 new_headers += "User-Agent: " + user_agent_value;
146 new_headers += "\r\n\r\n";
147
148 if (*additional_headers)
149 ::CoTaskMemFree(*additional_headers);
150 *additional_headers = reinterpret_cast<wchar_t*>(::CoTaskMemAlloc(
151 (new_headers.length() + 1) * sizeof(wchar_t)));
152 lstrcpyW(*additional_headers, ASCIIToWide(new_headers).c_str());
153
154 return hr;
155 }
156
157 // static
158 HRESULT HttpNegotiatePatch::OnResponse(IHttpNegotiate_OnResponse_Fn original,
159 IHttpNegotiate* me, DWORD response_code, LPCWSTR response_header,
160 LPCWSTR request_header, LPWSTR* additional_request_headers) {
161 HRESULT hr = original(me, response_code, response_header, request_header,
162 additional_request_headers);
163 return hr;
164 }
OLDNEW
« no previous file with comments | « chrome_frame/http_negotiate.h ('k') | chrome_frame/protocol_sink_wrap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698