OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/browser/chrome_plugin_host.h" | 5 #include "chrome/browser/chrome_plugin_host.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 #include "third_party/skia/include/core/SkBitmap.h" | 47 #include "third_party/skia/include/core/SkBitmap.h" |
48 | 48 |
49 | 49 |
50 using base::TimeDelta; | 50 using base::TimeDelta; |
51 | 51 |
52 // This class manages the interception of network requests. It queries the | 52 // This class manages the interception of network requests. It queries the |
53 // plugin on every request, and creates an intercept job if the plugin can | 53 // plugin on every request, and creates an intercept job if the plugin can |
54 // intercept the request. | 54 // intercept the request. |
55 // NOTE: All methods must be called on the IO thread. | 55 // NOTE: All methods must be called on the IO thread. |
56 class PluginRequestInterceptor | 56 class PluginRequestInterceptor |
57 : public PluginHelper, public URLRequest::Interceptor { | 57 : public PluginHelper, public net::URLRequest::Interceptor { |
58 public: | 58 public: |
59 static URLRequestJob* UninterceptedProtocolHandler( | 59 static URLRequestJob* UninterceptedProtocolHandler( |
60 URLRequest* request, const std::string& scheme) { | 60 net::URLRequest* request, const std::string& scheme) { |
61 // This will get called if a plugin failed to intercept a request for a | 61 // This will get called if a plugin failed to intercept a request for a |
62 // protocol it has registered. In that case, we return NULL and the request | 62 // protocol it has registered. In that case, we return NULL and the request |
63 // will result in an error. | 63 // will result in an error. |
64 return new URLRequestErrorJob(request, net::ERR_FILE_NOT_FOUND); | 64 return new URLRequestErrorJob(request, net::ERR_FILE_NOT_FOUND); |
65 } | 65 } |
66 | 66 |
67 explicit PluginRequestInterceptor(ChromePluginLib* plugin) | 67 explicit PluginRequestInterceptor(ChromePluginLib* plugin) |
68 : PluginHelper(plugin) { | 68 : PluginHelper(plugin) { |
69 URLRequest::RegisterRequestInterceptor(this); | 69 net::URLRequest::RegisterRequestInterceptor(this); |
70 } | 70 } |
71 | 71 |
72 virtual ~PluginRequestInterceptor() { | 72 virtual ~PluginRequestInterceptor() { |
73 URLRequest::UnregisterRequestInterceptor(this); | 73 net::URLRequest::UnregisterRequestInterceptor(this); |
74 | 74 |
75 // Unregister our protocols. | 75 // Unregister our protocols. |
76 for (HandledProtocolList::iterator it = registered_protocols_.begin(); | 76 for (HandledProtocolList::iterator it = registered_protocols_.begin(); |
77 it != registered_protocols_.end(); ++it) { | 77 it != registered_protocols_.end(); ++it) { |
78 URLRequest::ProtocolFactory* factory = | 78 net::URLRequest::ProtocolFactory* factory = |
79 URLRequest::RegisterProtocolFactory(*it, NULL); | 79 net::URLRequest::RegisterProtocolFactory(*it, NULL); |
80 DCHECK(factory == UninterceptedProtocolHandler); | 80 DCHECK(factory == UninterceptedProtocolHandler); |
81 } | 81 } |
82 } | 82 } |
83 | 83 |
84 void RegisterProtocol(const std::string& scheme) { | 84 void RegisterProtocol(const std::string& scheme) { |
85 DCHECK(CalledOnValidThread()); | 85 DCHECK(CalledOnValidThread()); |
86 | 86 |
87 std::string lower_scheme = StringToLowerASCII(scheme); | 87 std::string lower_scheme = StringToLowerASCII(scheme); |
88 handled_protocols_.insert(lower_scheme); | 88 handled_protocols_.insert(lower_scheme); |
89 | 89 |
90 // Only add a protocol factory if the URLRequest doesn't already handle | 90 // Only add a protocol factory if the net::URLRequest doesn't already handle |
91 // it. If we fail to intercept, the request will be treated as an error. | 91 // it. If we fail to intercept, the request will be treated as an error. |
92 if (!URLRequest::IsHandledProtocol(lower_scheme)) { | 92 if (!net::URLRequest::IsHandledProtocol(lower_scheme)) { |
93 registered_protocols_.insert(lower_scheme); | 93 registered_protocols_.insert(lower_scheme); |
94 URLRequest::RegisterProtocolFactory(lower_scheme, | 94 net::URLRequest::RegisterProtocolFactory(lower_scheme, |
95 &UninterceptedProtocolHandler); | 95 &UninterceptedProtocolHandler); |
96 } | 96 } |
97 } | 97 } |
98 | 98 |
99 // URLRequest::Interceptor | 99 // net::URLRequest::Interceptor |
100 virtual URLRequestJob* MaybeIntercept(URLRequest* request) { | 100 virtual URLRequestJob* MaybeIntercept(net::URLRequest* request) { |
101 // TODO(darin): This DCHECK fails in the unit tests because our interceptor | 101 // TODO(darin): This DCHECK fails in the unit tests because our interceptor |
102 // is being persisted across unit tests. As a result, each time we get | 102 // is being persisted across unit tests. As a result, each time we get |
103 // poked on a different thread, but never from more than one thread at a | 103 // poked on a different thread, but never from more than one thread at a |
104 // time. We need a way to have the URLRequestJobManager get reset between | 104 // time. We need a way to have the URLRequestJobManager get reset between |
105 // unit tests. | 105 // unit tests. |
106 // DCHECK(CalledOnValidThread()); | 106 // DCHECK(CalledOnValidThread()); |
107 | 107 |
108 if (!IsHandledProtocol(request->url().scheme())) | 108 if (!IsHandledProtocol(request->url().scheme())) |
109 return NULL; | 109 return NULL; |
110 | 110 |
(...skipping 25 matching lines...) Expand all Loading... |
136 void LogInterceptMissTime(const TimeDelta& time) { | 136 void LogInterceptMissTime(const TimeDelta& time) { |
137 UMA_HISTOGRAM_TIMES("Gears.InterceptMiss", time); | 137 UMA_HISTOGRAM_TIMES("Gears.InterceptMiss", time); |
138 } | 138 } |
139 | 139 |
140 typedef std::set<std::string> HandledProtocolList; | 140 typedef std::set<std::string> HandledProtocolList; |
141 HandledProtocolList handled_protocols_; | 141 HandledProtocolList handled_protocols_; |
142 HandledProtocolList registered_protocols_; | 142 HandledProtocolList registered_protocols_; |
143 }; | 143 }; |
144 | 144 |
145 // This class manages a network request made by the plugin, also acting as | 145 // This class manages a network request made by the plugin, also acting as |
146 // the URLRequest delegate. | 146 // the net::URLRequest delegate. |
147 // NOTE: All methods must be called on the IO thread. | 147 // NOTE: All methods must be called on the IO thread. |
148 class PluginRequestHandler : public PluginHelper, public URLRequest::Delegate { | 148 class PluginRequestHandler : public PluginHelper, |
| 149 public net::URLRequest::Delegate { |
149 public: | 150 public: |
150 static PluginRequestHandler* FromCPRequest(CPRequest* request) { | 151 static PluginRequestHandler* FromCPRequest(CPRequest* request) { |
151 return ScopableCPRequest::GetData<PluginRequestHandler*>(request); | 152 return ScopableCPRequest::GetData<PluginRequestHandler*>(request); |
152 } | 153 } |
153 | 154 |
154 PluginRequestHandler(ChromePluginLib* plugin, ScopableCPRequest* cprequest) | 155 PluginRequestHandler(ChromePluginLib* plugin, ScopableCPRequest* cprequest) |
155 : PluginHelper(plugin), cprequest_(cprequest), user_buffer_(NULL) { | 156 : PluginHelper(plugin), cprequest_(cprequest), user_buffer_(NULL) { |
156 cprequest_->data = this; // see FromCPRequest(). | 157 cprequest_->data = this; // see FromCPRequest(). |
157 | 158 |
158 URLRequestContext* context = CPBrowsingContextManager::Instance()-> | 159 URLRequestContext* context = CPBrowsingContextManager::Instance()-> |
159 ToURLRequestContext(cprequest_->context); | 160 ToURLRequestContext(cprequest_->context); |
160 // TODO(mpcomplete): remove fallback case when Gears support is prevalent. | 161 // TODO(mpcomplete): remove fallback case when Gears support is prevalent. |
161 if (!context) | 162 if (!context) |
162 context = Profile::GetDefaultRequestContext()->GetURLRequestContext(); | 163 context = Profile::GetDefaultRequestContext()->GetURLRequestContext(); |
163 | 164 |
164 GURL gurl(cprequest_->url); | 165 GURL gurl(cprequest_->url); |
165 request_.reset(new URLRequest(gurl, this)); | 166 request_.reset(new net::URLRequest(gurl, this)); |
166 request_->set_context(context); | 167 request_->set_context(context); |
167 request_->set_method(cprequest_->method); | 168 request_->set_method(cprequest_->method); |
168 request_->set_load_flags(PluginResponseUtils::CPLoadFlagsToNetFlags(0)); | 169 request_->set_load_flags(PluginResponseUtils::CPLoadFlagsToNetFlags(0)); |
169 } | 170 } |
170 | 171 |
171 URLRequest* request() { return request_.get(); } | 172 net::URLRequest* request() { return request_.get(); } |
172 | 173 |
173 // Wraper of URLRequest::Read() | 174 // Wraper of net::URLRequest::Read() |
174 bool Read(char* dest, int dest_size, int *bytes_read) { | 175 bool Read(char* dest, int dest_size, int *bytes_read) { |
175 CHECK(!my_buffer_.get()); | 176 CHECK(!my_buffer_.get()); |
176 // We'll use our own buffer until the read actually completes. | 177 // We'll use our own buffer until the read actually completes. |
177 user_buffer_ = dest; | 178 user_buffer_ = dest; |
178 my_buffer_ = new net::IOBuffer(dest_size); | 179 my_buffer_ = new net::IOBuffer(dest_size); |
179 | 180 |
180 if (request_->Read(my_buffer_, dest_size, bytes_read)) { | 181 if (request_->Read(my_buffer_, dest_size, bytes_read)) { |
181 memcpy(dest, my_buffer_->data(), *bytes_read); | 182 memcpy(dest, my_buffer_->data(), *bytes_read); |
182 my_buffer_ = NULL; | 183 my_buffer_ = NULL; |
183 return true; | 184 return true; |
184 } | 185 } |
185 | 186 |
186 if (!request_->status().is_io_pending()) | 187 if (!request_->status().is_io_pending()) |
187 my_buffer_ = NULL; | 188 my_buffer_ = NULL; |
188 | 189 |
189 return false; | 190 return false; |
190 } | 191 } |
191 | 192 |
192 // URLRequest::Delegate | 193 // net::URLRequest::Delegate |
193 virtual void OnReceivedRedirect(URLRequest* request, const GURL& new_url, | 194 virtual void OnReceivedRedirect(net::URLRequest* request, const GURL& new_url, |
194 bool* defer_redirect) { | 195 bool* defer_redirect) { |
195 plugin_->functions().response_funcs->received_redirect( | 196 plugin_->functions().response_funcs->received_redirect( |
196 cprequest_.get(), new_url.spec().c_str()); | 197 cprequest_.get(), new_url.spec().c_str()); |
197 } | 198 } |
198 | 199 |
199 virtual void OnResponseStarted(URLRequest* request) { | 200 virtual void OnResponseStarted(net::URLRequest* request) { |
200 // TODO(mpcomplete): better error codes | 201 // TODO(mpcomplete): better error codes |
201 CPError result = | 202 CPError result = |
202 request_->status().is_success() ? CPERR_SUCCESS : CPERR_FAILURE; | 203 request_->status().is_success() ? CPERR_SUCCESS : CPERR_FAILURE; |
203 plugin_->functions().response_funcs->start_completed( | 204 plugin_->functions().response_funcs->start_completed( |
204 cprequest_.get(), result); | 205 cprequest_.get(), result); |
205 } | 206 } |
206 | 207 |
207 virtual void OnReadCompleted(URLRequest* request, int bytes_read) { | 208 virtual void OnReadCompleted(net::URLRequest* request, int bytes_read) { |
208 CHECK(my_buffer_.get()); | 209 CHECK(my_buffer_.get()); |
209 CHECK(user_buffer_); | 210 CHECK(user_buffer_); |
210 if (bytes_read > 0) { | 211 if (bytes_read > 0) { |
211 memcpy(user_buffer_, my_buffer_->data(), bytes_read); | 212 memcpy(user_buffer_, my_buffer_->data(), bytes_read); |
212 } else if (bytes_read < 0) { | 213 } else if (bytes_read < 0) { |
213 // TODO(mpcomplete): better error codes | 214 // TODO(mpcomplete): better error codes |
214 bytes_read = CPERR_FAILURE; | 215 bytes_read = CPERR_FAILURE; |
215 } | 216 } |
216 my_buffer_ = NULL; | 217 my_buffer_ = NULL; |
217 plugin_->functions().response_funcs->read_completed( | 218 plugin_->functions().response_funcs->read_completed( |
218 cprequest_.get(), bytes_read); | 219 cprequest_.get(), bytes_read); |
219 } | 220 } |
220 | 221 |
221 private: | 222 private: |
222 scoped_ptr<ScopableCPRequest> cprequest_; | 223 scoped_ptr<ScopableCPRequest> cprequest_; |
223 scoped_ptr<URLRequest> request_; | 224 scoped_ptr<net::URLRequest> request_; |
224 scoped_refptr<net::IOBuffer> my_buffer_; | 225 scoped_refptr<net::IOBuffer> my_buffer_; |
225 char* user_buffer_; | 226 char* user_buffer_; |
226 }; | 227 }; |
227 | 228 |
228 // This class manages plugins that want to handle UI commands. Right now, we | 229 // This class manages plugins that want to handle UI commands. Right now, we |
229 // only allow 1 plugin to do this, so there's only ever 1 instance of this | 230 // only allow 1 plugin to do this, so there's only ever 1 instance of this |
230 // class at once. | 231 // class at once. |
231 // NOTE: All methods must be called on the IO thread. | 232 // NOTE: All methods must be called on the IO thread. |
232 class PluginCommandHandler : public PluginHelper { | 233 class PluginCommandHandler : public PluginHelper { |
233 public: | 234 public: |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
824 CPBrowsingContext context) { | 825 CPBrowsingContext context) { |
825 // Sadly if we try and pass context through, we seem to break cl's little | 826 // Sadly if we try and pass context through, we seem to break cl's little |
826 // brain trying to compile the Tuple3 ctor. This cast works. | 827 // brain trying to compile the Tuple3 ctor. This cast works. |
827 int32 context_as_int32 = static_cast<int32>(context); | 828 int32 context_as_int32 = static_cast<int32>(context); |
828 // Plugins can only be accessed on the IO thread. | 829 // Plugins can only be accessed on the IO thread. |
829 BrowserThread::PostTask( | 830 BrowserThread::PostTask( |
830 BrowserThread::IO, FROM_HERE, | 831 BrowserThread::IO, FROM_HERE, |
831 NewRunnableFunction(PluginCommandHandler::HandleCommand, | 832 NewRunnableFunction(PluginCommandHandler::HandleCommand, |
832 command, data, context_as_int32)); | 833 command, data, context_as_int32)); |
833 } | 834 } |
OLD | NEW |