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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 DISALLOW_COPY_AND_ASSIGN(V8ExternalStringFromScriptData); | 105 DISALLOW_COPY_AND_ASSIGN(V8ExternalStringFromScriptData); |
106 }; | 106 }; |
107 | 107 |
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(base::IsStringASCII(ascii)); |
116 } | 116 } |
117 | 117 |
118 virtual const char* data() const OVERRIDE { | 118 virtual const char* data() const OVERRIDE { |
119 return ascii_; | 119 return ascii_; |
120 } | 120 } |
121 | 121 |
122 virtual size_t length() const OVERRIDE { | 122 virtual size_t length() const OVERRIDE { |
123 return length_; | 123 return length_; |
124 } | 124 } |
125 | 125 |
(...skipping 26 matching lines...) Expand all Loading... |
152 // Note that the reinterpret cast is because on Windows string16 is an alias | 152 // Note that the reinterpret cast is because on Windows string16 is an alias |
153 // to wstring, and hence has character type wchar_t not uint16_t. | 153 // to wstring, and hence has character type wchar_t not uint16_t. |
154 if (len > 0) | 154 if (len > 0) |
155 s->Write(reinterpret_cast<uint16_t*>(WriteInto(&result, len + 1)), 0, len); | 155 s->Write(reinterpret_cast<uint16_t*>(WriteInto(&result, len + 1)), 0, len); |
156 return result; | 156 return result; |
157 } | 157 } |
158 | 158 |
159 // Converts an ASCII std::string to a V8 string. | 159 // Converts an ASCII std::string to a V8 string. |
160 v8::Local<v8::String> ASCIIStringToV8String(v8::Isolate* isolate, | 160 v8::Local<v8::String> ASCIIStringToV8String(v8::Isolate* isolate, |
161 const std::string& s) { | 161 const std::string& s) { |
162 DCHECK(IsStringASCII(s)); | 162 DCHECK(base::IsStringASCII(s)); |
163 return v8::String::NewFromUtf8(isolate, s.data(), v8::String::kNormalString, | 163 return v8::String::NewFromUtf8(isolate, s.data(), v8::String::kNormalString, |
164 s.size()); | 164 s.size()); |
165 } | 165 } |
166 | 166 |
167 // Converts a UTF16 base::string16 (warpped by a ProxyResolverScriptData) to a | 167 // Converts a UTF16 base::string16 (warpped by a ProxyResolverScriptData) to a |
168 // V8 string. | 168 // V8 string. |
169 v8::Local<v8::String> ScriptDataToV8String( | 169 v8::Local<v8::String> ScriptDataToV8String( |
170 v8::Isolate* isolate, const scoped_refptr<ProxyResolverScriptData>& s) { | 170 v8::Isolate* isolate, const scoped_refptr<ProxyResolverScriptData>& s) { |
171 if (s->utf16().size() * 2 <= kMaxStringBytesForCopy) { | 171 if (s->utf16().size() * 2 <= kMaxStringBytesForCopy) { |
172 return v8::String::NewFromTwoByte( | 172 return v8::String::NewFromTwoByte( |
173 isolate, | 173 isolate, |
174 reinterpret_cast<const uint16_t*>(s->utf16().data()), | 174 reinterpret_cast<const uint16_t*>(s->utf16().data()), |
175 v8::String::kNormalString, | 175 v8::String::kNormalString, |
176 s->utf16().size()); | 176 s->utf16().size()); |
177 } | 177 } |
178 return v8::String::NewExternal(isolate, | 178 return v8::String::NewExternal(isolate, |
179 new V8ExternalStringFromScriptData(s)); | 179 new V8ExternalStringFromScriptData(s)); |
180 } | 180 } |
181 | 181 |
182 // Converts an ASCII string literal to a V8 string. | 182 // Converts an ASCII string literal to a V8 string. |
183 v8::Local<v8::String> ASCIILiteralToV8String(v8::Isolate* isolate, | 183 v8::Local<v8::String> ASCIILiteralToV8String(v8::Isolate* isolate, |
184 const char* ascii) { | 184 const char* ascii) { |
185 DCHECK(IsStringASCII(ascii)); | 185 DCHECK(base::IsStringASCII(ascii)); |
186 size_t length = strlen(ascii); | 186 size_t length = strlen(ascii); |
187 if (length <= kMaxStringBytesForCopy) | 187 if (length <= kMaxStringBytesForCopy) |
188 return v8::String::NewFromUtf8(isolate, ascii, v8::String::kNormalString, | 188 return v8::String::NewFromUtf8(isolate, ascii, v8::String::kNormalString, |
189 length); | 189 length); |
190 return v8::String::NewExternal(isolate, | 190 return v8::String::NewExternal(isolate, |
191 new V8ExternalASCIILiteral(ascii, length)); | 191 new V8ExternalASCIILiteral(ascii, length)); |
192 } | 192 } |
193 | 193 |
194 // Stringizes a V8 object by calling its toString() method. Returns true | 194 // Stringizes a V8 object by calling its toString() method. Returns true |
195 // on success. This may fail if the toString() throws an exception. | 195 // on success. This may fail if the toString() throws an exception. |
(...skipping 15 matching lines...) Expand all Loading... |
211 // and fills |*hostname| with the result. | 211 // and fills |*hostname| with the result. |
212 bool GetHostnameArgument(const v8::FunctionCallbackInfo<v8::Value>& args, | 212 bool GetHostnameArgument(const v8::FunctionCallbackInfo<v8::Value>& args, |
213 std::string* hostname) { | 213 std::string* hostname) { |
214 // The first argument should be a string. | 214 // The first argument should be a string. |
215 if (args.Length() == 0 || args[0].IsEmpty() || !args[0]->IsString()) | 215 if (args.Length() == 0 || args[0].IsEmpty() || !args[0]->IsString()) |
216 return false; | 216 return false; |
217 | 217 |
218 const base::string16 hostname_utf16 = V8StringToUTF16(args[0]->ToString()); | 218 const base::string16 hostname_utf16 = V8StringToUTF16(args[0]->ToString()); |
219 | 219 |
220 // If the hostname is already in ASCII, simply return it as is. | 220 // If the hostname is already in ASCII, simply return it as is. |
221 if (IsStringASCII(hostname_utf16)) { | 221 if (base::IsStringASCII(hostname_utf16)) { |
222 *hostname = base::UTF16ToASCII(hostname_utf16); | 222 *hostname = base::UTF16ToASCII(hostname_utf16); |
223 return true; | 223 return true; |
224 } | 224 } |
225 | 225 |
226 // Otherwise try to convert it from IDN to punycode. | 226 // Otherwise try to convert it from IDN to punycode. |
227 const int kInitialBufferSize = 256; | 227 const int kInitialBufferSize = 256; |
228 url::RawCanonOutputT<base::char16, kInitialBufferSize> punycode_output; | 228 url::RawCanonOutputT<base::char16, kInitialBufferSize> punycode_output; |
229 if (!url::IDNToASCII(hostname_utf16.data(), hostname_utf16.length(), | 229 if (!url::IDNToASCII(hostname_utf16.data(), hostname_utf16.length(), |
230 &punycode_output)) { | 230 &punycode_output)) { |
231 return false; | 231 return false; |
232 } | 232 } |
233 | 233 |
234 // |punycode_output| should now be ASCII; convert it to a std::string. | 234 // |punycode_output| should now be ASCII; convert it to a std::string. |
235 // (We could use UTF16ToASCII() instead, but that requires an extra string | 235 // (We could use UTF16ToASCII() instead, but that requires an extra string |
236 // copy. Since ASCII is a subset of UTF8 the following is equivalent). | 236 // copy. Since ASCII is a subset of UTF8 the following is equivalent). |
237 bool success = base::UTF16ToUTF8(punycode_output.data(), | 237 bool success = base::UTF16ToUTF8(punycode_output.data(), |
238 punycode_output.length(), | 238 punycode_output.length(), |
239 hostname); | 239 hostname); |
240 DCHECK(success); | 240 DCHECK(success); |
241 DCHECK(IsStringASCII(*hostname)); | 241 DCHECK(base::IsStringASCII(*hostname)); |
242 return success; | 242 return success; |
243 } | 243 } |
244 | 244 |
245 // Wrapper for passing around IP address strings and IPAddressNumber objects. | 245 // Wrapper for passing around IP address strings and IPAddressNumber objects. |
246 struct IPAddress { | 246 struct IPAddress { |
247 IPAddress(const std::string& ip_string, const IPAddressNumber& ip_number) | 247 IPAddress(const std::string& ip_string, const IPAddressNumber& ip_number) |
248 : string_value(ip_string), | 248 : string_value(ip_string), |
249 ip_address_number(ip_number) { | 249 ip_address_number(ip_number) { |
250 } | 250 } |
251 | 251 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 } | 392 } |
393 | 393 |
394 if (!ret->IsString()) { | 394 if (!ret->IsString()) { |
395 js_bindings()->OnError( | 395 js_bindings()->OnError( |
396 -1, base::ASCIIToUTF16("FindProxyForURL() did not return a string.")); | 396 -1, base::ASCIIToUTF16("FindProxyForURL() did not return a string.")); |
397 return ERR_PAC_SCRIPT_FAILED; | 397 return ERR_PAC_SCRIPT_FAILED; |
398 } | 398 } |
399 | 399 |
400 base::string16 ret_str = V8StringToUTF16(ret->ToString()); | 400 base::string16 ret_str = V8StringToUTF16(ret->ToString()); |
401 | 401 |
402 if (!IsStringASCII(ret_str)) { | 402 if (!base::IsStringASCII(ret_str)) { |
403 // TODO(eroman): Rather than failing when a wide string is returned, we | 403 // TODO(eroman): Rather than failing when a wide string is returned, we |
404 // could extend the parsing to handle IDNA hostnames by | 404 // could extend the parsing to handle IDNA hostnames by |
405 // converting them to ASCII punycode. | 405 // converting them to ASCII punycode. |
406 // crbug.com/47234 | 406 // crbug.com/47234 |
407 base::string16 error_message = | 407 base::string16 error_message = |
408 base::ASCIIToUTF16("FindProxyForURL() returned a non-ASCII string " | 408 base::ASCIIToUTF16("FindProxyForURL() returned a non-ASCII string " |
409 "(crbug.com/47234): ") + ret_str; | 409 "(crbug.com/47234): ") + ret_str; |
410 js_bindings()->OnError(-1, error_message); | 410 js_bindings()->OnError(-1, error_message); |
411 return ERR_PAC_SCRIPT_FAILED; | 411 return ERR_PAC_SCRIPT_FAILED; |
412 } | 412 } |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 // V8 callback for when "sortIpAddressList()" is invoked by the PAC script. | 654 // V8 callback for when "sortIpAddressList()" is invoked by the PAC script. |
655 static void SortIpAddressListCallback( | 655 static void SortIpAddressListCallback( |
656 const v8::FunctionCallbackInfo<v8::Value>& args) { | 656 const v8::FunctionCallbackInfo<v8::Value>& args) { |
657 // We need at least one string argument. | 657 // We need at least one string argument. |
658 if (args.Length() == 0 || args[0].IsEmpty() || !args[0]->IsString()) { | 658 if (args.Length() == 0 || args[0].IsEmpty() || !args[0]->IsString()) { |
659 args.GetReturnValue().SetNull(); | 659 args.GetReturnValue().SetNull(); |
660 return; | 660 return; |
661 } | 661 } |
662 | 662 |
663 std::string ip_address_list = V8StringToUTF8(args[0]->ToString()); | 663 std::string ip_address_list = V8StringToUTF8(args[0]->ToString()); |
664 if (!IsStringASCII(ip_address_list)) { | 664 if (!base::IsStringASCII(ip_address_list)) { |
665 args.GetReturnValue().SetNull(); | 665 args.GetReturnValue().SetNull(); |
666 return; | 666 return; |
667 } | 667 } |
668 std::string sorted_ip_address_list; | 668 std::string sorted_ip_address_list; |
669 bool success = SortIpAddressList(ip_address_list, &sorted_ip_address_list); | 669 bool success = SortIpAddressList(ip_address_list, &sorted_ip_address_list); |
670 if (!success) { | 670 if (!success) { |
671 args.GetReturnValue().Set(false); | 671 args.GetReturnValue().Set(false); |
672 return; | 672 return; |
673 } | 673 } |
674 args.GetReturnValue().Set( | 674 args.GetReturnValue().Set( |
675 ASCIIStringToV8String(args.GetIsolate(), sorted_ip_address_list)); | 675 ASCIIStringToV8String(args.GetIsolate(), sorted_ip_address_list)); |
676 } | 676 } |
677 | 677 |
678 // V8 callback for when "isInNetEx()" is invoked by the PAC script. | 678 // V8 callback for when "isInNetEx()" is invoked by the PAC script. |
679 static void IsInNetExCallback( | 679 static void IsInNetExCallback( |
680 const v8::FunctionCallbackInfo<v8::Value>& args) { | 680 const v8::FunctionCallbackInfo<v8::Value>& args) { |
681 // We need at least 2 string arguments. | 681 // We need at least 2 string arguments. |
682 if (args.Length() < 2 || args[0].IsEmpty() || !args[0]->IsString() || | 682 if (args.Length() < 2 || args[0].IsEmpty() || !args[0]->IsString() || |
683 args[1].IsEmpty() || !args[1]->IsString()) { | 683 args[1].IsEmpty() || !args[1]->IsString()) { |
684 args.GetReturnValue().SetNull(); | 684 args.GetReturnValue().SetNull(); |
685 return; | 685 return; |
686 } | 686 } |
687 | 687 |
688 std::string ip_address = V8StringToUTF8(args[0]->ToString()); | 688 std::string ip_address = V8StringToUTF8(args[0]->ToString()); |
689 if (!IsStringASCII(ip_address)) { | 689 if (!base::IsStringASCII(ip_address)) { |
690 args.GetReturnValue().Set(false); | 690 args.GetReturnValue().Set(false); |
691 return; | 691 return; |
692 } | 692 } |
693 std::string ip_prefix = V8StringToUTF8(args[1]->ToString()); | 693 std::string ip_prefix = V8StringToUTF8(args[1]->ToString()); |
694 if (!IsStringASCII(ip_prefix)) { | 694 if (!base::IsStringASCII(ip_prefix)) { |
695 args.GetReturnValue().Set(false); | 695 args.GetReturnValue().Set(false); |
696 return; | 696 return; |
697 } | 697 } |
698 args.GetReturnValue().Set(IsInNetEx(ip_address, ip_prefix)); | 698 args.GetReturnValue().Set(IsInNetEx(ip_address, ip_prefix)); |
699 } | 699 } |
700 | 700 |
701 mutable base::Lock lock_; | 701 mutable base::Lock lock_; |
702 ProxyResolverV8* parent_; | 702 ProxyResolverV8* parent_; |
703 v8::Isolate* isolate_; | 703 v8::Isolate* isolate_; |
704 v8::Persistent<v8::External> v8_this_; | 704 v8::Persistent<v8::External> v8_this_; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 return 0; | 800 return 0; |
801 | 801 |
802 v8::Locker locked(g_proxy_resolver_isolate_->isolate()); | 802 v8::Locker locked(g_proxy_resolver_isolate_->isolate()); |
803 v8::Isolate::Scope isolate_scope(g_proxy_resolver_isolate_->isolate()); | 803 v8::Isolate::Scope isolate_scope(g_proxy_resolver_isolate_->isolate()); |
804 v8::HeapStatistics heap_statistics; | 804 v8::HeapStatistics heap_statistics; |
805 g_proxy_resolver_isolate_->isolate()->GetHeapStatistics(&heap_statistics); | 805 g_proxy_resolver_isolate_->isolate()->GetHeapStatistics(&heap_statistics); |
806 return heap_statistics.used_heap_size(); | 806 return heap_statistics.used_heap_size(); |
807 } | 807 } |
808 | 808 |
809 } // namespace net | 809 } // namespace net |
OLD | NEW |