OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this |
2 // source code is governed by a BSD-style license that can be found in the | 2 // source code is governed by a BSD-style license that can be found in the |
3 // LICENSE file. | 3 // LICENSE file. |
4 | 4 |
5 #include "net/proxy/proxy_resolver_v8.h" | 5 #include "net/proxy/proxy_resolver_v8.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
9 #include "googleurl/src/gurl.h" | 9 #include "googleurl/src/gurl.h" |
10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 *result = V8StringToStdString(str_object); | 46 *result = V8StringToStdString(str_object); |
47 return true; | 47 return true; |
48 } | 48 } |
49 | 49 |
50 } // namespace | 50 } // namespace |
51 | 51 |
52 // ProxyResolverV8::Context --------------------------------------------------- | 52 // ProxyResolverV8::Context --------------------------------------------------- |
53 | 53 |
54 class ProxyResolverV8::Context { | 54 class ProxyResolverV8::Context { |
55 public: | 55 public: |
56 Context(ProxyResolverJSBindings* js_bindings, const std::string& pac_data) | 56 explicit Context(ProxyResolverJSBindings* js_bindings) |
57 : js_bindings_(js_bindings) { | 57 : js_bindings_(js_bindings) { |
58 DCHECK(js_bindings != NULL); | 58 DCHECK(js_bindings != NULL); |
59 InitV8(pac_data); | |
60 } | 59 } |
61 | 60 |
62 ~Context() { | 61 ~Context() { |
63 v8::Locker locked; | 62 v8::Locker locked; |
64 | 63 |
65 v8_this_.Dispose(); | 64 v8_this_.Dispose(); |
66 v8_context_.Dispose(); | 65 v8_context_.Dispose(); |
67 } | 66 } |
68 | 67 |
69 int ResolveProxy(const GURL& query_url, ProxyInfo* results) { | 68 int ResolveProxy(const GURL& query_url, ProxyInfo* results) { |
70 v8::Locker locked; | 69 v8::Locker locked; |
71 v8::HandleScope scope; | 70 v8::HandleScope scope; |
72 | 71 |
73 v8::Context::Scope function_scope(v8_context_); | 72 v8::Context::Scope function_scope(v8_context_); |
74 | 73 |
75 v8::Local<v8::Value> function = | 74 v8::Local<v8::Value> function; |
76 v8_context_->Global()->Get(v8::String::New("FindProxyForURL")); | 75 if (!GetFindProxyForURL(&function)) { |
77 if (!function->IsFunction()) { | |
78 js_bindings_->OnError(-1, "FindProxyForURL() is undefined."); | 76 js_bindings_->OnError(-1, "FindProxyForURL() is undefined."); |
79 return ERR_PAC_SCRIPT_FAILED; | 77 return ERR_PAC_SCRIPT_FAILED; |
80 } | 78 } |
81 | 79 |
82 v8::Handle<v8::Value> argv[] = { | 80 v8::Handle<v8::Value> argv[] = { |
83 StdStringToV8String(query_url.spec()), | 81 StdStringToV8String(query_url.spec()), |
84 StdStringToV8String(query_url.host()), | 82 StdStringToV8String(query_url.host()), |
85 }; | 83 }; |
86 | 84 |
87 v8::TryCatch try_catch; | 85 v8::TryCatch try_catch; |
(...skipping 10 matching lines...) Expand all Loading... |
98 return ERR_PAC_SCRIPT_FAILED; | 96 return ERR_PAC_SCRIPT_FAILED; |
99 } | 97 } |
100 | 98 |
101 std::string ret_str = V8StringToStdString(ret->ToString()); | 99 std::string ret_str = V8StringToStdString(ret->ToString()); |
102 | 100 |
103 results->UsePacString(ret_str); | 101 results->UsePacString(ret_str); |
104 | 102 |
105 return OK; | 103 return OK; |
106 } | 104 } |
107 | 105 |
108 private: | 106 int InitV8(const std::string& pac_data) { |
109 void InitV8(const std::string& pac_data) { | |
110 v8::Locker locked; | 107 v8::Locker locked; |
111 v8::HandleScope scope; | 108 v8::HandleScope scope; |
112 | 109 |
113 v8_this_ = v8::Persistent<v8::External>::New(v8::External::New(this)); | 110 v8_this_ = v8::Persistent<v8::External>::New(v8::External::New(this)); |
114 v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); | 111 v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); |
115 | 112 |
116 // Attach the javascript bindings. | 113 // Attach the javascript bindings. |
117 v8::Local<v8::FunctionTemplate> alert_template = | 114 v8::Local<v8::FunctionTemplate> alert_template = |
118 v8::FunctionTemplate::New(&AlertCallback, v8_this_); | 115 v8::FunctionTemplate::New(&AlertCallback, v8_this_); |
119 global_template->Set(v8::String::New("alert"), alert_template); | 116 global_template->Set(v8::String::New("alert"), alert_template); |
(...skipping 18 matching lines...) Expand all Loading... |
138 std::string text_raw = pac_data + PROXY_RESOLVER_SCRIPT; | 135 std::string text_raw = pac_data + PROXY_RESOLVER_SCRIPT; |
139 v8::Local<v8::String> text = StdStringToV8String(text_raw); | 136 v8::Local<v8::String> text = StdStringToV8String(text_raw); |
140 v8::ScriptOrigin origin = v8::ScriptOrigin( | 137 v8::ScriptOrigin origin = v8::ScriptOrigin( |
141 v8::String::New(kPacResourceName)); | 138 v8::String::New(kPacResourceName)); |
142 v8::Local<v8::Script> code = v8::Script::Compile(text, &origin); | 139 v8::Local<v8::Script> code = v8::Script::Compile(text, &origin); |
143 | 140 |
144 // Execute. | 141 // Execute. |
145 if (!code.IsEmpty()) | 142 if (!code.IsEmpty()) |
146 code->Run(); | 143 code->Run(); |
147 | 144 |
148 if (try_catch.HasCaught()) | 145 if (try_catch.HasCaught()) { |
149 HandleError(try_catch.Message()); | 146 HandleError(try_catch.Message()); |
| 147 return ERR_PAC_SCRIPT_FAILED; |
| 148 } |
| 149 |
| 150 // At a minimum, the FindProxyForURL() function must be defined for this |
| 151 // to be a legitimiate PAC script. |
| 152 v8::Local<v8::Value> function; |
| 153 if (!GetFindProxyForURL(&function)) |
| 154 return ERR_PAC_SCRIPT_FAILED; |
| 155 |
| 156 return OK; |
| 157 } |
| 158 |
| 159 private: |
| 160 bool GetFindProxyForURL(v8::Local<v8::Value>* function) { |
| 161 *function = v8_context_->Global()->Get(v8::String::New("FindProxyForURL")); |
| 162 return (*function)->IsFunction(); |
150 } | 163 } |
151 | 164 |
152 // Handle an exception thrown by V8. | 165 // Handle an exception thrown by V8. |
153 void HandleError(v8::Handle<v8::Message> message) { | 166 void HandleError(v8::Handle<v8::Message> message) { |
154 if (message.IsEmpty()) | 167 if (message.IsEmpty()) |
155 return; | 168 return; |
156 | 169 |
157 // Otherwise dispatch to the bindings. | 170 // Otherwise dispatch to the bindings. |
158 int line_number = message->GetLineNumber(); | 171 int line_number = message->GetLineNumber(); |
159 std::string error_message; | 172 std::string error_message; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 js_bindings_(custom_js_bindings) { | 239 js_bindings_(custom_js_bindings) { |
227 } | 240 } |
228 | 241 |
229 ProxyResolverV8::~ProxyResolverV8() {} | 242 ProxyResolverV8::~ProxyResolverV8() {} |
230 | 243 |
231 int ProxyResolverV8::GetProxyForURL(const GURL& query_url, | 244 int ProxyResolverV8::GetProxyForURL(const GURL& query_url, |
232 ProxyInfo* results, | 245 ProxyInfo* results, |
233 CompletionCallback* /*callback*/, | 246 CompletionCallback* /*callback*/, |
234 RequestHandle* /*request*/) { | 247 RequestHandle* /*request*/) { |
235 // If the V8 instance has not been initialized (either because | 248 // If the V8 instance has not been initialized (either because |
236 // SetPacScriptByData() wasn't called yet, or because it was called with | 249 // SetPacScript() wasn't called yet, or because it failed. |
237 // empty string). | |
238 if (!context_.get()) | 250 if (!context_.get()) |
239 return ERR_FAILED; | 251 return ERR_FAILED; |
240 | 252 |
241 // Otherwise call into V8. | 253 // Otherwise call into V8. |
242 return context_->ResolveProxy(query_url, results); | 254 return context_->ResolveProxy(query_url, results); |
243 } | 255 } |
244 | 256 |
245 void ProxyResolverV8::CancelRequest(RequestHandle request) { | 257 void ProxyResolverV8::CancelRequest(RequestHandle request) { |
246 // This is a synchronous ProxyResolver; no possibility for async requests. | 258 // This is a synchronous ProxyResolver; no possibility for async requests. |
247 NOTREACHED(); | 259 NOTREACHED(); |
248 } | 260 } |
249 | 261 |
250 void ProxyResolverV8::SetPacScriptByDataInternal(const std::string& data) { | 262 int ProxyResolverV8::SetPacScript(const GURL& /*url*/, |
| 263 const std::string& bytes, |
| 264 CompletionCallback* /*callback*/) { |
251 context_.reset(); | 265 context_.reset(); |
252 if (!data.empty()) | 266 if (bytes.empty()) |
253 context_.reset(new Context(js_bindings_.get(), data)); | 267 return ERR_PAC_SCRIPT_FAILED; |
| 268 |
| 269 // Try parsing the PAC script. |
| 270 scoped_ptr<Context> context(new Context(js_bindings_.get())); |
| 271 int rv = context->InitV8(bytes); |
| 272 if (rv == OK) |
| 273 context_.reset(context.release()); |
| 274 return rv; |
254 } | 275 } |
255 | 276 |
256 } // namespace net | 277 } // namespace net |
OLD | NEW |