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

Side by Side Diff: chrome/common/net/url_request_intercept_job.cc

Issue 6576020: Remove Gears from Chrome (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: ready to review Created 9 years, 10 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
(Empty)
1 // Copyright (c) 2011 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 // This job type handles Chrome plugin network interception. When a plugin
6 // wants to intercept a request, a job of this type is created. The intercept
7 // job communicates with the plugin to retrieve the response headers and data.
8
9 #include "chrome/common/net/url_request_intercept_job.h"
10
11 #include <vector>
12
13 #include "base/compiler_specific.h"
14 #include "base/message_loop.h"
15 #include "base/string_util.h"
16 #include "chrome/common/chrome_plugin_lib.h"
17 #include "chrome/common/notification_source.h"
18 #include "net/base/io_buffer.h"
19 #include "net/base/net_errors.h"
20 #include "net/base/x509_certificate.h"
21 #include "net/http/http_response_headers.h"
22 #include "net/url_request/url_request.h"
23
24 using base::Time;
25 using base::TimeDelta;
26
27 //
28 // URLRequestInterceptJob
29 //
30
31 URLRequestInterceptJob::URLRequestInterceptJob(net::URLRequest* request,
32 ChromePluginLib* plugin,
33 ScopableCPRequest* cprequest)
34 : net::URLRequestJob(request),
35 cprequest_(cprequest),
36 plugin_(plugin),
37 read_buffer_(NULL),
38 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
39 cprequest_->data = this; // see FromCPRequest().
40
41 registrar_.Add(this, NotificationType::CHROME_PLUGIN_UNLOADED,
42 Source<ChromePluginLib>(plugin_));
43 }
44
45 URLRequestInterceptJob::~URLRequestInterceptJob() {
46 if (plugin_) {
47 plugin_->functions().request_funcs->end_request(cprequest_.get(),
48 CPERR_SUCCESS);
49 }
50 }
51
52 void URLRequestInterceptJob::DetachPlugin() {
53 registrar_.RemoveAll();
54 plugin_ = NULL;
55 }
56
57 void URLRequestInterceptJob::Start() {
58 // Start reading asynchronously so that all error reporting and data
59 // callbacks happen as they would for network requests.
60 MessageLoop::current()->PostTask(
61 FROM_HERE,
62 method_factory_.NewRunnableMethod(
63 &URLRequestInterceptJob::StartAsync));
64 }
65
66 void URLRequestInterceptJob::Kill() {
67 if (plugin_) {
68 plugin_->functions().request_funcs->end_request(cprequest_.get(),
69 CPERR_CANCELLED);
70 DetachPlugin();
71 }
72 net::URLRequestJob::Kill();
73 method_factory_.RevokeAll();
74 }
75
76 bool URLRequestInterceptJob::ReadRawData(net::IOBuffer* dest, int dest_size,
77 int* bytes_read) {
78 DCHECK_NE(dest_size, 0);
79 DCHECK(bytes_read);
80
81 if (!plugin_)
82 return false;
83
84 int rv = plugin_->functions().request_funcs->read(cprequest_.get(),
85 dest->data(), dest_size);
86 if (rv >= 0) {
87 *bytes_read = rv;
88 return true;
89 }
90
91 if (rv == CPERR_IO_PENDING) {
92 read_buffer_ = dest;
93 read_buffer_size_ = dest_size;
94 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
95 } else {
96 // TODO(mpcomplete): better error code
97 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
98 net::ERR_FAILED));
99 }
100
101 return false;
102 }
103
104 bool URLRequestInterceptJob::GetMimeType(std::string* mime_type) const {
105 return request_->response_headers()->GetMimeType(mime_type);
106 }
107
108 bool URLRequestInterceptJob::GetCharset(std::string* charset) {
109 return request_->response_headers()->GetCharset(charset);
110 }
111
112 bool URLRequestInterceptJob::GetContentEncodings(
113 std::vector<Filter::FilterType>* encoding_types) {
114 DCHECK(encoding_types->empty());
115 if (!request_->response_headers())
116 return false;
117
118 std::string encoding_type;
119 void* iter = NULL;
120 while (request_->response_headers()->EnumerateHeader(
121 &iter, "Content-Encoding", &encoding_type)) {
122 encoding_types->push_back(Filter::ConvertEncodingToType(encoding_type));
123 }
124
125 // Even if encoding types are empty, there is a chance that we need to add
126 // some decoding, as some proxies strip encoding completely. In such cases,
127 // we may need to add (for example) SDCH filtering (when the context suggests
128 // it is appropriate).
129 Filter::FixupEncodingTypes(*this, encoding_types);
130 return !encoding_types->empty();
131 }
132
133 void URLRequestInterceptJob::GetResponseInfo(net::HttpResponseInfo* info) {
134 if (!plugin_)
135 return;
136
137 std::string raw_headers;
138 int size = plugin_->functions().request_funcs->get_response_info(
139 cprequest_.get(), CPRESPONSEINFO_HTTP_RAW_HEADERS, NULL, 0);
140 int rv = size < 0 ? size :
141 plugin_->functions().request_funcs->get_response_info(
142 cprequest_.get(), CPRESPONSEINFO_HTTP_RAW_HEADERS,
143 WriteInto(&raw_headers, size+1), size);
144 if (rv != CPERR_SUCCESS) {
145 // TODO(mpcomplete): what should we do here?
146 raw_headers = "HTTP/1.1 404 Not Found";
147 raw_headers.push_back('\0');
148 }
149
150 info->headers = new net::HttpResponseHeaders(raw_headers);
151
152 if (request_->url().SchemeIsSecure()) {
153 // Make up a fake certificate for intercepted data since we don't have
154 // access to the real SSL info.
155 // TODO(mpcomplete): we should probably have the interception API transmit
156 // the SSL info, but the only consumer of this API (Gears) doesn't keep that
157 // around. We should change that.
158 const char* kCertIssuer = "Chrome Internal";
159 const int kLifetimeDays = 100;
160
161 DLOG(WARNING) << "Issuing a fake SSL certificate for interception of URL "
162 << request_->url();
163
164 info->ssl_info.cert =
165 new net::X509Certificate(request_->url().GetWithEmptyPath().spec(),
166 kCertIssuer,
167 Time::Now(),
168 Time::Now() +
169 TimeDelta::FromDays(kLifetimeDays));
170 info->ssl_info.cert_status = 0;
171 info->ssl_info.security_bits = -1;
172 }
173 }
174
175 int URLRequestInterceptJob::GetResponseCode() const {
176 if (!plugin_)
177 return -1;
178
179 int status = 200;
180 plugin_->functions().request_funcs->get_response_info(
181 cprequest_.get(), CPRESPONSEINFO_HTTP_STATUS, &status, sizeof(status));
182
183 return status;
184 }
185
186 bool URLRequestInterceptJob::IsRedirectResponse(GURL* location,
187 int* http_status_code) {
188 if (!request_->response_headers())
189 return false;
190
191 std::string value;
192 if (!request_->response_headers()->IsRedirect(&value))
193 return false;
194
195 *location = request_->url().Resolve(value);
196 *http_status_code = request_->response_headers()->response_code();
197 return true;
198 }
199
200 void URLRequestInterceptJob::StartAsync() {
201 // We may have been orphaned...
202 if (!request_ || !plugin_)
203 return;
204
205 int rv = plugin_->functions().request_funcs->start_request(cprequest_.get());
206 if (rv != CPERR_IO_PENDING)
207 OnStartCompleted(rv);
208 }
209
210 void URLRequestInterceptJob::OnStartCompleted(int result) {
211 if (result != CPERR_SUCCESS) {
212 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
213 net::ERR_CONNECTION_FAILED));
214 return;
215 }
216
217 NotifyHeadersComplete();
218 }
219
220 void URLRequestInterceptJob::OnReadCompleted(int bytes_read) {
221 if (bytes_read < 0) {
222 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
223 net::ERR_FAILED));
224 return;
225 }
226
227 SetStatus(net::URLRequestStatus()); // clear the async flag
228 NotifyReadComplete(bytes_read);
229 }
230
231 void URLRequestInterceptJob::Observe(NotificationType type,
232 const NotificationSource& source,
233 const NotificationDetails& details) {
234 DCHECK(type == NotificationType::CHROME_PLUGIN_UNLOADED);
235 DCHECK(plugin_ == Source<ChromePluginLib>(source).ptr());
236 DetachPlugin();
237 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698