OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // source code is governed by a BSD-style license that can be found in the | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/proxy/proxy_resolver_v8.h" | 5 #include "net/proxy/proxy_resolver_v8.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
9 #include "googleurl/src/gurl.h" | 9 #include "googleurl/src/gurl.h" |
10 #include "net/base/load_log.h" | |
11 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
| 11 #include "net/base/net_log.h" |
12 #include "net/proxy/proxy_info.h" | 12 #include "net/proxy/proxy_info.h" |
13 #include "net/proxy/proxy_resolver_js_bindings.h" | 13 #include "net/proxy/proxy_resolver_js_bindings.h" |
14 #include "net/proxy/proxy_resolver_script.h" | 14 #include "net/proxy/proxy_resolver_script.h" |
15 #include "v8/include/v8.h" | 15 #include "v8/include/v8.h" |
16 | 16 |
17 // Notes on the javascript environment: | 17 // Notes on the javascript environment: |
18 // | 18 // |
19 // For the majority of the PAC utility functions, we use the same code | 19 // For the majority of the PAC utility functions, we use the same code |
20 // as Firefox. See the javascript library that proxy_resolver_scipt.h | 20 // as Firefox. See the javascript library that proxy_resolver_scipt.h |
21 // pulls in. | 21 // pulls in. |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 return true; | 95 return true; |
96 } | 96 } |
97 | 97 |
98 } // namespace | 98 } // namespace |
99 | 99 |
100 // ProxyResolverV8::Context --------------------------------------------------- | 100 // ProxyResolverV8::Context --------------------------------------------------- |
101 | 101 |
102 class ProxyResolverV8::Context { | 102 class ProxyResolverV8::Context { |
103 public: | 103 public: |
104 explicit Context(ProxyResolverJSBindings* js_bindings) | 104 explicit Context(ProxyResolverJSBindings* js_bindings) |
105 : js_bindings_(js_bindings), current_request_load_log_(NULL) { | 105 : js_bindings_(js_bindings), current_request_net_log_(NULL) { |
106 DCHECK(js_bindings != NULL); | 106 DCHECK(js_bindings != NULL); |
107 } | 107 } |
108 | 108 |
109 ~Context() { | 109 ~Context() { |
110 v8::Locker locked; | 110 v8::Locker locked; |
111 | 111 |
112 v8_this_.Dispose(); | 112 v8_this_.Dispose(); |
113 v8_context_.Dispose(); | 113 v8_context_.Dispose(); |
114 } | 114 } |
115 | 115 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 | 207 |
208 // At a minimum, the FindProxyForURL() function must be defined for this | 208 // At a minimum, the FindProxyForURL() function must be defined for this |
209 // to be a legitimiate PAC script. | 209 // to be a legitimiate PAC script. |
210 v8::Local<v8::Value> function; | 210 v8::Local<v8::Value> function; |
211 if (!GetFindProxyForURL(&function)) | 211 if (!GetFindProxyForURL(&function)) |
212 return ERR_PAC_SCRIPT_FAILED; | 212 return ERR_PAC_SCRIPT_FAILED; |
213 | 213 |
214 return OK; | 214 return OK; |
215 } | 215 } |
216 | 216 |
217 void SetCurrentRequestLoadLog(LoadLog* load_log) { | 217 void SetCurrentRequestNetLog(BoundNetLog* net_log) { |
218 current_request_load_log_ = load_log; | 218 current_request_net_log_ = net_log; |
219 } | 219 } |
220 | 220 |
221 void PurgeMemory() { | 221 void PurgeMemory() { |
222 v8::Locker locked; | 222 v8::Locker locked; |
223 // Repeatedly call the V8 idle notification until it returns true ("nothing | 223 // Repeatedly call the V8 idle notification until it returns true ("nothing |
224 // more to free"). Note that it makes more sense to do this than to | 224 // more to free"). Note that it makes more sense to do this than to |
225 // implement a new "delete everything" pass because object references make | 225 // implement a new "delete everything" pass because object references make |
226 // it difficult to free everything possible in just one pass. | 226 // it difficult to free everything possible in just one pass. |
227 while (!v8::V8::IdleNotification()) | 227 while (!v8::V8::IdleNotification()) |
228 ; | 228 ; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 | 286 |
287 context->js_bindings_->Alert(message); | 287 context->js_bindings_->Alert(message); |
288 return v8::Undefined(); | 288 return v8::Undefined(); |
289 } | 289 } |
290 | 290 |
291 // V8 callback for when "myIpAddress()" is invoked by the PAC script. | 291 // V8 callback for when "myIpAddress()" is invoked by the PAC script. |
292 static v8::Handle<v8::Value> MyIpAddressCallback(const v8::Arguments& args) { | 292 static v8::Handle<v8::Value> MyIpAddressCallback(const v8::Arguments& args) { |
293 Context* context = | 293 Context* context = |
294 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); | 294 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); |
295 | 295 |
296 LoadLog::BeginEvent(context->current_request_load_log_, | 296 context->current_request_net_log_->BeginEvent( |
297 LoadLog::TYPE_PROXY_RESOLVER_V8_MY_IP_ADDRESS); | 297 NetLog::TYPE_PROXY_RESOLVER_V8_MY_IP_ADDRESS); |
298 | 298 |
299 // We shouldn't be called with any arguments, but will not complain if | 299 // We shouldn't be called with any arguments, but will not complain if |
300 // we are. | 300 // we are. |
301 std::string result = context->js_bindings_->MyIpAddress(); | 301 std::string result = context->js_bindings_->MyIpAddress(); |
302 | 302 |
303 LoadLog::EndEvent(context->current_request_load_log_, | 303 context->current_request_net_log_->EndEvent( |
304 LoadLog::TYPE_PROXY_RESOLVER_V8_MY_IP_ADDRESS); | 304 NetLog::TYPE_PROXY_RESOLVER_V8_MY_IP_ADDRESS); |
305 | 305 |
306 if (result.empty()) | 306 if (result.empty()) |
307 result = "127.0.0.1"; | 307 result = "127.0.0.1"; |
308 return StdStringToV8String(result); | 308 return StdStringToV8String(result); |
309 } | 309 } |
310 | 310 |
311 // V8 callback for when "myIpAddressEx()" is invoked by the PAC script. | 311 // V8 callback for when "myIpAddressEx()" is invoked by the PAC script. |
312 static v8::Handle<v8::Value> MyIpAddressExCallback( | 312 static v8::Handle<v8::Value> MyIpAddressExCallback( |
313 const v8::Arguments& args) { | 313 const v8::Arguments& args) { |
314 Context* context = | 314 Context* context = |
315 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); | 315 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); |
316 | 316 |
317 LoadLog::BeginEvent(context->current_request_load_log_, | 317 context->current_request_net_log_->BeginEvent( |
318 LoadLog::TYPE_PROXY_RESOLVER_V8_MY_IP_ADDRESS_EX); | 318 NetLog::TYPE_PROXY_RESOLVER_V8_MY_IP_ADDRESS_EX); |
319 | 319 |
320 // We shouldn't be called with any arguments, but will not complain if | 320 // We shouldn't be called with any arguments, but will not complain if |
321 // we are. | 321 // we are. |
322 std::string result = context->js_bindings_->MyIpAddressEx(); | 322 std::string result = context->js_bindings_->MyIpAddressEx(); |
323 | 323 |
324 LoadLog::EndEvent(context->current_request_load_log_, | 324 context->current_request_net_log_->EndEvent( |
325 LoadLog::TYPE_PROXY_RESOLVER_V8_MY_IP_ADDRESS_EX); | 325 NetLog::TYPE_PROXY_RESOLVER_V8_MY_IP_ADDRESS_EX); |
326 | 326 |
327 return StdStringToV8String(result); | 327 return StdStringToV8String(result); |
328 } | 328 } |
329 | 329 |
330 // V8 callback for when "dnsResolve()" is invoked by the PAC script. | 330 // V8 callback for when "dnsResolve()" is invoked by the PAC script. |
331 static v8::Handle<v8::Value> DnsResolveCallback(const v8::Arguments& args) { | 331 static v8::Handle<v8::Value> DnsResolveCallback(const v8::Arguments& args) { |
332 Context* context = | 332 Context* context = |
333 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); | 333 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); |
334 | 334 |
335 // We need at least one argument. | 335 // We need at least one argument. |
336 std::string host; | 336 std::string host; |
337 if (args.Length() == 0) { | 337 if (args.Length() == 0) { |
338 host = "undefined"; | 338 host = "undefined"; |
339 } else { | 339 } else { |
340 if (!V8ObjectToString(args[0], &host)) | 340 if (!V8ObjectToString(args[0], &host)) |
341 return v8::Undefined(); | 341 return v8::Undefined(); |
342 } | 342 } |
343 | 343 |
344 LoadLog::BeginEvent(context->current_request_load_log_, | 344 context->current_request_net_log_->BeginEvent( |
345 LoadLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE); | 345 NetLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE); |
346 | 346 |
347 std::string result = context->js_bindings_->DnsResolve(host); | 347 std::string result = context->js_bindings_->DnsResolve(host); |
348 | 348 |
349 LoadLog::EndEvent(context->current_request_load_log_, | 349 context->current_request_net_log_->EndEvent( |
350 LoadLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE); | 350 NetLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE); |
351 | 351 |
352 // DnsResolve() returns empty string on failure. | 352 // DnsResolve() returns empty string on failure. |
353 return result.empty() ? v8::Null() : StdStringToV8String(result); | 353 return result.empty() ? v8::Null() : StdStringToV8String(result); |
354 } | 354 } |
355 | 355 |
356 // V8 callback for when "dnsResolveEx()" is invoked by the PAC script. | 356 // V8 callback for when "dnsResolveEx()" is invoked by the PAC script. |
357 static v8::Handle<v8::Value> DnsResolveExCallback(const v8::Arguments& args) { | 357 static v8::Handle<v8::Value> DnsResolveExCallback(const v8::Arguments& args) { |
358 Context* context = | 358 Context* context = |
359 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); | 359 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); |
360 | 360 |
361 // We need at least one argument. | 361 // We need at least one argument. |
362 std::string host; | 362 std::string host; |
363 if (args.Length() == 0) { | 363 if (args.Length() == 0) { |
364 host = "undefined"; | 364 host = "undefined"; |
365 } else { | 365 } else { |
366 if (!V8ObjectToString(args[0], &host)) | 366 if (!V8ObjectToString(args[0], &host)) |
367 return v8::Undefined(); | 367 return v8::Undefined(); |
368 } | 368 } |
369 | 369 |
370 LoadLog::BeginEvent(context->current_request_load_log_, | 370 context->current_request_net_log_->BeginEvent( |
371 LoadLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE_EX); | 371 NetLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE_EX); |
372 | 372 |
373 std::string result = context->js_bindings_->DnsResolveEx(host); | 373 std::string result = context->js_bindings_->DnsResolveEx(host); |
374 | 374 |
375 LoadLog::EndEvent(context->current_request_load_log_, | 375 context->current_request_net_log_->EndEvent( |
376 LoadLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE_EX); | 376 NetLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE_EX); |
377 | 377 |
378 return StdStringToV8String(result); | 378 return StdStringToV8String(result); |
379 } | 379 } |
380 | 380 |
381 ProxyResolverJSBindings* js_bindings_; | 381 ProxyResolverJSBindings* js_bindings_; |
382 LoadLog* current_request_load_log_; | 382 BoundNetLog* current_request_net_log_; |
383 v8::Persistent<v8::External> v8_this_; | 383 v8::Persistent<v8::External> v8_this_; |
384 v8::Persistent<v8::Context> v8_context_; | 384 v8::Persistent<v8::Context> v8_context_; |
385 }; | 385 }; |
386 | 386 |
387 // ProxyResolverV8 ------------------------------------------------------------ | 387 // ProxyResolverV8 ------------------------------------------------------------ |
388 | 388 |
389 ProxyResolverV8::ProxyResolverV8( | 389 ProxyResolverV8::ProxyResolverV8( |
390 ProxyResolverJSBindings* custom_js_bindings) | 390 ProxyResolverJSBindings* custom_js_bindings) |
391 : ProxyResolver(true /*expects_pac_bytes*/), | 391 : ProxyResolver(true /*expects_pac_bytes*/), |
392 js_bindings_(custom_js_bindings) { | 392 js_bindings_(custom_js_bindings) { |
393 } | 393 } |
394 | 394 |
395 ProxyResolverV8::~ProxyResolverV8() {} | 395 ProxyResolverV8::~ProxyResolverV8() {} |
396 | 396 |
397 int ProxyResolverV8::GetProxyForURL(const GURL& query_url, | 397 int ProxyResolverV8::GetProxyForURL(const GURL& query_url, |
398 ProxyInfo* results, | 398 ProxyInfo* results, |
399 CompletionCallback* /*callback*/, | 399 CompletionCallback* /*callback*/, |
400 RequestHandle* /*request*/, | 400 RequestHandle* /*request*/, |
401 LoadLog* load_log) { | 401 const BoundNetLog& net_log) { |
402 // If the V8 instance has not been initialized (either because | 402 // If the V8 instance has not been initialized (either because |
403 // SetPacScript() wasn't called yet, or because it failed. | 403 // SetPacScript() wasn't called yet, or because it failed. |
404 if (!context_.get()) | 404 if (!context_.get()) |
405 return ERR_FAILED; | 405 return ERR_FAILED; |
406 | 406 |
| 407 BoundNetLog log(net_log); |
| 408 |
407 // Otherwise call into V8. | 409 // Otherwise call into V8. |
408 context_->SetCurrentRequestLoadLog(load_log); | 410 context_->SetCurrentRequestNetLog(&log); |
409 int rv = context_->ResolveProxy(query_url, results); | 411 int rv = context_->ResolveProxy(query_url, results); |
410 context_->SetCurrentRequestLoadLog(NULL); | 412 context_->SetCurrentRequestNetLog(NULL); |
411 | 413 |
412 return rv; | 414 return rv; |
413 } | 415 } |
414 | 416 |
415 void ProxyResolverV8::CancelRequest(RequestHandle request) { | 417 void ProxyResolverV8::CancelRequest(RequestHandle request) { |
416 // This is a synchronous ProxyResolver; no possibility for async requests. | 418 // This is a synchronous ProxyResolver; no possibility for async requests. |
417 NOTREACHED(); | 419 NOTREACHED(); |
418 } | 420 } |
419 | 421 |
420 void ProxyResolverV8::PurgeMemory() { | 422 void ProxyResolverV8::PurgeMemory() { |
421 context_->PurgeMemory(); | 423 context_->PurgeMemory(); |
422 } | 424 } |
423 | 425 |
424 int ProxyResolverV8::SetPacScript(const GURL& /*url*/, | 426 int ProxyResolverV8::SetPacScript(const GURL& /*url*/, |
425 const std::string& bytes_utf8, | 427 const std::string& bytes_utf8, |
426 CompletionCallback* /*callback*/) { | 428 CompletionCallback* /*callback*/) { |
427 context_.reset(); | 429 context_.reset(); |
428 if (bytes_utf8.empty()) | 430 if (bytes_utf8.empty()) |
429 return ERR_PAC_SCRIPT_FAILED; | 431 return ERR_PAC_SCRIPT_FAILED; |
430 | 432 |
431 // Try parsing the PAC script. | 433 // Try parsing the PAC script. |
432 scoped_ptr<Context> context(new Context(js_bindings_.get())); | 434 scoped_ptr<Context> context(new Context(js_bindings_.get())); |
433 int rv = context->InitV8(bytes_utf8); | 435 int rv = context->InitV8(bytes_utf8); |
434 if (rv == OK) | 436 if (rv == OK) |
435 context_.reset(context.release()); | 437 context_.reset(context.release()); |
436 return rv; | 438 return rv; |
437 } | 439 } |
438 | 440 |
439 } // namespace net | 441 } // namespace net |
OLD | NEW |