| 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 |