Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1004)

Unified Diff: net/proxy/proxy_resolver_v8.cc

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/proxy/proxy_resolver_v8.h ('k') | net/proxy/proxy_resolver_v8_tracing.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/proxy/proxy_resolver_v8.cc
diff --git a/net/proxy/proxy_resolver_v8.cc b/net/proxy/proxy_resolver_v8.cc
deleted file mode 100644
index 693fbb24837ff84b01f7ffd4bd5018c6e3b77944..0000000000000000000000000000000000000000
--- a/net/proxy/proxy_resolver_v8.cc
+++ /dev/null
@@ -1,842 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/proxy/proxy_resolver_v8.h"
-
-#include <algorithm>
-#include <cstdio>
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/debug/leak_annotations.h"
-#include "base/logging.h"
-#include "base/strings/string_tokenizer.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/synchronization/lock.h"
-#include "gin/array_buffer.h"
-#include "gin/public/isolate_holder.h"
-#include "net/base/net_errors.h"
-#include "net/base/net_log.h"
-#include "net/base/net_util.h"
-#include "net/proxy/proxy_info.h"
-#include "net/proxy/proxy_resolver_script.h"
-#include "url/gurl.h"
-#include "url/url_canon.h"
-#include "v8/include/v8.h"
-
-// Notes on the javascript environment:
-//
-// For the majority of the PAC utility functions, we use the same code
-// as Firefox. See the javascript library that proxy_resolver_scipt.h
-// pulls in.
-//
-// In addition, we implement a subset of Microsoft's extensions to PAC.
-// - myIpAddressEx()
-// - dnsResolveEx()
-// - isResolvableEx()
-// - isInNetEx()
-// - sortIpAddressList()
-//
-// It is worth noting that the original PAC specification does not describe
-// the return values on failure. Consequently, there are compatibility
-// differences between browsers on what to return on failure, which are
-// illustrated below:
-//
-// --------------------+-------------+-------------------+--------------
-// | Firefox3 | InternetExplorer8 | --> Us <---
-// --------------------+-------------+-------------------+--------------
-// myIpAddress() | "127.0.0.1" | ??? | "127.0.0.1"
-// dnsResolve() | null | false | null
-// myIpAddressEx() | N/A | "" | ""
-// sortIpAddressList() | N/A | false | false
-// dnsResolveEx() | N/A | "" | ""
-// isInNetEx() | N/A | false | false
-// --------------------+-------------+-------------------+--------------
-//
-// TODO(eroman): The cell above reading ??? means I didn't test it.
-//
-// Another difference is in how dnsResolve() and myIpAddress() are
-// implemented -- whether they should restrict to IPv4 results, or
-// include both IPv4 and IPv6. The following table illustrates the
-// differences:
-//
-// --------------------+-------------+-------------------+--------------
-// | Firefox3 | InternetExplorer8 | --> Us <---
-// --------------------+-------------+-------------------+--------------
-// myIpAddress() | IPv4/IPv6 | IPv4 | IPv4
-// dnsResolve() | IPv4/IPv6 | IPv4 | IPv4
-// isResolvable() | IPv4/IPv6 | IPv4 | IPv4
-// myIpAddressEx() | N/A | IPv4/IPv6 | IPv4/IPv6
-// dnsResolveEx() | N/A | IPv4/IPv6 | IPv4/IPv6
-// sortIpAddressList() | N/A | IPv4/IPv6 | IPv4/IPv6
-// isResolvableEx() | N/A | IPv4/IPv6 | IPv4/IPv6
-// isInNetEx() | N/A | IPv4/IPv6 | IPv4/IPv6
-// -----------------+-------------+-------------------+--------------
-
-namespace net {
-
-namespace {
-
-// Pseudo-name for the PAC script.
-const char kPacResourceName[] = "proxy-pac-script.js";
-// Pseudo-name for the PAC utility script.
-const char kPacUtilityResourceName[] = "proxy-pac-utility-script.js";
-
-// External string wrapper so V8 can access the UTF16 string wrapped by
-// ProxyResolverScriptData.
-class V8ExternalStringFromScriptData
- : public v8::String::ExternalStringResource {
- public:
- explicit V8ExternalStringFromScriptData(
- const scoped_refptr<ProxyResolverScriptData>& script_data)
- : script_data_(script_data) {}
-
- const uint16_t* data() const override {
- return reinterpret_cast<const uint16*>(script_data_->utf16().data());
- }
-
- size_t length() const override { return script_data_->utf16().size(); }
-
- private:
- const scoped_refptr<ProxyResolverScriptData> script_data_;
- DISALLOW_COPY_AND_ASSIGN(V8ExternalStringFromScriptData);
-};
-
-// External string wrapper so V8 can access a string literal.
-class V8ExternalASCIILiteral
- : public v8::String::ExternalOneByteStringResource {
- public:
- // |ascii| must be a NULL-terminated C string, and must remain valid
- // throughout this object's lifetime.
- V8ExternalASCIILiteral(const char* ascii, size_t length)
- : ascii_(ascii), length_(length) {
- DCHECK(base::IsStringASCII(ascii));
- }
-
- const char* data() const override { return ascii_; }
-
- size_t length() const override { return length_; }
-
- private:
- const char* ascii_;
- size_t length_;
- DISALLOW_COPY_AND_ASSIGN(V8ExternalASCIILiteral);
-};
-
-// When creating a v8::String from a C++ string we have two choices: create
-// a copy, or create a wrapper that shares the same underlying storage.
-// For small strings it is better to just make a copy, whereas for large
-// strings there are savings by sharing the storage. This number identifies
-// the cutoff length for when to start wrapping rather than creating copies.
-const size_t kMaxStringBytesForCopy = 256;
-
-// Converts a V8 String to a UTF8 std::string.
-std::string V8StringToUTF8(v8::Local<v8::String> s) {
- int len = s->Length();
- std::string result;
- if (len > 0)
- s->WriteUtf8(WriteInto(&result, len + 1));
- return result;
-}
-
-// Converts a V8 String to a UTF16 base::string16.
-base::string16 V8StringToUTF16(v8::Local<v8::String> s) {
- int len = s->Length();
- base::string16 result;
- // Note that the reinterpret cast is because on Windows string16 is an alias
- // to wstring, and hence has character type wchar_t not uint16_t.
- if (len > 0)
- s->Write(reinterpret_cast<uint16_t*>(WriteInto(&result, len + 1)), 0, len);
- return result;
-}
-
-// Converts an ASCII std::string to a V8 string.
-v8::Local<v8::String> ASCIIStringToV8String(v8::Isolate* isolate,
- const std::string& s) {
- DCHECK(base::IsStringASCII(s));
- return v8::String::NewFromUtf8(isolate, s.data(), v8::String::kNormalString,
- s.size());
-}
-
-// Converts a UTF16 base::string16 (warpped by a ProxyResolverScriptData) to a
-// V8 string.
-v8::Local<v8::String> ScriptDataToV8String(
- v8::Isolate* isolate, const scoped_refptr<ProxyResolverScriptData>& s) {
- if (s->utf16().size() * 2 <= kMaxStringBytesForCopy) {
- return v8::String::NewFromTwoByte(
- isolate,
- reinterpret_cast<const uint16_t*>(s->utf16().data()),
- v8::String::kNormalString,
- s->utf16().size());
- }
- return v8::String::NewExternal(isolate,
- new V8ExternalStringFromScriptData(s));
-}
-
-// Converts an ASCII string literal to a V8 string.
-v8::Local<v8::String> ASCIILiteralToV8String(v8::Isolate* isolate,
- const char* ascii) {
- DCHECK(base::IsStringASCII(ascii));
- size_t length = strlen(ascii);
- if (length <= kMaxStringBytesForCopy)
- return v8::String::NewFromUtf8(isolate, ascii, v8::String::kNormalString,
- length);
- return v8::String::NewExternal(isolate,
- new V8ExternalASCIILiteral(ascii, length));
-}
-
-// Stringizes a V8 object by calling its toString() method. Returns true
-// on success. This may fail if the toString() throws an exception.
-bool V8ObjectToUTF16String(v8::Local<v8::Value> object,
- base::string16* utf16_result,
- v8::Isolate* isolate) {
- if (object.IsEmpty())
- return false;
-
- v8::HandleScope scope(isolate);
- v8::Local<v8::String> str_object = object->ToString(isolate);
- if (str_object.IsEmpty())
- return false;
- *utf16_result = V8StringToUTF16(str_object);
- return true;
-}
-
-// Extracts an hostname argument from |args|. On success returns true
-// and fills |*hostname| with the result.
-bool GetHostnameArgument(const v8::FunctionCallbackInfo<v8::Value>& args,
- std::string* hostname) {
- // The first argument should be a string.
- if (args.Length() == 0 || args[0].IsEmpty() || !args[0]->IsString())
- return false;
-
- const base::string16 hostname_utf16 =
- V8StringToUTF16(v8::Local<v8::String>::Cast(args[0]));
-
- // If the hostname is already in ASCII, simply return it as is.
- if (base::IsStringASCII(hostname_utf16)) {
- *hostname = base::UTF16ToASCII(hostname_utf16);
- return true;
- }
-
- // Otherwise try to convert it from IDN to punycode.
- const int kInitialBufferSize = 256;
- url::RawCanonOutputT<base::char16, kInitialBufferSize> punycode_output;
- if (!url::IDNToASCII(hostname_utf16.data(), hostname_utf16.length(),
- &punycode_output)) {
- return false;
- }
-
- // |punycode_output| should now be ASCII; convert it to a std::string.
- // (We could use UTF16ToASCII() instead, but that requires an extra string
- // copy. Since ASCII is a subset of UTF8 the following is equivalent).
- bool success = base::UTF16ToUTF8(punycode_output.data(),
- punycode_output.length(),
- hostname);
- DCHECK(success);
- DCHECK(base::IsStringASCII(*hostname));
- return success;
-}
-
-// Wrapper for passing around IP address strings and IPAddressNumber objects.
-struct IPAddress {
- IPAddress(const std::string& ip_string, const IPAddressNumber& ip_number)
- : string_value(ip_string),
- ip_address_number(ip_number) {
- }
-
- // Used for sorting IP addresses in ascending order in SortIpAddressList().
- // IP6 addresses are placed ahead of IPv4 addresses.
- bool operator<(const IPAddress& rhs) const {
- const IPAddressNumber& ip1 = this->ip_address_number;
- const IPAddressNumber& ip2 = rhs.ip_address_number;
- if (ip1.size() != ip2.size())
- return ip1.size() > ip2.size(); // IPv6 before IPv4.
- DCHECK(ip1.size() == ip2.size());
- return memcmp(&ip1[0], &ip2[0], ip1.size()) < 0; // Ascending order.
- }
-
- std::string string_value;
- IPAddressNumber ip_address_number;
-};
-
-// Handler for "sortIpAddressList(IpAddressList)". |ip_address_list| is a
-// semi-colon delimited string containing IP addresses.
-// |sorted_ip_address_list| is the resulting list of sorted semi-colon delimited
-// IP addresses or an empty string if unable to sort the IP address list.
-// Returns 'true' if the sorting was successful, and 'false' if the input was an
-// empty string, a string of separators (";" in this case), or if any of the IP
-// addresses in the input list failed to parse.
-bool SortIpAddressList(const std::string& ip_address_list,
- std::string* sorted_ip_address_list) {
- sorted_ip_address_list->clear();
-
- // Strip all whitespace (mimics IE behavior).
- std::string cleaned_ip_address_list;
- base::RemoveChars(ip_address_list, " \t", &cleaned_ip_address_list);
- if (cleaned_ip_address_list.empty())
- return false;
-
- // Split-up IP addresses and store them in a vector.
- std::vector<IPAddress> ip_vector;
- IPAddressNumber ip_num;
- base::StringTokenizer str_tok(cleaned_ip_address_list, ";");
- while (str_tok.GetNext()) {
- if (!ParseIPLiteralToNumber(str_tok.token(), &ip_num))
- return false;
- ip_vector.push_back(IPAddress(str_tok.token(), ip_num));
- }
-
- if (ip_vector.empty()) // Can happen if we have something like
- return false; // sortIpAddressList(";") or sortIpAddressList("; ;")
-
- DCHECK(!ip_vector.empty());
-
- // Sort lists according to ascending numeric value.
- if (ip_vector.size() > 1)
- std::stable_sort(ip_vector.begin(), ip_vector.end());
-
- // Return a semi-colon delimited list of sorted addresses (IPv6 followed by
- // IPv4).
- for (size_t i = 0; i < ip_vector.size(); ++i) {
- if (i > 0)
- *sorted_ip_address_list += ";";
- *sorted_ip_address_list += ip_vector[i].string_value;
- }
- return true;
-}
-
-// Handler for "isInNetEx(ip_address, ip_prefix)". |ip_address| is a string
-// containing an IPv4/IPv6 address, and |ip_prefix| is a string containg a
-// slash-delimited IP prefix with the top 'n' bits specified in the bit
-// field. This returns 'true' if the address is in the same subnet, and
-// 'false' otherwise. Also returns 'false' if the prefix is in an incorrect
-// format, or if an address and prefix of different types are used (e.g. IPv6
-// address and IPv4 prefix).
-bool IsInNetEx(const std::string& ip_address, const std::string& ip_prefix) {
- IPAddressNumber address;
- if (!ParseIPLiteralToNumber(ip_address, &address))
- return false;
-
- IPAddressNumber prefix;
- size_t prefix_length_in_bits;
- if (!ParseCIDRBlock(ip_prefix, &prefix, &prefix_length_in_bits))
- return false;
-
- // Both |address| and |prefix| must be of the same type (IPv4 or IPv6).
- if (address.size() != prefix.size())
- return false;
-
- DCHECK((address.size() == 4 && prefix.size() == 4) ||
- (address.size() == 16 && prefix.size() == 16));
-
- return IPNumberMatchesPrefix(address, prefix, prefix_length_in_bits);
-}
-
-// Consider only single component domains like 'foo' as plain host names.
-bool IsPlainHostName(const std::string& hostname_utf8) {
- if (hostname_utf8.find('.') != std::string::npos)
- return false;
-
- // IPv6 literals might not contain any periods, however are not considered
- // plain host names.
- IPAddressNumber unused;
- return !ParseIPLiteralToNumber(hostname_utf8, &unused);
-}
-
-} // namespace
-
-// ProxyResolverV8::Context ---------------------------------------------------
-
-class ProxyResolverV8::Context {
- public:
- Context(ProxyResolverV8* parent, v8::Isolate* isolate)
- : parent_(parent),
- isolate_(isolate) {
- DCHECK(isolate);
- }
-
- ~Context() {
- v8::Locker locked(isolate_);
- v8::Isolate::Scope isolate_scope(isolate_);
-
- v8_this_.Reset();
- v8_context_.Reset();
- }
-
- JSBindings* js_bindings() {
- return parent_->js_bindings_;
- }
-
- int ResolveProxy(const GURL& query_url, ProxyInfo* results) {
- v8::Locker locked(isolate_);
- v8::Isolate::Scope isolate_scope(isolate_);
- v8::HandleScope scope(isolate_);
-
- v8::Local<v8::Context> context =
- v8::Local<v8::Context>::New(isolate_, v8_context_);
- v8::Context::Scope function_scope(context);
-
- v8::Local<v8::Value> function;
- if (!GetFindProxyForURL(&function)) {
- js_bindings()->OnError(
- -1, base::ASCIIToUTF16("FindProxyForURL() is undefined."));
- return ERR_PAC_SCRIPT_FAILED;
- }
-
- v8::Local<v8::Value> argv[] = {
- ASCIIStringToV8String(isolate_, query_url.spec()),
- ASCIIStringToV8String(isolate_, query_url.HostNoBrackets()),
- };
-
- v8::TryCatch try_catch;
- v8::Local<v8::Value> ret = v8::Function::Cast(*function)->Call(
- context->Global(), arraysize(argv), argv);
-
- if (try_catch.HasCaught()) {
- HandleError(try_catch.Message());
- return ERR_PAC_SCRIPT_FAILED;
- }
-
- if (!ret->IsString()) {
- js_bindings()->OnError(
- -1, base::ASCIIToUTF16("FindProxyForURL() did not return a string."));
- return ERR_PAC_SCRIPT_FAILED;
- }
-
- base::string16 ret_str = V8StringToUTF16(v8::Local<v8::String>::Cast(ret));
-
- if (!base::IsStringASCII(ret_str)) {
- // TODO(eroman): Rather than failing when a wide string is returned, we
- // could extend the parsing to handle IDNA hostnames by
- // converting them to ASCII punycode.
- // crbug.com/47234
- base::string16 error_message =
- base::ASCIIToUTF16("FindProxyForURL() returned a non-ASCII string "
- "(crbug.com/47234): ") + ret_str;
- js_bindings()->OnError(-1, error_message);
- return ERR_PAC_SCRIPT_FAILED;
- }
-
- results->UsePacString(base::UTF16ToASCII(ret_str));
- return OK;
- }
-
- int InitV8(const scoped_refptr<ProxyResolverScriptData>& pac_script) {
- v8::Locker locked(isolate_);
- v8::Isolate::Scope isolate_scope(isolate_);
- v8::HandleScope scope(isolate_);
-
- v8_this_.Reset(isolate_, v8::External::New(isolate_, this));
- v8::Local<v8::External> v8_this =
- v8::Local<v8::External>::New(isolate_, v8_this_);
- v8::Local<v8::ObjectTemplate> global_template =
- v8::ObjectTemplate::New(isolate_);
-
- // Attach the javascript bindings.
- v8::Local<v8::FunctionTemplate> alert_template =
- v8::FunctionTemplate::New(isolate_, &AlertCallback, v8_this);
- global_template->Set(ASCIILiteralToV8String(isolate_, "alert"),
- alert_template);
-
- v8::Local<v8::FunctionTemplate> my_ip_address_template =
- v8::FunctionTemplate::New(isolate_, &MyIpAddressCallback, v8_this);
- global_template->Set(ASCIILiteralToV8String(isolate_, "myIpAddress"),
- my_ip_address_template);
-
- v8::Local<v8::FunctionTemplate> dns_resolve_template =
- v8::FunctionTemplate::New(isolate_, &DnsResolveCallback, v8_this);
- global_template->Set(ASCIILiteralToV8String(isolate_, "dnsResolve"),
- dns_resolve_template);
-
- v8::Local<v8::FunctionTemplate> is_plain_host_name_template =
- v8::FunctionTemplate::New(isolate_, &IsPlainHostNameCallback, v8_this);
- global_template->Set(ASCIILiteralToV8String(isolate_, "isPlainHostName"),
- is_plain_host_name_template);
-
- // Microsoft's PAC extensions:
-
- v8::Local<v8::FunctionTemplate> dns_resolve_ex_template =
- v8::FunctionTemplate::New(isolate_, &DnsResolveExCallback, v8_this);
- global_template->Set(ASCIILiteralToV8String(isolate_, "dnsResolveEx"),
- dns_resolve_ex_template);
-
- v8::Local<v8::FunctionTemplate> my_ip_address_ex_template =
- v8::FunctionTemplate::New(isolate_, &MyIpAddressExCallback, v8_this);
- global_template->Set(ASCIILiteralToV8String(isolate_, "myIpAddressEx"),
- my_ip_address_ex_template);
-
- v8::Local<v8::FunctionTemplate> sort_ip_address_list_template =
- v8::FunctionTemplate::New(isolate_,
- &SortIpAddressListCallback,
- v8_this);
- global_template->Set(ASCIILiteralToV8String(isolate_, "sortIpAddressList"),
- sort_ip_address_list_template);
-
- v8::Local<v8::FunctionTemplate> is_in_net_ex_template =
- v8::FunctionTemplate::New(isolate_, &IsInNetExCallback, v8_this);
- global_template->Set(ASCIILiteralToV8String(isolate_, "isInNetEx"),
- is_in_net_ex_template);
-
- v8_context_.Reset(
- isolate_, v8::Context::New(isolate_, NULL, global_template));
-
- v8::Local<v8::Context> context =
- v8::Local<v8::Context>::New(isolate_, v8_context_);
- v8::Context::Scope ctx(context);
-
- // Add the PAC utility functions to the environment.
- // (This script should never fail, as it is a string literal!)
- // Note that the two string literals are concatenated.
- int rv = RunScript(
- ASCIILiteralToV8String(
- isolate_,
- PROXY_RESOLVER_SCRIPT
- PROXY_RESOLVER_SCRIPT_EX),
- kPacUtilityResourceName);
- if (rv != OK) {
- NOTREACHED();
- return rv;
- }
-
- // Add the user's PAC code to the environment.
- rv =
- RunScript(ScriptDataToV8String(isolate_, pac_script), kPacResourceName);
- if (rv != OK)
- return rv;
-
- // At a minimum, the FindProxyForURL() function must be defined for this
- // to be a legitimiate PAC script.
- v8::Local<v8::Value> function;
- if (!GetFindProxyForURL(&function)) {
- js_bindings()->OnError(
- -1, base::ASCIIToUTF16("FindProxyForURL() is undefined."));
- return ERR_PAC_SCRIPT_FAILED;
- }
-
- return OK;
- }
-
- private:
- bool GetFindProxyForURL(v8::Local<v8::Value>* function) {
- v8::Local<v8::Context> context =
- v8::Local<v8::Context>::New(isolate_, v8_context_);
- *function =
- context->Global()->Get(
- ASCIILiteralToV8String(isolate_, "FindProxyForURL"));
- return (*function)->IsFunction();
- }
-
- // Handle an exception thrown by V8.
- void HandleError(v8::Local<v8::Message> message) {
- base::string16 error_message;
- int line_number = -1;
-
- if (!message.IsEmpty()) {
- line_number = message->GetLineNumber();
- V8ObjectToUTF16String(message->Get(), &error_message, isolate_);
- }
-
- js_bindings()->OnError(line_number, error_message);
- }
-
- // Compiles and runs |script| in the current V8 context.
- // Returns OK on success, otherwise an error code.
- int RunScript(v8::Local<v8::String> script, const char* script_name) {
- v8::TryCatch try_catch;
-
- // Compile the script.
- v8::ScriptOrigin origin =
- v8::ScriptOrigin(ASCIILiteralToV8String(isolate_, script_name));
- v8::Local<v8::Script> code = v8::Script::Compile(script, &origin);
-
- // Execute.
- if (!code.IsEmpty())
- code->Run();
-
- // Check for errors.
- if (try_catch.HasCaught()) {
- HandleError(try_catch.Message());
- return ERR_PAC_SCRIPT_FAILED;
- }
-
- return OK;
- }
-
- // V8 callback for when "alert()" is invoked by the PAC script.
- static void AlertCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
- Context* context =
- static_cast<Context*>(v8::External::Cast(*args.Data())->Value());
-
- // Like firefox we assume "undefined" if no argument was specified, and
- // disregard any arguments beyond the first.
- base::string16 message;
- if (args.Length() == 0) {
- message = base::ASCIIToUTF16("undefined");
- } else {
- if (!V8ObjectToUTF16String(args[0], &message, args.GetIsolate()))
- return; // toString() threw an exception.
- }
-
- context->js_bindings()->Alert(message);
- }
-
- // V8 callback for when "myIpAddress()" is invoked by the PAC script.
- static void MyIpAddressCallback(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- DnsResolveCallbackHelper(args, JSBindings::MY_IP_ADDRESS);
- }
-
- // V8 callback for when "myIpAddressEx()" is invoked by the PAC script.
- static void MyIpAddressExCallback(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- DnsResolveCallbackHelper(args, JSBindings::MY_IP_ADDRESS_EX);
- }
-
- // V8 callback for when "dnsResolve()" is invoked by the PAC script.
- static void DnsResolveCallback(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- DnsResolveCallbackHelper(args, JSBindings::DNS_RESOLVE);
- }
-
- // V8 callback for when "dnsResolveEx()" is invoked by the PAC script.
- static void DnsResolveExCallback(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- DnsResolveCallbackHelper(args, JSBindings::DNS_RESOLVE_EX);
- }
-
- // Shared code for implementing:
- // - myIpAddress(), myIpAddressEx(), dnsResolve(), dnsResolveEx().
- static void DnsResolveCallbackHelper(
- const v8::FunctionCallbackInfo<v8::Value>& args,
- JSBindings::ResolveDnsOperation op) {
- Context* context =
- static_cast<Context*>(v8::External::Cast(*args.Data())->Value());
-
- std::string hostname;
-
- // dnsResolve() and dnsResolveEx() need at least 1 argument.
- if (op == JSBindings::DNS_RESOLVE || op == JSBindings::DNS_RESOLVE_EX) {
- if (!GetHostnameArgument(args, &hostname)) {
- if (op == JSBindings::DNS_RESOLVE)
- args.GetReturnValue().SetNull();
- return;
- }
- }
-
- std::string result;
- bool success;
- bool terminate = false;
-
- {
- v8::Unlocker unlocker(args.GetIsolate());
- success = context->js_bindings()->ResolveDns(
- hostname, op, &result, &terminate);
- }
-
- if (terminate)
- v8::V8::TerminateExecution(args.GetIsolate());
-
- if (success) {
- args.GetReturnValue().Set(
- ASCIIStringToV8String(args.GetIsolate(), result));
- return;
- }
-
- // Each function handles resolution errors differently.
- switch (op) {
- case JSBindings::DNS_RESOLVE:
- args.GetReturnValue().SetNull();
- return;
- case JSBindings::DNS_RESOLVE_EX:
- args.GetReturnValue().SetEmptyString();
- return;
- case JSBindings::MY_IP_ADDRESS:
- args.GetReturnValue().Set(
- ASCIILiteralToV8String(args.GetIsolate(), "127.0.0.1"));
- return;
- case JSBindings::MY_IP_ADDRESS_EX:
- args.GetReturnValue().SetEmptyString();
- return;
- }
-
- NOTREACHED();
- }
-
- // V8 callback for when "sortIpAddressList()" is invoked by the PAC script.
- static void SortIpAddressListCallback(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- // We need at least one string argument.
- if (args.Length() == 0 || args[0].IsEmpty() || !args[0]->IsString()) {
- args.GetReturnValue().SetNull();
- return;
- }
-
- std::string ip_address_list =
- V8StringToUTF8(v8::Local<v8::String>::Cast(args[0]));
- if (!base::IsStringASCII(ip_address_list)) {
- args.GetReturnValue().SetNull();
- return;
- }
- std::string sorted_ip_address_list;
- bool success = SortIpAddressList(ip_address_list, &sorted_ip_address_list);
- if (!success) {
- args.GetReturnValue().Set(false);
- return;
- }
- args.GetReturnValue().Set(
- ASCIIStringToV8String(args.GetIsolate(), sorted_ip_address_list));
- }
-
- // V8 callback for when "isInNetEx()" is invoked by the PAC script.
- static void IsInNetExCallback(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- // We need at least 2 string arguments.
- if (args.Length() < 2 || args[0].IsEmpty() || !args[0]->IsString() ||
- args[1].IsEmpty() || !args[1]->IsString()) {
- args.GetReturnValue().SetNull();
- return;
- }
-
- std::string ip_address =
- V8StringToUTF8(v8::Local<v8::String>::Cast(args[0]));
- if (!base::IsStringASCII(ip_address)) {
- args.GetReturnValue().Set(false);
- return;
- }
- std::string ip_prefix =
- V8StringToUTF8(v8::Local<v8::String>::Cast(args[1]));
- if (!base::IsStringASCII(ip_prefix)) {
- args.GetReturnValue().Set(false);
- return;
- }
- args.GetReturnValue().Set(IsInNetEx(ip_address, ip_prefix));
- }
-
- // V8 callback for when "isPlainHostName()" is invoked by the PAC script.
- static void IsPlainHostNameCallback(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- // Need at least 1 string arguments.
- if (args.Length() < 1 || args[0].IsEmpty() || !args[0]->IsString()) {
- args.GetIsolate()->ThrowException(
- v8::Exception::TypeError(ASCIIStringToV8String(
- args.GetIsolate(), "Requires 1 string parameter")));
- return;
- }
-
- std::string hostname_utf8 =
- V8StringToUTF8(v8::Local<v8::String>::Cast(args[0]));
- args.GetReturnValue().Set(IsPlainHostName(hostname_utf8));
- }
-
- mutable base::Lock lock_;
- ProxyResolverV8* parent_;
- v8::Isolate* isolate_;
- v8::Persistent<v8::External> v8_this_;
- v8::Persistent<v8::Context> v8_context_;
-};
-
-// ProxyResolverV8 ------------------------------------------------------------
-
-ProxyResolverV8::ProxyResolverV8()
- : ProxyResolver(true /*expects_pac_bytes*/),
- js_bindings_(NULL) {
-}
-
-ProxyResolverV8::~ProxyResolverV8() {}
-
-int ProxyResolverV8::GetProxyForURL(
- const GURL& query_url, ProxyInfo* results,
- const CompletionCallback& /*callback*/,
- RequestHandle* /*request*/,
- const BoundNetLog& net_log) {
- DCHECK(js_bindings_);
-
- // If the V8 instance has not been initialized (either because
- // SetPacScript() wasn't called yet, or because it failed.
- if (!context_)
- return ERR_FAILED;
-
- // Otherwise call into V8.
- int rv = context_->ResolveProxy(query_url, results);
-
- return rv;
-}
-
-void ProxyResolverV8::CancelRequest(RequestHandle request) {
- // This is a synchronous ProxyResolver; no possibility for async requests.
- NOTREACHED();
-}
-
-LoadState ProxyResolverV8::GetLoadState(RequestHandle request) const {
- NOTREACHED();
- return LOAD_STATE_IDLE;
-}
-
-void ProxyResolverV8::CancelSetPacScript() {
- NOTREACHED();
-}
-
-int ProxyResolverV8::SetPacScript(
- const scoped_refptr<ProxyResolverScriptData>& script_data,
- const CompletionCallback& /*callback*/) {
- DCHECK(script_data.get());
- DCHECK(js_bindings_);
-
- context_.reset();
- if (script_data->utf16().empty())
- return ERR_PAC_SCRIPT_FAILED;
-
- // Try parsing the PAC script.
- scoped_ptr<Context> context(new Context(this, GetDefaultIsolate()));
- int rv = context->InitV8(script_data);
- if (rv == OK)
- context_.reset(context.release());
- return rv;
-}
-
-// static
-void ProxyResolverV8::EnsureIsolateCreated() {
- if (g_proxy_resolver_isolate_)
- return;
- gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode,
- gin::ArrayBufferAllocator::SharedInstance());
- g_proxy_resolver_isolate_ = new gin::IsolateHolder;
- ANNOTATE_LEAKING_OBJECT_PTR(g_proxy_resolver_isolate_);
-}
-
-// static
-v8::Isolate* ProxyResolverV8::GetDefaultIsolate() {
- DCHECK(g_proxy_resolver_isolate_)
- << "Must call ProxyResolverV8::EnsureIsolateCreated() first";
- return g_proxy_resolver_isolate_->isolate();
-}
-
-gin::IsolateHolder* ProxyResolverV8::g_proxy_resolver_isolate_ = NULL;
-
-// static
-size_t ProxyResolverV8::GetTotalHeapSize() {
- if (!g_proxy_resolver_isolate_)
- return 0;
-
- v8::Locker locked(g_proxy_resolver_isolate_->isolate());
- v8::Isolate::Scope isolate_scope(g_proxy_resolver_isolate_->isolate());
- v8::HeapStatistics heap_statistics;
- g_proxy_resolver_isolate_->isolate()->GetHeapStatistics(&heap_statistics);
- return heap_statistics.total_heap_size();
-}
-
-// static
-size_t ProxyResolverV8::GetUsedHeapSize() {
- if (!g_proxy_resolver_isolate_)
- return 0;
-
- v8::Locker locked(g_proxy_resolver_isolate_->isolate());
- v8::Isolate::Scope isolate_scope(g_proxy_resolver_isolate_->isolate());
- v8::HeapStatistics heap_statistics;
- g_proxy_resolver_isolate_->isolate()->GetHeapStatistics(&heap_statistics);
- return heap_statistics.used_heap_size();
-}
-
-} // namespace net
« no previous file with comments | « net/proxy/proxy_resolver_v8.h ('k') | net/proxy/proxy_resolver_v8_tracing.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698