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