// Copyright (c) 2015 GitHub, Inc. // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. #include "atom/browser/api/atom_api_web_request.h" #include #include "atom/browser/atom_browser_context.h" #include "atom/browser/net/atom_network_delegate.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/net_converter.h" #include "atom/common/native_mate_converters/value_converter.h" #include "content/public/browser/browser_thread.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" using content::BrowserThread; namespace mate { template <> struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Local val, URLPattern* out) { std::string pattern; if (!ConvertFromV8(isolate, val, &pattern)) return false; *out = URLPattern(URLPattern::SCHEME_ALL); return out->Parse(pattern) == URLPattern::PARSE_SUCCESS; } }; } // namespace mate namespace atom { namespace api { namespace { template void CallNetworkDelegateMethod( brightray::URLRequestContextGetter* url_request_context_getter, Method method, Event type, URLPatterns patterns, Listener listener) { // Force creating network delegate. net::URLRequestContext* context = url_request_context_getter->GetURLRequestContext(); // Then call the method. AtomNetworkDelegate* network_delegate = static_cast(context->network_delegate()); (network_delegate->*method)(type, std::move(patterns), std::move(listener)); } } // namespace WebRequest::WebRequest(v8::Isolate* isolate, AtomBrowserContext* browser_context) : browser_context_(browser_context) { Init(isolate); } WebRequest::~WebRequest() {} template void WebRequest::SetSimpleListener(mate::Arguments* args) { SetListener( &AtomNetworkDelegate::SetSimpleListenerInIO, type, args); } template void WebRequest::SetResponseListener(mate::Arguments* args) { SetListener( &AtomNetworkDelegate::SetResponseListenerInIO, type, args); } template void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) { // { urls }. URLPatterns patterns; mate::Dictionary dict; args->GetNext(&dict) && dict.Get("urls", &patterns); // Function or null. v8::Local value; Listener listener; if (!args->GetNext(&listener) && !(args->GetNext(&value) && value->IsNull())) { args->ThrowError("Must pass null or a Function"); return; } brightray::URLRequestContextGetter* url_request_context_getter = browser_context_->url_request_context_getter(); if (!url_request_context_getter) return; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::Bind(&CallNetworkDelegateMethod, base::RetainedRef(url_request_context_getter), method, type, std::move(patterns), std::move(listener))); } // static mate::Handle WebRequest::Create( v8::Isolate* isolate, AtomBrowserContext* browser_context) { return mate::CreateHandle(isolate, new WebRequest(isolate, browser_context)); } // static void WebRequest::BuildPrototype(v8::Isolate* isolate, v8::Local prototype) { prototype->SetClassName(mate::StringToV8(isolate, "WebRequest")); mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) .SetMethod("onBeforeRequest", &WebRequest::SetResponseListener< AtomNetworkDelegate::kOnBeforeRequest>) .SetMethod("onBeforeSendHeaders", &WebRequest::SetResponseListener< AtomNetworkDelegate::kOnBeforeSendHeaders>) .SetMethod("onHeadersReceived", &WebRequest::SetResponseListener< AtomNetworkDelegate::kOnHeadersReceived>) .SetMethod( "onSendHeaders", &WebRequest::SetSimpleListener) .SetMethod("onBeforeRedirect", &WebRequest::SetSimpleListener< AtomNetworkDelegate::kOnBeforeRedirect>) .SetMethod("onResponseStarted", &WebRequest::SetSimpleListener< AtomNetworkDelegate::kOnResponseStarted>) .SetMethod( "onCompleted", &WebRequest::SetSimpleListener) .SetMethod("onErrorOccurred", &WebRequest::SetSimpleListener< AtomNetworkDelegate::kOnErrorOccurred>); } } // namespace api } // namespace atom