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" |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/string_tokenizer.h" | 13 #include "base/string_tokenizer.h" |
14 #include "base/string_util.h" | 14 #include "base/string_util.h" |
15 #include "base/synchronization/lock.h" | 15 #include "base/synchronization/lock.h" |
16 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
17 #include "googleurl/src/gurl.h" | 17 #include "googleurl/src/gurl.h" |
18 #include "googleurl/src/url_canon.h" | 18 #include "googleurl/src/url_canon.h" |
19 #include "net/base/host_cache.h" | |
20 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
21 #include "net/base/net_log.h" | 20 #include "net/base/net_log.h" |
22 #include "net/base/net_util.h" | 21 #include "net/base/net_util.h" |
23 #include "net/proxy/proxy_info.h" | 22 #include "net/proxy/proxy_info.h" |
24 #include "net/proxy/proxy_resolver_js_bindings.h" | |
25 #include "net/proxy/proxy_resolver_request_context.h" | |
26 #include "net/proxy/proxy_resolver_script.h" | 23 #include "net/proxy/proxy_resolver_script.h" |
27 #include "v8/include/v8.h" | 24 #include "v8/include/v8.h" |
28 | 25 |
29 // Notes on the javascript environment: | 26 // Notes on the javascript environment: |
30 // | 27 // |
31 // For the majority of the PAC utility functions, we use the same code | 28 // For the majority of the PAC utility functions, we use the same code |
32 // as Firefox. See the javascript library that proxy_resolver_scipt.h | 29 // as Firefox. See the javascript library that proxy_resolver_scipt.h |
33 // pulls in. | 30 // pulls in. |
34 // | 31 // |
35 // In addition, we implement a subset of Microsoft's extensions to PAC. | 32 // In addition, we implement a subset of Microsoft's extensions to PAC. |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 | 325 |
329 return IPNumberMatchesPrefix(address, prefix, prefix_length_in_bits); | 326 return IPNumberMatchesPrefix(address, prefix, prefix_length_in_bits); |
330 } | 327 } |
331 | 328 |
332 } // namespace | 329 } // namespace |
333 | 330 |
334 // ProxyResolverV8::Context --------------------------------------------------- | 331 // ProxyResolverV8::Context --------------------------------------------------- |
335 | 332 |
336 class ProxyResolverV8::Context { | 333 class ProxyResolverV8::Context { |
337 public: | 334 public: |
338 explicit Context(ProxyResolverJSBindings* js_bindings) | 335 explicit Context(ProxyResolverV8* parent) |
339 : is_resolving_host_(false), | 336 : parent_(parent) { |
340 js_bindings_(js_bindings) { | |
341 DCHECK(js_bindings != NULL); | |
342 } | 337 } |
343 | 338 |
344 ~Context() { | 339 ~Context() { |
345 v8::Locker locked; | 340 v8::Locker locked; |
346 | 341 |
347 v8_this_.Dispose(); | 342 v8_this_.Dispose(); |
348 v8_context_.Dispose(); | 343 v8_context_.Dispose(); |
349 | 344 |
350 // Run the V8 garbage collector. We do this to be sure the | 345 // Run the V8 garbage collector. We do this to be sure the |
351 // ExternalStringResource objects we allocated get properly disposed. | 346 // ExternalStringResource objects we allocated get properly disposed. |
352 // Otherwise when running the unit-tests they may get leaked. | 347 // Otherwise when running the unit-tests they may get leaked. |
353 // See crbug.com/48145. | 348 // See crbug.com/48145. |
354 PurgeMemory(); | 349 PurgeMemory(); |
355 } | 350 } |
356 | 351 |
| 352 JSBindings* js_bindings() { |
| 353 return parent_->js_bindings_; |
| 354 } |
| 355 |
357 int ResolveProxy(const GURL& query_url, ProxyInfo* results) { | 356 int ResolveProxy(const GURL& query_url, ProxyInfo* results) { |
358 v8::Locker locked; | 357 v8::Locker locked; |
359 v8::HandleScope scope; | 358 v8::HandleScope scope; |
360 | 359 |
361 v8::Context::Scope function_scope(v8_context_); | 360 v8::Context::Scope function_scope(v8_context_); |
362 | 361 |
363 v8::Local<v8::Value> function; | 362 v8::Local<v8::Value> function; |
364 if (!GetFindProxyForURL(&function)) { | 363 if (!GetFindProxyForURL(&function)) { |
365 js_bindings_->OnError( | 364 js_bindings()->OnError( |
366 -1, ASCIIToUTF16("FindProxyForURL() is undefined.")); | 365 -1, ASCIIToUTF16("FindProxyForURL() is undefined.")); |
367 return ERR_PAC_SCRIPT_FAILED; | 366 return ERR_PAC_SCRIPT_FAILED; |
368 } | 367 } |
369 | 368 |
370 v8::Handle<v8::Value> argv[] = { | 369 v8::Handle<v8::Value> argv[] = { |
371 ASCIIStringToV8String(query_url.spec()), | 370 ASCIIStringToV8String(query_url.spec()), |
372 ASCIIStringToV8String(query_url.HostNoBrackets()), | 371 ASCIIStringToV8String(query_url.HostNoBrackets()), |
373 }; | 372 }; |
374 | 373 |
375 v8::TryCatch try_catch; | 374 v8::TryCatch try_catch; |
376 v8::Local<v8::Value> ret = v8::Function::Cast(*function)->Call( | 375 v8::Local<v8::Value> ret = v8::Function::Cast(*function)->Call( |
377 v8_context_->Global(), arraysize(argv), argv); | 376 v8_context_->Global(), arraysize(argv), argv); |
378 | 377 |
379 if (try_catch.HasCaught()) { | 378 if (try_catch.HasCaught()) { |
380 HandleError(try_catch.Message()); | 379 HandleError(try_catch.Message()); |
381 return ERR_PAC_SCRIPT_FAILED; | 380 return ERR_PAC_SCRIPT_FAILED; |
382 } | 381 } |
383 | 382 |
384 if (!ret->IsString()) { | 383 if (!ret->IsString()) { |
385 js_bindings_->OnError( | 384 js_bindings()->OnError( |
386 -1, ASCIIToUTF16("FindProxyForURL() did not return a string.")); | 385 -1, ASCIIToUTF16("FindProxyForURL() did not return a string.")); |
387 return ERR_PAC_SCRIPT_FAILED; | 386 return ERR_PAC_SCRIPT_FAILED; |
388 } | 387 } |
389 | 388 |
390 string16 ret_str = V8StringToUTF16(ret->ToString()); | 389 string16 ret_str = V8StringToUTF16(ret->ToString()); |
391 | 390 |
392 if (!IsStringASCII(ret_str)) { | 391 if (!IsStringASCII(ret_str)) { |
393 // TODO(eroman): Rather than failing when a wide string is returned, we | 392 // TODO(eroman): Rather than failing when a wide string is returned, we |
394 // could extend the parsing to handle IDNA hostnames by | 393 // could extend the parsing to handle IDNA hostnames by |
395 // converting them to ASCII punycode. | 394 // converting them to ASCII punycode. |
396 // crbug.com/47234 | 395 // crbug.com/47234 |
397 string16 error_message = | 396 string16 error_message = |
398 ASCIIToUTF16("FindProxyForURL() returned a non-ASCII string " | 397 ASCIIToUTF16("FindProxyForURL() returned a non-ASCII string " |
399 "(crbug.com/47234): ") + ret_str; | 398 "(crbug.com/47234): ") + ret_str; |
400 js_bindings_->OnError(-1, error_message); | 399 js_bindings()->OnError(-1, error_message); |
401 return ERR_PAC_SCRIPT_FAILED; | 400 return ERR_PAC_SCRIPT_FAILED; |
402 } | 401 } |
403 | 402 |
404 results->UsePacString(UTF16ToASCII(ret_str)); | 403 results->UsePacString(UTF16ToASCII(ret_str)); |
405 return OK; | 404 return OK; |
406 } | 405 } |
407 | 406 |
408 int InitV8(const scoped_refptr<ProxyResolverScriptData>& pac_script) { | 407 int InitV8(const scoped_refptr<ProxyResolverScriptData>& pac_script) { |
409 v8::Locker locked; | 408 v8::Locker locked; |
410 v8::HandleScope scope; | 409 v8::HandleScope scope; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 | 467 |
469 // Add the user's PAC code to the environment. | 468 // Add the user's PAC code to the environment. |
470 rv = RunScript(ScriptDataToV8String(pac_script), kPacResourceName); | 469 rv = RunScript(ScriptDataToV8String(pac_script), kPacResourceName); |
471 if (rv != OK) | 470 if (rv != OK) |
472 return rv; | 471 return rv; |
473 | 472 |
474 // At a minimum, the FindProxyForURL() function must be defined for this | 473 // At a minimum, the FindProxyForURL() function must be defined for this |
475 // to be a legitimiate PAC script. | 474 // to be a legitimiate PAC script. |
476 v8::Local<v8::Value> function; | 475 v8::Local<v8::Value> function; |
477 if (!GetFindProxyForURL(&function)) { | 476 if (!GetFindProxyForURL(&function)) { |
478 js_bindings_->OnError( | 477 js_bindings()->OnError( |
479 -1, ASCIIToUTF16("FindProxyForURL() is undefined.")); | 478 -1, ASCIIToUTF16("FindProxyForURL() is undefined.")); |
480 return ERR_PAC_SCRIPT_FAILED; | 479 return ERR_PAC_SCRIPT_FAILED; |
481 } | 480 } |
482 | 481 |
483 return OK; | 482 return OK; |
484 } | 483 } |
485 | 484 |
486 void SetCurrentRequestContext(ProxyResolverRequestContext* context) { | |
487 js_bindings_->set_current_request_context(context); | |
488 } | |
489 | |
490 void PurgeMemory() { | 485 void PurgeMemory() { |
491 v8::Locker locked; | 486 v8::Locker locked; |
492 v8::V8::LowMemoryNotification(); | 487 v8::V8::LowMemoryNotification(); |
493 } | 488 } |
494 | 489 |
495 bool is_resolving_host() const { | |
496 base::AutoLock auto_lock(lock_); | |
497 return is_resolving_host_; | |
498 } | |
499 | |
500 private: | 490 private: |
501 class ScopedHostResolve { | |
502 public: | |
503 explicit ScopedHostResolve(Context* context) | |
504 : context_(context) { | |
505 context_->BeginHostResolve(); | |
506 } | |
507 | |
508 ~ScopedHostResolve() { | |
509 context_->EndHostResolve(); | |
510 } | |
511 | |
512 private: | |
513 Context* const context_; | |
514 DISALLOW_COPY_AND_ASSIGN(ScopedHostResolve); | |
515 }; | |
516 | |
517 void BeginHostResolve() { | |
518 base::AutoLock auto_lock(lock_); | |
519 DCHECK(!is_resolving_host_); | |
520 is_resolving_host_ = true; | |
521 } | |
522 | |
523 void EndHostResolve() { | |
524 base::AutoLock auto_lock(lock_); | |
525 DCHECK(is_resolving_host_); | |
526 is_resolving_host_ = false; | |
527 } | |
528 | |
529 bool GetFindProxyForURL(v8::Local<v8::Value>* function) { | 491 bool GetFindProxyForURL(v8::Local<v8::Value>* function) { |
530 *function = v8_context_->Global()->Get( | 492 *function = v8_context_->Global()->Get( |
531 ASCIILiteralToV8String("FindProxyForURL")); | 493 ASCIILiteralToV8String("FindProxyForURL")); |
532 return (*function)->IsFunction(); | 494 return (*function)->IsFunction(); |
533 } | 495 } |
534 | 496 |
535 // Handle an exception thrown by V8. | 497 // Handle an exception thrown by V8. |
536 void HandleError(v8::Handle<v8::Message> message) { | 498 void HandleError(v8::Handle<v8::Message> message) { |
537 if (message.IsEmpty()) | 499 if (message.IsEmpty()) |
538 return; | 500 return; |
539 | 501 |
540 // Otherwise dispatch to the bindings. | 502 // Otherwise dispatch to the bindings. |
541 int line_number = message->GetLineNumber(); | 503 int line_number = message->GetLineNumber(); |
542 string16 error_message; | 504 string16 error_message; |
543 V8ObjectToUTF16String(message->Get(), &error_message); | 505 V8ObjectToUTF16String(message->Get(), &error_message); |
544 js_bindings_->OnError(line_number, error_message); | 506 js_bindings()->OnError(line_number, error_message); |
545 } | 507 } |
546 | 508 |
547 // Compiles and runs |script| in the current V8 context. | 509 // Compiles and runs |script| in the current V8 context. |
548 // Returns OK on success, otherwise an error code. | 510 // Returns OK on success, otherwise an error code. |
549 int RunScript(v8::Handle<v8::String> script, const char* script_name) { | 511 int RunScript(v8::Handle<v8::String> script, const char* script_name) { |
550 v8::TryCatch try_catch; | 512 v8::TryCatch try_catch; |
551 | 513 |
552 // Compile the script. | 514 // Compile the script. |
553 v8::ScriptOrigin origin = | 515 v8::ScriptOrigin origin = |
554 v8::ScriptOrigin(ASCIILiteralToV8String(script_name)); | 516 v8::ScriptOrigin(ASCIILiteralToV8String(script_name)); |
(...skipping 20 matching lines...) Expand all Loading... |
575 // Like firefox we assume "undefined" if no argument was specified, and | 537 // Like firefox we assume "undefined" if no argument was specified, and |
576 // disregard any arguments beyond the first. | 538 // disregard any arguments beyond the first. |
577 string16 message; | 539 string16 message; |
578 if (args.Length() == 0) { | 540 if (args.Length() == 0) { |
579 message = ASCIIToUTF16("undefined"); | 541 message = ASCIIToUTF16("undefined"); |
580 } else { | 542 } else { |
581 if (!V8ObjectToUTF16String(args[0], &message)) | 543 if (!V8ObjectToUTF16String(args[0], &message)) |
582 return v8::Undefined(); // toString() threw an exception. | 544 return v8::Undefined(); // toString() threw an exception. |
583 } | 545 } |
584 | 546 |
585 context->js_bindings_->Alert(message); | 547 context->js_bindings()->Alert(message); |
586 return v8::Undefined(); | 548 return v8::Undefined(); |
587 } | 549 } |
588 | 550 |
589 // V8 callback for when "myIpAddress()" is invoked by the PAC script. | 551 // V8 callback for when "myIpAddress()" is invoked by the PAC script. |
590 static v8::Handle<v8::Value> MyIpAddressCallback(const v8::Arguments& args) { | 552 static v8::Handle<v8::Value> MyIpAddressCallback(const v8::Arguments& args) { |
591 Context* context = | 553 Context* context = |
592 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); | 554 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); |
593 | 555 |
594 std::string result; | 556 std::string result; |
595 bool success; | 557 bool success; |
596 | 558 |
597 { | 559 { |
598 v8::Unlocker unlocker; | 560 v8::Unlocker unlocker; |
599 ScopedHostResolve scoped_host_resolve(context); | |
600 | 561 |
601 // We shouldn't be called with any arguments, but will not complain if | 562 // We shouldn't be called with any arguments, but will not complain if |
602 // we are. | 563 // we are. |
603 success = context->js_bindings_->MyIpAddress(&result); | 564 success = context->js_bindings()->ResolveDns( |
| 565 "", JSBindings::MY_IP_ADDRESS, &result); |
604 } | 566 } |
605 | 567 |
606 if (!success) | 568 if (!success) |
607 return ASCIILiteralToV8String("127.0.0.1"); | 569 return ASCIILiteralToV8String("127.0.0.1"); |
608 return ASCIIStringToV8String(result); | 570 return ASCIIStringToV8String(result); |
609 } | 571 } |
610 | 572 |
611 // V8 callback for when "myIpAddressEx()" is invoked by the PAC script. | 573 // V8 callback for when "myIpAddressEx()" is invoked by the PAC script. |
612 static v8::Handle<v8::Value> MyIpAddressExCallback( | 574 static v8::Handle<v8::Value> MyIpAddressExCallback( |
613 const v8::Arguments& args) { | 575 const v8::Arguments& args) { |
614 Context* context = | 576 Context* context = |
615 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); | 577 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); |
616 | 578 |
617 std::string ip_address_list; | 579 std::string ip_address_list; |
618 bool success; | 580 bool success; |
619 | 581 |
620 { | 582 { |
621 v8::Unlocker unlocker; | 583 v8::Unlocker unlocker; |
622 ScopedHostResolve scoped_host_resolve(context); | |
623 | |
624 // We shouldn't be called with any arguments, but will not complain if | 584 // We shouldn't be called with any arguments, but will not complain if |
625 // we are. | 585 // we are. |
626 success = context->js_bindings_->MyIpAddressEx(&ip_address_list); | 586 success = context->js_bindings()->ResolveDns( |
| 587 "", JSBindings::MY_IP_ADDRESS_EX, &ip_address_list); |
627 } | 588 } |
628 | 589 |
629 if (!success) | 590 if (!success) |
630 ip_address_list = std::string(); | 591 ip_address_list = std::string(); |
631 return ASCIIStringToV8String(ip_address_list); | 592 return ASCIIStringToV8String(ip_address_list); |
632 } | 593 } |
633 | 594 |
634 // V8 callback for when "dnsResolve()" is invoked by the PAC script. | 595 // V8 callback for when "dnsResolve()" is invoked by the PAC script. |
635 static v8::Handle<v8::Value> DnsResolveCallback(const v8::Arguments& args) { | 596 static v8::Handle<v8::Value> DnsResolveCallback(const v8::Arguments& args) { |
636 Context* context = | 597 Context* context = |
637 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); | 598 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); |
638 | 599 |
639 // We need at least one string argument. | 600 // We need at least one string argument. |
640 std::string hostname; | 601 std::string hostname; |
641 if (!GetHostnameArgument(args, &hostname)) | 602 if (!GetHostnameArgument(args, &hostname)) |
642 return v8::Null(); | 603 return v8::Null(); |
643 | 604 |
644 std::string ip_address; | 605 std::string ip_address; |
645 bool success; | 606 bool success; |
646 | 607 |
647 { | 608 { |
648 v8::Unlocker unlocker; | 609 v8::Unlocker unlocker; |
649 ScopedHostResolve scoped_host_resolve(context); | 610 success = context->js_bindings()->ResolveDns( |
650 success = context->js_bindings_->DnsResolve(hostname, &ip_address); | 611 hostname, JSBindings::DNS_RESOLVE, &ip_address); |
651 } | 612 } |
652 | 613 |
653 return success ? ASCIIStringToV8String(ip_address) : v8::Null(); | 614 return success ? ASCIIStringToV8String(ip_address) : v8::Null(); |
654 } | 615 } |
655 | 616 |
656 // V8 callback for when "dnsResolveEx()" is invoked by the PAC script. | 617 // V8 callback for when "dnsResolveEx()" is invoked by the PAC script. |
657 static v8::Handle<v8::Value> DnsResolveExCallback(const v8::Arguments& args) { | 618 static v8::Handle<v8::Value> DnsResolveExCallback(const v8::Arguments& args) { |
658 Context* context = | 619 Context* context = |
659 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); | 620 static_cast<Context*>(v8::External::Cast(*args.Data())->Value()); |
660 | 621 |
661 // We need at least one string argument. | 622 // We need at least one string argument. |
662 std::string hostname; | 623 std::string hostname; |
663 if (!GetHostnameArgument(args, &hostname)) | 624 if (!GetHostnameArgument(args, &hostname)) |
664 return v8::Undefined(); | 625 return v8::Undefined(); |
665 | 626 |
666 std::string ip_address_list; | 627 std::string ip_address_list; |
667 bool success; | 628 bool success; |
668 | 629 |
669 { | 630 { |
670 v8::Unlocker unlocker; | 631 v8::Unlocker unlocker; |
671 ScopedHostResolve scoped_host_resolve(context); | 632 success = context->js_bindings()->ResolveDns( |
672 success = context->js_bindings_->DnsResolveEx(hostname, &ip_address_list); | 633 hostname, JSBindings::DNS_RESOLVE_EX, &ip_address_list); |
673 } | 634 } |
674 | 635 |
675 if (!success) | 636 if (!success) |
676 ip_address_list = std::string(); | 637 ip_address_list = std::string(); |
677 | 638 |
678 return ASCIIStringToV8String(ip_address_list); | 639 return ASCIIStringToV8String(ip_address_list); |
679 } | 640 } |
680 | 641 |
681 // V8 callback for when "sortIpAddressList()" is invoked by the PAC script. | 642 // V8 callback for when "sortIpAddressList()" is invoked by the PAC script. |
682 static v8::Handle<v8::Value> SortIpAddressListCallback( | 643 static v8::Handle<v8::Value> SortIpAddressListCallback( |
(...skipping 22 matching lines...) Expand all Loading... |
705 std::string ip_address = V8StringToUTF8(args[0]->ToString()); | 666 std::string ip_address = V8StringToUTF8(args[0]->ToString()); |
706 if (!IsStringASCII(ip_address)) | 667 if (!IsStringASCII(ip_address)) |
707 return v8::False(); | 668 return v8::False(); |
708 std::string ip_prefix = V8StringToUTF8(args[1]->ToString()); | 669 std::string ip_prefix = V8StringToUTF8(args[1]->ToString()); |
709 if (!IsStringASCII(ip_prefix)) | 670 if (!IsStringASCII(ip_prefix)) |
710 return v8::False(); | 671 return v8::False(); |
711 return IsInNetEx(ip_address, ip_prefix) ? v8::True() : v8::False(); | 672 return IsInNetEx(ip_address, ip_prefix) ? v8::True() : v8::False(); |
712 } | 673 } |
713 | 674 |
714 mutable base::Lock lock_; | 675 mutable base::Lock lock_; |
715 bool is_resolving_host_; | 676 ProxyResolverV8* parent_; |
716 ProxyResolverJSBindings* js_bindings_; | |
717 v8::Persistent<v8::External> v8_this_; | 677 v8::Persistent<v8::External> v8_this_; |
718 v8::Persistent<v8::Context> v8_context_; | 678 v8::Persistent<v8::Context> v8_context_; |
719 }; | 679 }; |
720 | 680 |
721 // ProxyResolverV8 ------------------------------------------------------------ | 681 // ProxyResolverV8 ------------------------------------------------------------ |
722 | 682 |
723 ProxyResolverV8::ProxyResolverV8( | 683 ProxyResolverV8::ProxyResolverV8() |
724 ProxyResolverJSBindings* custom_js_bindings) | |
725 : ProxyResolver(true /*expects_pac_bytes*/), | 684 : ProxyResolver(true /*expects_pac_bytes*/), |
726 js_bindings_(custom_js_bindings) { | 685 js_bindings_(NULL) { |
727 } | 686 } |
728 | 687 |
729 ProxyResolverV8::~ProxyResolverV8() {} | 688 ProxyResolverV8::~ProxyResolverV8() {} |
730 | 689 |
731 int ProxyResolverV8::GetProxyForURL( | 690 int ProxyResolverV8::GetProxyForURL( |
732 const GURL& query_url, ProxyInfo* results, | 691 const GURL& query_url, ProxyInfo* results, |
733 const CompletionCallback& /*callback*/, | 692 const CompletionCallback& /*callback*/, |
734 RequestHandle* /*request*/, | 693 RequestHandle* /*request*/, |
735 const BoundNetLog& net_log) { | 694 const BoundNetLog& net_log) { |
736 // If the V8 instance has not been initialized (either because | 695 // If the V8 instance has not been initialized (either because |
737 // SetPacScript() wasn't called yet, or because it failed. | 696 // SetPacScript() wasn't called yet, or because it failed. |
738 if (!context_.get()) | 697 if (!context_.get()) |
739 return ERR_FAILED; | 698 return ERR_FAILED; |
740 | 699 |
741 // Associate some short-lived context with this request. This context will be | |
742 // available to any of the javascript "bindings" that are subsequently invoked | |
743 // from the javascript. | |
744 // | |
745 // In particular, we create a HostCache to aggressively cache failed DNS | |
746 // resolves. | |
747 const unsigned kMaxCacheEntries = 50; | |
748 HostCache host_cache(kMaxCacheEntries); | |
749 | |
750 ProxyResolverRequestContext request_context(&net_log, &host_cache); | |
751 | |
752 // Otherwise call into V8. | 700 // Otherwise call into V8. |
753 context_->SetCurrentRequestContext(&request_context); | |
754 int rv = context_->ResolveProxy(query_url, results); | 701 int rv = context_->ResolveProxy(query_url, results); |
755 context_->SetCurrentRequestContext(NULL); | |
756 | 702 |
757 return rv; | 703 return rv; |
758 } | 704 } |
759 | 705 |
760 void ProxyResolverV8::CancelRequest(RequestHandle request) { | 706 void ProxyResolverV8::CancelRequest(RequestHandle request) { |
761 // This is a synchronous ProxyResolver; no possibility for async requests. | 707 // This is a synchronous ProxyResolver; no possibility for async requests. |
762 NOTREACHED(); | 708 NOTREACHED(); |
763 } | 709 } |
764 | 710 |
765 LoadState ProxyResolverV8::GetLoadState(RequestHandle request) const { | 711 LoadState ProxyResolverV8::GetLoadState(RequestHandle request) const { |
766 NOTREACHED(); | 712 NOTREACHED(); |
767 return LOAD_STATE_IDLE; | 713 return LOAD_STATE_IDLE; |
768 } | 714 } |
769 | 715 |
770 LoadState ProxyResolverV8::GetLoadStateThreadSafe(RequestHandle request) const { | |
771 if (context_->is_resolving_host()) | |
772 return LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT; | |
773 return LOAD_STATE_RESOLVING_PROXY_FOR_URL; | |
774 } | |
775 | |
776 void ProxyResolverV8::CancelSetPacScript() { | 716 void ProxyResolverV8::CancelSetPacScript() { |
777 NOTREACHED(); | 717 NOTREACHED(); |
778 } | 718 } |
779 | 719 |
780 void ProxyResolverV8::PurgeMemory() { | 720 void ProxyResolverV8::PurgeMemory() { |
781 context_->PurgeMemory(); | 721 context_->PurgeMemory(); |
782 } | 722 } |
783 | 723 |
784 void ProxyResolverV8::Shutdown() { | |
785 js_bindings_->Shutdown(); | |
786 } | |
787 | |
788 int ProxyResolverV8::SetPacScript( | 724 int ProxyResolverV8::SetPacScript( |
789 const scoped_refptr<ProxyResolverScriptData>& script_data, | 725 const scoped_refptr<ProxyResolverScriptData>& script_data, |
790 const CompletionCallback& /*callback*/) { | 726 const CompletionCallback& /*callback*/) { |
791 DCHECK(script_data.get()); | 727 DCHECK(script_data.get()); |
792 context_.reset(); | 728 context_.reset(); |
793 if (script_data->utf16().empty()) | 729 if (script_data->utf16().empty()) |
794 return ERR_PAC_SCRIPT_FAILED; | 730 return ERR_PAC_SCRIPT_FAILED; |
795 | 731 |
796 // Try parsing the PAC script. | 732 // Try parsing the PAC script. |
797 scoped_ptr<Context> context(new Context(js_bindings_.get())); | 733 scoped_ptr<Context> context(new Context(this)); |
798 int rv = context->InitV8(script_data); | 734 int rv = context->InitV8(script_data); |
799 if (rv == OK) | 735 if (rv == OK) |
800 context_.reset(context.release()); | 736 context_.reset(context.release()); |
801 return rv; | 737 return rv; |
802 } | 738 } |
803 | 739 |
804 } // namespace net | 740 } // namespace net |
OLD | NEW |