| 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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 // External string wrapper so V8 can access a string literal. | 108 // External string wrapper so V8 can access a string literal. |
| 109 class V8ExternalASCIILiteral : public v8::String::ExternalAsciiStringResource { | 109 class V8ExternalASCIILiteral : public v8::String::ExternalAsciiStringResource { |
| 110 public: | 110 public: |
| 111 // |ascii| must be a NULL-terminated C string, and must remain valid | 111 // |ascii| must be a NULL-terminated C string, and must remain valid |
| 112 // throughout this object's lifetime. | 112 // throughout this object's lifetime. |
| 113 V8ExternalASCIILiteral(const char* ascii, size_t length) | 113 V8ExternalASCIILiteral(const char* ascii, size_t length) |
| 114 : ascii_(ascii), length_(length) { | 114 : ascii_(ascii), length_(length) { |
| 115 DCHECK(IsStringASCII(ascii)); | 115 DCHECK(IsStringASCII(ascii)); |
| 116 } | 116 } |
| 117 | 117 |
| 118 virtual const char* data() const OVERRIDE { | 118 virtual const char* data() const OVERRIDE { return ascii_; } |
| 119 return ascii_; | |
| 120 } | |
| 121 | 119 |
| 122 virtual size_t length() const OVERRIDE { | 120 virtual size_t length() const OVERRIDE { return length_; } |
| 123 return length_; | |
| 124 } | |
| 125 | 121 |
| 126 private: | 122 private: |
| 127 const char* ascii_; | 123 const char* ascii_; |
| 128 size_t length_; | 124 size_t length_; |
| 129 DISALLOW_COPY_AND_ASSIGN(V8ExternalASCIILiteral); | 125 DISALLOW_COPY_AND_ASSIGN(V8ExternalASCIILiteral); |
| 130 }; | 126 }; |
| 131 | 127 |
| 132 // When creating a v8::String from a C++ string we have two choices: create | 128 // When creating a v8::String from a C++ string we have two choices: create |
| 133 // a copy, or create a wrapper that shares the same underlying storage. | 129 // a copy, or create a wrapper that shares the same underlying storage. |
| 134 // For small strings it is better to just make a copy, whereas for large | 130 // For small strings it is better to just make a copy, whereas for large |
| (...skipping 18 matching lines...) Expand all Loading... |
| 153 // to wstring, and hence has character type wchar_t not uint16_t. | 149 // to wstring, and hence has character type wchar_t not uint16_t. |
| 154 if (len > 0) | 150 if (len > 0) |
| 155 s->Write(reinterpret_cast<uint16_t*>(WriteInto(&result, len + 1)), 0, len); | 151 s->Write(reinterpret_cast<uint16_t*>(WriteInto(&result, len + 1)), 0, len); |
| 156 return result; | 152 return result; |
| 157 } | 153 } |
| 158 | 154 |
| 159 // Converts an ASCII std::string to a V8 string. | 155 // Converts an ASCII std::string to a V8 string. |
| 160 v8::Local<v8::String> ASCIIStringToV8String(v8::Isolate* isolate, | 156 v8::Local<v8::String> ASCIIStringToV8String(v8::Isolate* isolate, |
| 161 const std::string& s) { | 157 const std::string& s) { |
| 162 DCHECK(IsStringASCII(s)); | 158 DCHECK(IsStringASCII(s)); |
| 163 return v8::String::NewFromUtf8(isolate, s.data(), v8::String::kNormalString, | 159 return v8::String::NewFromUtf8( |
| 164 s.size()); | 160 isolate, s.data(), v8::String::kNormalString, s.size()); |
| 165 } | 161 } |
| 166 | 162 |
| 167 // Converts a UTF16 base::string16 (warpped by a ProxyResolverScriptData) to a | 163 // Converts a UTF16 base::string16 (warpped by a ProxyResolverScriptData) to a |
| 168 // V8 string. | 164 // V8 string. |
| 169 v8::Local<v8::String> ScriptDataToV8String( | 165 v8::Local<v8::String> ScriptDataToV8String( |
| 170 v8::Isolate* isolate, const scoped_refptr<ProxyResolverScriptData>& s) { | 166 v8::Isolate* isolate, |
| 167 const scoped_refptr<ProxyResolverScriptData>& s) { |
| 171 if (s->utf16().size() * 2 <= kMaxStringBytesForCopy) { | 168 if (s->utf16().size() * 2 <= kMaxStringBytesForCopy) { |
| 172 return v8::String::NewFromTwoByte( | 169 return v8::String::NewFromTwoByte( |
| 173 isolate, | 170 isolate, |
| 174 reinterpret_cast<const uint16_t*>(s->utf16().data()), | 171 reinterpret_cast<const uint16_t*>(s->utf16().data()), |
| 175 v8::String::kNormalString, | 172 v8::String::kNormalString, |
| 176 s->utf16().size()); | 173 s->utf16().size()); |
| 177 } | 174 } |
| 178 return v8::String::NewExternal(isolate, | 175 return v8::String::NewExternal(isolate, |
| 179 new V8ExternalStringFromScriptData(s)); | 176 new V8ExternalStringFromScriptData(s)); |
| 180 } | 177 } |
| 181 | 178 |
| 182 // Converts an ASCII string literal to a V8 string. | 179 // Converts an ASCII string literal to a V8 string. |
| 183 v8::Local<v8::String> ASCIILiteralToV8String(v8::Isolate* isolate, | 180 v8::Local<v8::String> ASCIILiteralToV8String(v8::Isolate* isolate, |
| 184 const char* ascii) { | 181 const char* ascii) { |
| 185 DCHECK(IsStringASCII(ascii)); | 182 DCHECK(IsStringASCII(ascii)); |
| 186 size_t length = strlen(ascii); | 183 size_t length = strlen(ascii); |
| 187 if (length <= kMaxStringBytesForCopy) | 184 if (length <= kMaxStringBytesForCopy) |
| 188 return v8::String::NewFromUtf8(isolate, ascii, v8::String::kNormalString, | 185 return v8::String::NewFromUtf8( |
| 189 length); | 186 isolate, ascii, v8::String::kNormalString, length); |
| 190 return v8::String::NewExternal(isolate, | 187 return v8::String::NewExternal(isolate, |
| 191 new V8ExternalASCIILiteral(ascii, length)); | 188 new V8ExternalASCIILiteral(ascii, length)); |
| 192 } | 189 } |
| 193 | 190 |
| 194 // Stringizes a V8 object by calling its toString() method. Returns true | 191 // Stringizes a V8 object by calling its toString() method. Returns true |
| 195 // on success. This may fail if the toString() throws an exception. | 192 // on success. This may fail if the toString() throws an exception. |
| 196 bool V8ObjectToUTF16String(v8::Handle<v8::Value> object, | 193 bool V8ObjectToUTF16String(v8::Handle<v8::Value> object, |
| 197 base::string16* utf16_result, | 194 base::string16* utf16_result, |
| 198 v8::Isolate* isolate) { | 195 v8::Isolate* isolate) { |
| 199 if (object.IsEmpty()) | 196 if (object.IsEmpty()) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 219 | 216 |
| 220 // If the hostname is already in ASCII, simply return it as is. | 217 // If the hostname is already in ASCII, simply return it as is. |
| 221 if (IsStringASCII(hostname_utf16)) { | 218 if (IsStringASCII(hostname_utf16)) { |
| 222 *hostname = base::UTF16ToASCII(hostname_utf16); | 219 *hostname = base::UTF16ToASCII(hostname_utf16); |
| 223 return true; | 220 return true; |
| 224 } | 221 } |
| 225 | 222 |
| 226 // Otherwise try to convert it from IDN to punycode. | 223 // Otherwise try to convert it from IDN to punycode. |
| 227 const int kInitialBufferSize = 256; | 224 const int kInitialBufferSize = 256; |
| 228 url::RawCanonOutputT<base::char16, kInitialBufferSize> punycode_output; | 225 url::RawCanonOutputT<base::char16, kInitialBufferSize> punycode_output; |
| 229 if (!url::IDNToASCII(hostname_utf16.data(), hostname_utf16.length(), | 226 if (!url::IDNToASCII( |
| 230 &punycode_output)) { | 227 hostname_utf16.data(), hostname_utf16.length(), &punycode_output)) { |
| 231 return false; | 228 return false; |
| 232 } | 229 } |
| 233 | 230 |
| 234 // |punycode_output| should now be ASCII; convert it to a std::string. | 231 // |punycode_output| should now be ASCII; convert it to a std::string. |
| 235 // (We could use UTF16ToASCII() instead, but that requires an extra string | 232 // (We could use UTF16ToASCII() instead, but that requires an extra string |
| 236 // copy. Since ASCII is a subset of UTF8 the following is equivalent). | 233 // copy. Since ASCII is a subset of UTF8 the following is equivalent). |
| 237 bool success = base::UTF16ToUTF8(punycode_output.data(), | 234 bool success = base::UTF16ToUTF8( |
| 238 punycode_output.length(), | 235 punycode_output.data(), punycode_output.length(), hostname); |
| 239 hostname); | |
| 240 DCHECK(success); | 236 DCHECK(success); |
| 241 DCHECK(IsStringASCII(*hostname)); | 237 DCHECK(IsStringASCII(*hostname)); |
| 242 return success; | 238 return success; |
| 243 } | 239 } |
| 244 | 240 |
| 245 // Wrapper for passing around IP address strings and IPAddressNumber objects. | 241 // Wrapper for passing around IP address strings and IPAddressNumber objects. |
| 246 struct IPAddress { | 242 struct IPAddress { |
| 247 IPAddress(const std::string& ip_string, const IPAddressNumber& ip_number) | 243 IPAddress(const std::string& ip_string, const IPAddressNumber& ip_number) |
| 248 : string_value(ip_string), | 244 : string_value(ip_string), ip_address_number(ip_number) {} |
| 249 ip_address_number(ip_number) { | |
| 250 } | |
| 251 | 245 |
| 252 // Used for sorting IP addresses in ascending order in SortIpAddressList(). | 246 // Used for sorting IP addresses in ascending order in SortIpAddressList(). |
| 253 // IP6 addresses are placed ahead of IPv4 addresses. | 247 // IP6 addresses are placed ahead of IPv4 addresses. |
| 254 bool operator<(const IPAddress& rhs) const { | 248 bool operator<(const IPAddress& rhs) const { |
| 255 const IPAddressNumber& ip1 = this->ip_address_number; | 249 const IPAddressNumber& ip1 = this->ip_address_number; |
| 256 const IPAddressNumber& ip2 = rhs.ip_address_number; | 250 const IPAddressNumber& ip2 = rhs.ip_address_number; |
| 257 if (ip1.size() != ip2.size()) | 251 if (ip1.size() != ip2.size()) |
| 258 return ip1.size() > ip2.size(); // IPv6 before IPv4. | 252 return ip1.size() > ip2.size(); // IPv6 before IPv4. |
| 259 DCHECK(ip1.size() == ip2.size()); | 253 DCHECK(ip1.size() == ip2.size()); |
| 260 return memcmp(&ip1[0], &ip2[0], ip1.size()) < 0; // Ascending order. | 254 return memcmp(&ip1[0], &ip2[0], ip1.size()) < 0; // Ascending order. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 return IPNumberMatchesPrefix(address, prefix, prefix_length_in_bits); | 331 return IPNumberMatchesPrefix(address, prefix, prefix_length_in_bits); |
| 338 } | 332 } |
| 339 | 333 |
| 340 } // namespace | 334 } // namespace |
| 341 | 335 |
| 342 // ProxyResolverV8::Context --------------------------------------------------- | 336 // ProxyResolverV8::Context --------------------------------------------------- |
| 343 | 337 |
| 344 class ProxyResolverV8::Context { | 338 class ProxyResolverV8::Context { |
| 345 public: | 339 public: |
| 346 Context(ProxyResolverV8* parent, v8::Isolate* isolate) | 340 Context(ProxyResolverV8* parent, v8::Isolate* isolate) |
| 347 : parent_(parent), | 341 : parent_(parent), isolate_(isolate) { |
| 348 isolate_(isolate) { | |
| 349 DCHECK(isolate); | 342 DCHECK(isolate); |
| 350 } | 343 } |
| 351 | 344 |
| 352 ~Context() { | 345 ~Context() { |
| 353 v8::Locker locked(isolate_); | 346 v8::Locker locked(isolate_); |
| 354 v8::Isolate::Scope isolate_scope(isolate_); | 347 v8::Isolate::Scope isolate_scope(isolate_); |
| 355 | 348 |
| 356 v8_this_.Reset(); | 349 v8_this_.Reset(); |
| 357 v8_context_.Reset(); | 350 v8_context_.Reset(); |
| 358 } | 351 } |
| 359 | 352 |
| 360 JSBindings* js_bindings() { | 353 JSBindings* js_bindings() { return parent_->js_bindings_; } |
| 361 return parent_->js_bindings_; | |
| 362 } | |
| 363 | 354 |
| 364 int ResolveProxy(const GURL& query_url, ProxyInfo* results) { | 355 int ResolveProxy(const GURL& query_url, ProxyInfo* results) { |
| 365 v8::Locker locked(isolate_); | 356 v8::Locker locked(isolate_); |
| 366 v8::Isolate::Scope isolate_scope(isolate_); | 357 v8::Isolate::Scope isolate_scope(isolate_); |
| 367 v8::HandleScope scope(isolate_); | 358 v8::HandleScope scope(isolate_); |
| 368 | 359 |
| 369 v8::Local<v8::Context> context = | 360 v8::Local<v8::Context> context = |
| 370 v8::Local<v8::Context>::New(isolate_, v8_context_); | 361 v8::Local<v8::Context>::New(isolate_, v8_context_); |
| 371 v8::Context::Scope function_scope(context); | 362 v8::Context::Scope function_scope(context); |
| 372 | 363 |
| 373 v8::Local<v8::Value> function; | 364 v8::Local<v8::Value> function; |
| 374 if (!GetFindProxyForURL(&function)) { | 365 if (!GetFindProxyForURL(&function)) { |
| 375 js_bindings()->OnError( | 366 js_bindings()->OnError( |
| 376 -1, base::ASCIIToUTF16("FindProxyForURL() is undefined.")); | 367 -1, base::ASCIIToUTF16("FindProxyForURL() is undefined.")); |
| 377 return ERR_PAC_SCRIPT_FAILED; | 368 return ERR_PAC_SCRIPT_FAILED; |
| 378 } | 369 } |
| 379 | 370 |
| 380 v8::Handle<v8::Value> argv[] = { | 371 v8::Handle<v8::Value> argv[] = { |
| 381 ASCIIStringToV8String(isolate_, query_url.spec()), | 372 ASCIIStringToV8String(isolate_, query_url.spec()), |
| 382 ASCIIStringToV8String(isolate_, query_url.HostNoBrackets()), | 373 ASCIIStringToV8String(isolate_, query_url.HostNoBrackets()), |
| 383 }; | 374 }; |
| 384 | 375 |
| 385 v8::TryCatch try_catch; | 376 v8::TryCatch try_catch; |
| 386 v8::Local<v8::Value> ret = v8::Function::Cast(*function)->Call( | 377 v8::Local<v8::Value> ret = v8::Function::Cast(*function)->Call( |
| 387 context->Global(), arraysize(argv), argv); | 378 context->Global(), arraysize(argv), argv); |
| 388 | 379 |
| 389 if (try_catch.HasCaught()) { | 380 if (try_catch.HasCaught()) { |
| 390 HandleError(try_catch.Message()); | 381 HandleError(try_catch.Message()); |
| 391 return ERR_PAC_SCRIPT_FAILED; | 382 return ERR_PAC_SCRIPT_FAILED; |
| 392 } | 383 } |
| 393 | 384 |
| 394 if (!ret->IsString()) { | 385 if (!ret->IsString()) { |
| 395 js_bindings()->OnError( | 386 js_bindings()->OnError( |
| 396 -1, base::ASCIIToUTF16("FindProxyForURL() did not return a string.")); | 387 -1, base::ASCIIToUTF16("FindProxyForURL() did not return a string.")); |
| 397 return ERR_PAC_SCRIPT_FAILED; | 388 return ERR_PAC_SCRIPT_FAILED; |
| 398 } | 389 } |
| 399 | 390 |
| 400 base::string16 ret_str = V8StringToUTF16(ret->ToString()); | 391 base::string16 ret_str = V8StringToUTF16(ret->ToString()); |
| 401 | 392 |
| 402 if (!IsStringASCII(ret_str)) { | 393 if (!IsStringASCII(ret_str)) { |
| 403 // 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 |
| 404 // could extend the parsing to handle IDNA hostnames by | 395 // could extend the parsing to handle IDNA hostnames by |
| 405 // converting them to ASCII punycode. | 396 // converting them to ASCII punycode. |
| 406 // crbug.com/47234 | 397 // crbug.com/47234 |
| 407 base::string16 error_message = | 398 base::string16 error_message = |
| 408 base::ASCIIToUTF16("FindProxyForURL() returned a non-ASCII string " | 399 base::ASCIIToUTF16( |
| 409 "(crbug.com/47234): ") + ret_str; | 400 "FindProxyForURL() returned a non-ASCII string " |
| 401 "(crbug.com/47234): ") + |
| 402 ret_str; |
| 410 js_bindings()->OnError(-1, error_message); | 403 js_bindings()->OnError(-1, error_message); |
| 411 return ERR_PAC_SCRIPT_FAILED; | 404 return ERR_PAC_SCRIPT_FAILED; |
| 412 } | 405 } |
| 413 | 406 |
| 414 results->UsePacString(base::UTF16ToASCII(ret_str)); | 407 results->UsePacString(base::UTF16ToASCII(ret_str)); |
| 415 return OK; | 408 return OK; |
| 416 } | 409 } |
| 417 | 410 |
| 418 int InitV8(const scoped_refptr<ProxyResolverScriptData>& pac_script) { | 411 int InitV8(const scoped_refptr<ProxyResolverScriptData>& pac_script) { |
| 419 v8::Locker locked(isolate_); | 412 v8::Locker locked(isolate_); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 448 v8::FunctionTemplate::New(isolate_, &DnsResolveExCallback, v8_this); | 441 v8::FunctionTemplate::New(isolate_, &DnsResolveExCallback, v8_this); |
| 449 global_template->Set(ASCIILiteralToV8String(isolate_, "dnsResolveEx"), | 442 global_template->Set(ASCIILiteralToV8String(isolate_, "dnsResolveEx"), |
| 450 dns_resolve_ex_template); | 443 dns_resolve_ex_template); |
| 451 | 444 |
| 452 v8::Local<v8::FunctionTemplate> my_ip_address_ex_template = | 445 v8::Local<v8::FunctionTemplate> my_ip_address_ex_template = |
| 453 v8::FunctionTemplate::New(isolate_, &MyIpAddressExCallback, v8_this); | 446 v8::FunctionTemplate::New(isolate_, &MyIpAddressExCallback, v8_this); |
| 454 global_template->Set(ASCIILiteralToV8String(isolate_, "myIpAddressEx"), | 447 global_template->Set(ASCIILiteralToV8String(isolate_, "myIpAddressEx"), |
| 455 my_ip_address_ex_template); | 448 my_ip_address_ex_template); |
| 456 | 449 |
| 457 v8::Local<v8::FunctionTemplate> sort_ip_address_list_template = | 450 v8::Local<v8::FunctionTemplate> sort_ip_address_list_template = |
| 458 v8::FunctionTemplate::New(isolate_, | 451 v8::FunctionTemplate::New( |
| 459 &SortIpAddressListCallback, | 452 isolate_, &SortIpAddressListCallback, v8_this); |
| 460 v8_this); | |
| 461 global_template->Set(ASCIILiteralToV8String(isolate_, "sortIpAddressList"), | 453 global_template->Set(ASCIILiteralToV8String(isolate_, "sortIpAddressList"), |
| 462 sort_ip_address_list_template); | 454 sort_ip_address_list_template); |
| 463 | 455 |
| 464 v8::Local<v8::FunctionTemplate> is_in_net_ex_template = | 456 v8::Local<v8::FunctionTemplate> is_in_net_ex_template = |
| 465 v8::FunctionTemplate::New(isolate_, &IsInNetExCallback, v8_this); | 457 v8::FunctionTemplate::New(isolate_, &IsInNetExCallback, v8_this); |
| 466 global_template->Set(ASCIILiteralToV8String(isolate_, "isInNetEx"), | 458 global_template->Set(ASCIILiteralToV8String(isolate_, "isInNetEx"), |
| 467 is_in_net_ex_template); | 459 is_in_net_ex_template); |
| 468 | 460 |
| 469 v8_context_.Reset( | 461 v8_context_.Reset(isolate_, |
| 470 isolate_, v8::Context::New(isolate_, NULL, global_template)); | 462 v8::Context::New(isolate_, NULL, global_template)); |
| 471 | 463 |
| 472 v8::Local<v8::Context> context = | 464 v8::Local<v8::Context> context = |
| 473 v8::Local<v8::Context>::New(isolate_, v8_context_); | 465 v8::Local<v8::Context>::New(isolate_, v8_context_); |
| 474 v8::Context::Scope ctx(context); | 466 v8::Context::Scope ctx(context); |
| 475 | 467 |
| 476 // Add the PAC utility functions to the environment. | 468 // Add the PAC utility functions to the environment. |
| 477 // (This script should never fail, as it is a string literal!) | 469 // (This script should never fail, as it is a string literal!) |
| 478 // Note that the two string literals are concatenated. | 470 // Note that the two string literals are concatenated. |
| 479 int rv = RunScript( | 471 int rv = |
| 480 ASCIILiteralToV8String( | 472 RunScript(ASCIILiteralToV8String( |
| 481 isolate_, | 473 isolate_, PROXY_RESOLVER_SCRIPT PROXY_RESOLVER_SCRIPT_EX), |
| 482 PROXY_RESOLVER_SCRIPT | 474 kPacUtilityResourceName); |
| 483 PROXY_RESOLVER_SCRIPT_EX), | |
| 484 kPacUtilityResourceName); | |
| 485 if (rv != OK) { | 475 if (rv != OK) { |
| 486 NOTREACHED(); | 476 NOTREACHED(); |
| 487 return rv; | 477 return rv; |
| 488 } | 478 } |
| 489 | 479 |
| 490 // Add the user's PAC code to the environment. | 480 // Add the user's PAC code to the environment. |
| 491 rv = | 481 rv = |
| 492 RunScript(ScriptDataToV8String(isolate_, pac_script), kPacResourceName); | 482 RunScript(ScriptDataToV8String(isolate_, pac_script), kPacResourceName); |
| 493 if (rv != OK) | 483 if (rv != OK) |
| 494 return rv; | 484 return rv; |
| 495 | 485 |
| 496 // At a minimum, the FindProxyForURL() function must be defined for this | 486 // At a minimum, the FindProxyForURL() function must be defined for this |
| 497 // to be a legitimiate PAC script. | 487 // to be a legitimiate PAC script. |
| 498 v8::Local<v8::Value> function; | 488 v8::Local<v8::Value> function; |
| 499 if (!GetFindProxyForURL(&function)) { | 489 if (!GetFindProxyForURL(&function)) { |
| 500 js_bindings()->OnError( | 490 js_bindings()->OnError( |
| 501 -1, base::ASCIIToUTF16("FindProxyForURL() is undefined.")); | 491 -1, base::ASCIIToUTF16("FindProxyForURL() is undefined.")); |
| 502 return ERR_PAC_SCRIPT_FAILED; | 492 return ERR_PAC_SCRIPT_FAILED; |
| 503 } | 493 } |
| 504 | 494 |
| 505 return OK; | 495 return OK; |
| 506 } | 496 } |
| 507 | 497 |
| 508 private: | 498 private: |
| 509 bool GetFindProxyForURL(v8::Local<v8::Value>* function) { | 499 bool GetFindProxyForURL(v8::Local<v8::Value>* function) { |
| 510 v8::Local<v8::Context> context = | 500 v8::Local<v8::Context> context = |
| 511 v8::Local<v8::Context>::New(isolate_, v8_context_); | 501 v8::Local<v8::Context>::New(isolate_, v8_context_); |
| 512 *function = | 502 *function = context->Global()->Get( |
| 513 context->Global()->Get( | 503 ASCIILiteralToV8String(isolate_, "FindProxyForURL")); |
| 514 ASCIILiteralToV8String(isolate_, "FindProxyForURL")); | |
| 515 return (*function)->IsFunction(); | 504 return (*function)->IsFunction(); |
| 516 } | 505 } |
| 517 | 506 |
| 518 // Handle an exception thrown by V8. | 507 // Handle an exception thrown by V8. |
| 519 void HandleError(v8::Handle<v8::Message> message) { | 508 void HandleError(v8::Handle<v8::Message> message) { |
| 520 base::string16 error_message; | 509 base::string16 error_message; |
| 521 int line_number = -1; | 510 int line_number = -1; |
| 522 | 511 |
| 523 if (!message.IsEmpty()) { | 512 if (!message.IsEmpty()) { |
| 524 line_number = message->GetLineNumber(); | 513 line_number = message->GetLineNumber(); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 return; | 600 return; |
| 612 } | 601 } |
| 613 } | 602 } |
| 614 | 603 |
| 615 std::string result; | 604 std::string result; |
| 616 bool success; | 605 bool success; |
| 617 bool terminate = false; | 606 bool terminate = false; |
| 618 | 607 |
| 619 { | 608 { |
| 620 v8::Unlocker unlocker(args.GetIsolate()); | 609 v8::Unlocker unlocker(args.GetIsolate()); |
| 621 success = context->js_bindings()->ResolveDns( | 610 success = |
| 622 hostname, op, &result, &terminate); | 611 context->js_bindings()->ResolveDns(hostname, op, &result, &terminate); |
| 623 } | 612 } |
| 624 | 613 |
| 625 if (terminate) | 614 if (terminate) |
| 626 v8::V8::TerminateExecution(args.GetIsolate()); | 615 v8::V8::TerminateExecution(args.GetIsolate()); |
| 627 | 616 |
| 628 if (success) { | 617 if (success) { |
| 629 args.GetReturnValue().Set( | 618 args.GetReturnValue().Set( |
| 630 ASCIIStringToV8String(args.GetIsolate(), result)); | 619 ASCIIStringToV8String(args.GetIsolate(), result)); |
| 631 return; | 620 return; |
| 632 } | 621 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 mutable base::Lock lock_; | 690 mutable base::Lock lock_; |
| 702 ProxyResolverV8* parent_; | 691 ProxyResolverV8* parent_; |
| 703 v8::Isolate* isolate_; | 692 v8::Isolate* isolate_; |
| 704 v8::Persistent<v8::External> v8_this_; | 693 v8::Persistent<v8::External> v8_this_; |
| 705 v8::Persistent<v8::Context> v8_context_; | 694 v8::Persistent<v8::Context> v8_context_; |
| 706 }; | 695 }; |
| 707 | 696 |
| 708 // ProxyResolverV8 ------------------------------------------------------------ | 697 // ProxyResolverV8 ------------------------------------------------------------ |
| 709 | 698 |
| 710 ProxyResolverV8::ProxyResolverV8() | 699 ProxyResolverV8::ProxyResolverV8() |
| 711 : ProxyResolver(true /*expects_pac_bytes*/), | 700 : ProxyResolver(true /*expects_pac_bytes*/), js_bindings_(NULL) { |
| 712 js_bindings_(NULL) { | |
| 713 } | 701 } |
| 714 | 702 |
| 715 ProxyResolverV8::~ProxyResolverV8() {} | 703 ProxyResolverV8::~ProxyResolverV8() { |
| 704 } |
| 716 | 705 |
| 717 int ProxyResolverV8::GetProxyForURL( | 706 int ProxyResolverV8::GetProxyForURL(const GURL& query_url, |
| 718 const GURL& query_url, ProxyInfo* results, | 707 ProxyInfo* results, |
| 719 const CompletionCallback& /*callback*/, | 708 const CompletionCallback& /*callback*/, |
| 720 RequestHandle* /*request*/, | 709 RequestHandle* /*request*/, |
| 721 const BoundNetLog& net_log) { | 710 const BoundNetLog& net_log) { |
| 722 DCHECK(js_bindings_); | 711 DCHECK(js_bindings_); |
| 723 | 712 |
| 724 // If the V8 instance has not been initialized (either because | 713 // If the V8 instance has not been initialized (either because |
| 725 // SetPacScript() wasn't called yet, or because it failed. | 714 // SetPacScript() wasn't called yet, or because it failed. |
| 726 if (!context_) | 715 if (!context_) |
| 727 return ERR_FAILED; | 716 return ERR_FAILED; |
| 728 | 717 |
| 729 // Otherwise call into V8. | 718 // Otherwise call into V8. |
| 730 int rv = context_->ResolveProxy(query_url, results); | 719 int rv = context_->ResolveProxy(query_url, results); |
| 731 | 720 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 800 return 0; | 789 return 0; |
| 801 | 790 |
| 802 v8::Locker locked(g_proxy_resolver_isolate_->isolate()); | 791 v8::Locker locked(g_proxy_resolver_isolate_->isolate()); |
| 803 v8::Isolate::Scope isolate_scope(g_proxy_resolver_isolate_->isolate()); | 792 v8::Isolate::Scope isolate_scope(g_proxy_resolver_isolate_->isolate()); |
| 804 v8::HeapStatistics heap_statistics; | 793 v8::HeapStatistics heap_statistics; |
| 805 g_proxy_resolver_isolate_->isolate()->GetHeapStatistics(&heap_statistics); | 794 g_proxy_resolver_isolate_->isolate()->GetHeapStatistics(&heap_statistics); |
| 806 return heap_statistics.used_heap_size(); | 795 return heap_statistics.used_heap_size(); |
| 807 } | 796 } |
| 808 | 797 |
| 809 } // namespace net | 798 } // namespace net |
| OLD | NEW |