OLD | NEW |
---|---|
1 // Copyright (c) 2012 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 "net/proxy/proxy_resolver_v8.h" | 5 #include "net/proxy/proxy_resolver_v8.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cstdio> | 8 #include <cstdio> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 | 328 |
329 return IPNumberMatchesPrefix(address, prefix, prefix_length_in_bits); | 329 return IPNumberMatchesPrefix(address, prefix, prefix_length_in_bits); |
330 } | 330 } |
331 | 331 |
332 } // namespace | 332 } // namespace |
333 | 333 |
334 // ProxyResolverV8::Context --------------------------------------------------- | 334 // ProxyResolverV8::Context --------------------------------------------------- |
335 | 335 |
336 class ProxyResolverV8::Context { | 336 class ProxyResolverV8::Context { |
337 public: | 337 public: |
338 explicit Context(ProxyResolverJSBindings* js_bindings) | 338 explicit Context(ProxyResolverJSBindings* js_bindings, |
eroman
2013/01/18 19:21:14
nit: no more need for constructor to be marked exp
Sven Panne
2013/01/21 08:50:06
Done.
| |
339 v8::Isolate* v8_default_isolate) | |
339 : is_resolving_host_(false), | 340 : is_resolving_host_(false), |
340 js_bindings_(js_bindings) { | 341 js_bindings_(js_bindings), |
342 v8_default_isolate_(v8_default_isolate) { | |
341 DCHECK(js_bindings != NULL); | 343 DCHECK(js_bindings != NULL); |
342 } | 344 } |
343 | 345 |
344 ~Context() { | 346 ~Context() { |
345 v8::Locker locked; | 347 v8::Locker locked(v8_default_isolate_); |
346 | 348 |
347 v8_this_.Dispose(); | 349 v8_this_.Dispose(); |
348 v8_context_.Dispose(); | 350 v8_context_.Dispose(); |
349 | 351 |
350 // Run the V8 garbage collector. We do this to be sure the | 352 // Run the V8 garbage collector. We do this to be sure the |
351 // ExternalStringResource objects we allocated get properly disposed. | 353 // ExternalStringResource objects we allocated get properly disposed. |
352 // Otherwise when running the unit-tests they may get leaked. | 354 // Otherwise when running the unit-tests they may get leaked. |
353 // See crbug.com/48145. | 355 // See crbug.com/48145. |
354 PurgeMemory(); | 356 PurgeMemory(); |
355 } | 357 } |
356 | 358 |
357 int ResolveProxy(const GURL& query_url, ProxyInfo* results) { | 359 int ResolveProxy(const GURL& query_url, ProxyInfo* results) { |
358 v8::Locker locked; | 360 v8::Locker locked(v8_default_isolate_); |
359 v8::HandleScope scope; | 361 v8::HandleScope scope; |
360 | 362 |
361 v8::Context::Scope function_scope(v8_context_); | 363 v8::Context::Scope function_scope(v8_context_); |
362 | 364 |
363 v8::Local<v8::Value> function; | 365 v8::Local<v8::Value> function; |
364 if (!GetFindProxyForURL(&function)) { | 366 if (!GetFindProxyForURL(&function)) { |
365 js_bindings_->OnError( | 367 js_bindings_->OnError( |
366 -1, ASCIIToUTF16("FindProxyForURL() is undefined.")); | 368 -1, ASCIIToUTF16("FindProxyForURL() is undefined.")); |
367 return ERR_PAC_SCRIPT_FAILED; | 369 return ERR_PAC_SCRIPT_FAILED; |
368 } | 370 } |
(...skipping 30 matching lines...) Expand all Loading... | |
399 "(crbug.com/47234): ") + ret_str; | 401 "(crbug.com/47234): ") + ret_str; |
400 js_bindings_->OnError(-1, error_message); | 402 js_bindings_->OnError(-1, error_message); |
401 return ERR_PAC_SCRIPT_FAILED; | 403 return ERR_PAC_SCRIPT_FAILED; |
402 } | 404 } |
403 | 405 |
404 results->UsePacString(UTF16ToASCII(ret_str)); | 406 results->UsePacString(UTF16ToASCII(ret_str)); |
405 return OK; | 407 return OK; |
406 } | 408 } |
407 | 409 |
408 int InitV8(const scoped_refptr<ProxyResolverScriptData>& pac_script) { | 410 int InitV8(const scoped_refptr<ProxyResolverScriptData>& pac_script) { |
409 v8::Locker locked; | 411 v8::Locker locked(v8_default_isolate_); |
410 v8::HandleScope scope; | 412 v8::HandleScope scope; |
411 | 413 |
412 v8_this_ = v8::Persistent<v8::External>::New(v8::External::New(this)); | 414 v8_this_ = v8::Persistent<v8::External>::New(v8::External::New(this)); |
413 v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); | 415 v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); |
414 | 416 |
415 // Attach the javascript bindings. | 417 // Attach the javascript bindings. |
416 v8::Local<v8::FunctionTemplate> alert_template = | 418 v8::Local<v8::FunctionTemplate> alert_template = |
417 v8::FunctionTemplate::New(&AlertCallback, v8_this_); | 419 v8::FunctionTemplate::New(&AlertCallback, v8_this_); |
418 global_template->Set(ASCIILiteralToV8String("alert"), alert_template); | 420 global_template->Set(ASCIILiteralToV8String("alert"), alert_template); |
419 | 421 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
481 } | 483 } |
482 | 484 |
483 return OK; | 485 return OK; |
484 } | 486 } |
485 | 487 |
486 void SetCurrentRequestContext(ProxyResolverRequestContext* context) { | 488 void SetCurrentRequestContext(ProxyResolverRequestContext* context) { |
487 js_bindings_->set_current_request_context(context); | 489 js_bindings_->set_current_request_context(context); |
488 } | 490 } |
489 | 491 |
490 void PurgeMemory() { | 492 void PurgeMemory() { |
491 v8::Locker locked; | 493 v8::Locker locked(v8_default_isolate_); |
492 v8::V8::LowMemoryNotification(); | 494 v8::V8::LowMemoryNotification(); |
493 } | 495 } |
494 | 496 |
495 bool is_resolving_host() const { | 497 bool is_resolving_host() const { |
496 base::AutoLock auto_lock(lock_); | 498 base::AutoLock auto_lock(lock_); |
497 return is_resolving_host_; | 499 return is_resolving_host_; |
498 } | 500 } |
499 | 501 |
500 private: | 502 private: |
501 class ScopedHostResolve { | 503 class ScopedHostResolve { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
588 | 590 |
589 // V8 callback for when "myIpAddress()" is invoked by the PAC script. | 591 // V8 callback for when "myIpAddress()" is invoked by the PAC script. |
590 static v8::Handle<v8::Value> MyIpAddressCallback(const v8::Arguments& args) { | 592 static v8::Handle<v8::Value> MyIpAddressCallback(const v8::Arguments& args) { |
591 Context* context = | 593 Context* context = |
592 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); | 594 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); |
593 | 595 |
594 std::string result; | 596 std::string result; |
595 bool success; | 597 bool success; |
596 | 598 |
597 { | 599 { |
598 v8::Unlocker unlocker; | 600 v8::Unlocker unlocker(args.GetIsolate()); |
599 ScopedHostResolve scoped_host_resolve(context); | 601 ScopedHostResolve scoped_host_resolve(context); |
600 | 602 |
601 // We shouldn't be called with any arguments, but will not complain if | 603 // We shouldn't be called with any arguments, but will not complain if |
602 // we are. | 604 // we are. |
603 success = context->js_bindings_->MyIpAddress(&result); | 605 success = context->js_bindings_->MyIpAddress(&result); |
604 } | 606 } |
605 | 607 |
606 if (!success) | 608 if (!success) |
607 return ASCIILiteralToV8String("127.0.0.1"); | 609 return ASCIILiteralToV8String("127.0.0.1"); |
608 return ASCIIStringToV8String(result); | 610 return ASCIIStringToV8String(result); |
609 } | 611 } |
610 | 612 |
611 // V8 callback for when "myIpAddressEx()" is invoked by the PAC script. | 613 // V8 callback for when "myIpAddressEx()" is invoked by the PAC script. |
612 static v8::Handle<v8::Value> MyIpAddressExCallback( | 614 static v8::Handle<v8::Value> MyIpAddressExCallback( |
613 const v8::Arguments& args) { | 615 const v8::Arguments& args) { |
614 Context* context = | 616 Context* context = |
615 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); | 617 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); |
616 | 618 |
617 std::string ip_address_list; | 619 std::string ip_address_list; |
618 bool success; | 620 bool success; |
619 | 621 |
620 { | 622 { |
621 v8::Unlocker unlocker; | 623 v8::Unlocker unlocker(args.GetIsolate()); |
622 ScopedHostResolve scoped_host_resolve(context); | 624 ScopedHostResolve scoped_host_resolve(context); |
623 | 625 |
624 // We shouldn't be called with any arguments, but will not complain if | 626 // We shouldn't be called with any arguments, but will not complain if |
625 // we are. | 627 // we are. |
626 success = context->js_bindings_->MyIpAddressEx(&ip_address_list); | 628 success = context->js_bindings_->MyIpAddressEx(&ip_address_list); |
627 } | 629 } |
628 | 630 |
629 if (!success) | 631 if (!success) |
630 ip_address_list = std::string(); | 632 ip_address_list = std::string(); |
631 return ASCIIStringToV8String(ip_address_list); | 633 return ASCIIStringToV8String(ip_address_list); |
632 } | 634 } |
633 | 635 |
634 // V8 callback for when "dnsResolve()" is invoked by the PAC script. | 636 // V8 callback for when "dnsResolve()" is invoked by the PAC script. |
635 static v8::Handle<v8::Value> DnsResolveCallback(const v8::Arguments& args) { | 637 static v8::Handle<v8::Value> DnsResolveCallback(const v8::Arguments& args) { |
636 Context* context = | 638 Context* context = |
637 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); | 639 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); |
638 | 640 |
639 // We need at least one string argument. | 641 // We need at least one string argument. |
640 std::string hostname; | 642 std::string hostname; |
641 if (!GetHostnameArgument(args, &hostname)) | 643 if (!GetHostnameArgument(args, &hostname)) |
642 return v8::Null(); | 644 return v8::Null(); |
643 | 645 |
644 std::string ip_address; | 646 std::string ip_address; |
645 bool success; | 647 bool success; |
646 | 648 |
647 { | 649 { |
648 v8::Unlocker unlocker; | 650 v8::Unlocker unlocker(args.GetIsolate()); |
649 ScopedHostResolve scoped_host_resolve(context); | 651 ScopedHostResolve scoped_host_resolve(context); |
650 success = context->js_bindings_->DnsResolve(hostname, &ip_address); | 652 success = context->js_bindings_->DnsResolve(hostname, &ip_address); |
651 } | 653 } |
652 | 654 |
653 return success ? ASCIIStringToV8String(ip_address) : v8::Null(); | 655 return success ? ASCIIStringToV8String(ip_address) : v8::Null(); |
654 } | 656 } |
655 | 657 |
656 // V8 callback for when "dnsResolveEx()" is invoked by the PAC script. | 658 // V8 callback for when "dnsResolveEx()" is invoked by the PAC script. |
657 static v8::Handle<v8::Value> DnsResolveExCallback(const v8::Arguments& args) { | 659 static v8::Handle<v8::Value> DnsResolveExCallback(const v8::Arguments& args) { |
658 Context* context = | 660 Context* context = |
659 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); | 661 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); |
660 | 662 |
661 // We need at least one string argument. | 663 // We need at least one string argument. |
662 std::string hostname; | 664 std::string hostname; |
663 if (!GetHostnameArgument(args, &hostname)) | 665 if (!GetHostnameArgument(args, &hostname)) |
664 return v8::Undefined(); | 666 return v8::Undefined(); |
665 | 667 |
666 std::string ip_address_list; | 668 std::string ip_address_list; |
667 bool success; | 669 bool success; |
668 | 670 |
669 { | 671 { |
670 v8::Unlocker unlocker; | 672 v8::Unlocker unlocker(args.GetIsolate()); |
671 ScopedHostResolve scoped_host_resolve(context); | 673 ScopedHostResolve scoped_host_resolve(context); |
672 success = context->js_bindings_->DnsResolveEx(hostname, &ip_address_list); | 674 success = context->js_bindings_->DnsResolveEx(hostname, &ip_address_list); |
673 } | 675 } |
674 | 676 |
675 if (!success) | 677 if (!success) |
676 ip_address_list = std::string(); | 678 ip_address_list = std::string(); |
677 | 679 |
678 return ASCIIStringToV8String(ip_address_list); | 680 return ASCIIStringToV8String(ip_address_list); |
679 } | 681 } |
680 | 682 |
(...skipping 26 matching lines...) Expand all Loading... | |
707 return v8::False(); | 709 return v8::False(); |
708 std::string ip_prefix = V8StringToUTF8(args[1]->ToString()); | 710 std::string ip_prefix = V8StringToUTF8(args[1]->ToString()); |
709 if (!IsStringASCII(ip_prefix)) | 711 if (!IsStringASCII(ip_prefix)) |
710 return v8::False(); | 712 return v8::False(); |
711 return IsInNetEx(ip_address, ip_prefix) ? v8::True() : v8::False(); | 713 return IsInNetEx(ip_address, ip_prefix) ? v8::True() : v8::False(); |
712 } | 714 } |
713 | 715 |
714 mutable base::Lock lock_; | 716 mutable base::Lock lock_; |
715 bool is_resolving_host_; | 717 bool is_resolving_host_; |
716 ProxyResolverJSBindings* js_bindings_; | 718 ProxyResolverJSBindings* js_bindings_; |
719 v8::Isolate* v8_default_isolate_; | |
717 v8::Persistent<v8::External> v8_this_; | 720 v8::Persistent<v8::External> v8_this_; |
718 v8::Persistent<v8::Context> v8_context_; | 721 v8::Persistent<v8::Context> v8_context_; |
719 }; | 722 }; |
720 | 723 |
721 // ProxyResolverV8 ------------------------------------------------------------ | 724 // ProxyResolverV8 ------------------------------------------------------------ |
722 | 725 |
723 ProxyResolverV8::ProxyResolverV8( | 726 ProxyResolverV8::ProxyResolverV8( |
724 ProxyResolverJSBindings* custom_js_bindings) | 727 ProxyResolverJSBindings* custom_js_bindings, |
728 v8::Isolate* v8_default_isolate) | |
725 : ProxyResolver(true /*expects_pac_bytes*/), | 729 : ProxyResolver(true /*expects_pac_bytes*/), |
726 js_bindings_(custom_js_bindings) { | 730 js_bindings_(custom_js_bindings), |
731 v8_default_isolate_(v8_default_isolate) { | |
727 } | 732 } |
728 | 733 |
729 ProxyResolverV8::~ProxyResolverV8() {} | 734 ProxyResolverV8::~ProxyResolverV8() {} |
730 | 735 |
731 int ProxyResolverV8::GetProxyForURL( | 736 int ProxyResolverV8::GetProxyForURL( |
732 const GURL& query_url, ProxyInfo* results, | 737 const GURL& query_url, ProxyInfo* results, |
733 const CompletionCallback& /*callback*/, | 738 const CompletionCallback& /*callback*/, |
734 RequestHandle* /*request*/, | 739 RequestHandle* /*request*/, |
735 const BoundNetLog& net_log) { | 740 const BoundNetLog& net_log) { |
736 // If the V8 instance has not been initialized (either because | 741 // If the V8 instance has not been initialized (either because |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
787 | 792 |
788 int ProxyResolverV8::SetPacScript( | 793 int ProxyResolverV8::SetPacScript( |
789 const scoped_refptr<ProxyResolverScriptData>& script_data, | 794 const scoped_refptr<ProxyResolverScriptData>& script_data, |
790 const CompletionCallback& /*callback*/) { | 795 const CompletionCallback& /*callback*/) { |
791 DCHECK(script_data.get()); | 796 DCHECK(script_data.get()); |
792 context_.reset(); | 797 context_.reset(); |
793 if (script_data->utf16().empty()) | 798 if (script_data->utf16().empty()) |
794 return ERR_PAC_SCRIPT_FAILED; | 799 return ERR_PAC_SCRIPT_FAILED; |
795 | 800 |
796 // Try parsing the PAC script. | 801 // Try parsing the PAC script. |
797 scoped_ptr<Context> context(new Context(js_bindings_.get())); | 802 scoped_ptr<Context> context(new Context(js_bindings_.get(), |
803 v8_default_isolate_)); | |
798 int rv = context->InitV8(script_data); | 804 int rv = context->InitV8(script_data); |
799 if (rv == OK) | 805 if (rv == OK) |
800 context_.reset(context.release()); | 806 context_.reset(context.release()); |
801 return rv; | 807 return rv; |
802 } | 808 } |
803 | 809 |
804 } // namespace net | 810 } // namespace net |
OLD | NEW |