commit e451d9212179197b88abeb752602de3859bb1765 Author: Adam Roben Date: Wed Mar 13 15:12:05 2013 -0400 Initial commit diff --git a/brightray/.gitignore b/brightray/.gitignore new file mode 100644 index 0000000000..dde2688146 --- /dev/null +++ b/brightray/.gitignore @@ -0,0 +1,2 @@ +/brightray.xcodeproj/ +/build/ diff --git a/brightray/.gitmodules b/brightray/.gitmodules new file mode 100644 index 0000000000..3579d1eb60 --- /dev/null +++ b/brightray/.gitmodules @@ -0,0 +1,3 @@ +[submodule "vendor/libchromiumcontent"] + path = vendor/libchromiumcontent + url = https://github.com/aroben/libchromiumcontent diff --git a/brightray/LICENSE b/brightray/LICENSE new file mode 100644 index 0000000000..4fb14d4add --- /dev/null +++ b/brightray/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013 Adam Roben + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/brightray/LICENSE-CHROMIUM b/brightray/LICENSE-CHROMIUM new file mode 100644 index 0000000000..3d0f7d3edf --- /dev/null +++ b/brightray/LICENSE-CHROMIUM @@ -0,0 +1,27 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/brightray/README.md b/brightray/README.md new file mode 100644 index 0000000000..725a4718af --- /dev/null +++ b/brightray/README.md @@ -0,0 +1,34 @@ +# Brightray + +Brightray is a static library that makes +[libchromiumcontent](https://github.com/aroben/libchromiumcontent) easier to +use in applications. + +## Using it in your app + +See [brightray_example](https://github.com/aroben/brightray_example) for a +sample application written using Brightray. + +## Development + +### One-time setup + +You must previously have built and uploaded libchromiumcontent using its +`script/upload` script. + + $ script/bootstrap http://base.url.com/used/by/script/upload + +### Building + + $ script/build + +Building Brightray on its own isn’t all that interesting, since it’s just a +static library. Building it into an application (like +[brightray_example](https://github.com/aroben/brightray_example)) is the only +way to test it. + +## License + +In general, everything is covered by the [`LICENSE`](LICENSE) file. Some files +specify at the top that they are covered by the +[`LICENSE-CHROMIUM`](LICENSE-CHROMIUM) file instead. diff --git a/brightray/brightray.gyp b/brightray/brightray.gyp new file mode 100644 index 0000000000..0e19a903cb --- /dev/null +++ b/brightray/brightray.gyp @@ -0,0 +1,47 @@ +{ + 'includes': [ + 'brightray.gypi', + ], + 'targets': [ + { + 'target_name': 'brightray', + 'type': 'static_library', + 'include_dirs': [ + '<(libchromiumcontent_include_dir)', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + '<(libchromiumcontent_include_dir)', + ], + }, + 'sources': [ + 'browser/browser_client.cc', + 'browser/browser_client.h', + 'browser/browser_context.cc', + 'browser/browser_context.h', + 'browser/browser_main_parts.cc', + 'browser/browser_main_parts.h', + 'browser/browser_main_parts_mac.mm', + 'browser/mac/bry_application.h', + 'browser/mac/bry_application.mm', + 'browser/network_delegate.cc', + 'browser/network_delegate.h', + 'browser/url_request_context_getter.cc', + 'browser/url_request_context_getter.h', + 'common/main_delegate.cc', + 'common/main_delegate.h', + 'common/main_delegate_mac.mm', + ], + 'conditions': [ + ['OS=="mac"', { + 'link_settings': { + 'libraries': [ + 'libchromiumcontent.dylib', + '$(SDKROOT)/System/Library/Frameworks/AppKit.framework', + ], + }, + }], + ], + }, + ], +} diff --git a/brightray/brightray.gypi b/brightray/brightray.gypi new file mode 100644 index 0000000000..ecd35a269e --- /dev/null +++ b/brightray/brightray.gypi @@ -0,0 +1,39 @@ +{ + 'variables': { + 'libchromiumcontent_dir': 'vendor/download/libchromiumcontent', + 'libchromiumcontent_library_dir': '<(libchromiumcontent_dir)/Release', + 'libchromiumcontent_include_dir': '<(libchromiumcontent_dir)/include', + 'libchromiumcontent_resources_dir': '<(libchromiumcontent_library_dir)', + }, + 'target_defaults': { + 'defines': [ + 'NDEBUG', + ], + 'xcode_settings': { + 'CLANG_CXX_LANGUAGE_STANDARD': 'gnu++11', + 'CLANG_CXX_LIBRARY': 'libstdc++', + 'COMBINE_HIDPI_IMAGES': 'YES', + 'GCC_ENABLE_CPP_RTTI': 'NO', + 'GCC_TREAT_WARNINGS_AS_ERRORS': 'YES', + 'MACOSX_DEPLOYMENT_TARGET': '10.7', + 'RUN_CLANG_STATIC_ANALYZER': 'YES', + 'SDKROOT': 'macosx10.7', + 'WARNING_CFLAGS': [ + '-Wall', + '-Wextra', + '-Wno-unused-parameter', + '-Wno-missing-field-initializers', + ], + }, + 'configurations': { + 'Debug': { + 'xcode_settings': { + 'COPY_PHASE_STRIP': 'NO', + 'GCC_OPTIMIZATION_LEVEL': '0', + }, + }, + 'Release': { + }, + }, + }, +} diff --git a/brightray/browser/browser_client.cc b/brightray/browser/browser_client.cc new file mode 100644 index 0000000000..b9115fe1eb --- /dev/null +++ b/brightray/browser/browser_client.cc @@ -0,0 +1,35 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#include "browser_client.h" + +#include "browser_context.h" +#include "browser_main_parts.h" + +namespace brightray { + +BrowserClient::BrowserClient() { +} + +BrowserClient::~BrowserClient() { +} + +BrowserContext* BrowserClient::browser_context() { + return browser_main_parts_->browser_context(); +} + +BrowserMainParts* BrowserClient::OverrideCreateBrowserMainParts(const content::MainFunctionParams&) { + return new BrowserMainParts; +} + +content::BrowserMainParts* BrowserClient::CreateBrowserMainParts(const content::MainFunctionParams& parameters) { + browser_main_parts_.reset(OverrideCreateBrowserMainParts(parameters)); + return browser_main_parts_.get(); +} + +net::URLRequestContextGetter* BrowserClient::CreateRequestContext(content::BrowserContext* browser_context, content::ProtocolHandlerMap* protocol_handlers) { + return static_cast(browser_context)->CreateRequestContext(protocol_handlers); +} + +} diff --git a/brightray/browser/browser_client.h b/brightray/browser/browser_client.h new file mode 100644 index 0000000000..ac5412233f --- /dev/null +++ b/brightray/browser/browser_client.h @@ -0,0 +1,39 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#ifndef __brightray__browser_client__ +#define __brightray__browser_client__ + +#include "content/public/browser/content_browser_client.h" + +namespace brightray { + +class BrowserContext; +class BrowserMainParts; + +class BrowserClient : public content::ContentBrowserClient { +public: + BrowserClient(); + ~BrowserClient(); + + BrowserContext* browser_context(); + BrowserMainParts* browser_main_parts() { return browser_main_parts_.get(); } + +protected: + // Subclasses should override this to provide their own BrowserMainParts implementation. The + // lifetime of the returned instance is managed by the caller. + virtual BrowserMainParts* OverrideCreateBrowserMainParts(const content::MainFunctionParams&); + +private: + virtual content::BrowserMainParts* CreateBrowserMainParts(const content::MainFunctionParams&) OVERRIDE; + virtual net::URLRequestContextGetter* CreateRequestContext(content::BrowserContext*, content::ProtocolHandlerMap*) OVERRIDE; + + scoped_ptr browser_main_parts_; + + DISALLOW_COPY_AND_ASSIGN(BrowserClient); +}; + +} + +#endif /* defined(__brightray__browser_client__) */ diff --git a/brightray/browser/browser_context.cc b/brightray/browser/browser_context.cc new file mode 100644 index 0000000000..5177813399 --- /dev/null +++ b/brightray/browser/browser_context.cc @@ -0,0 +1,106 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#include "browser_context.h" + +#include "base/files/file_path.h" +#include "base/path_service.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/resource_context.h" +#include "content/public/browser/storage_partition.h" +#include "net/base/host_resolver.h" +#include "url_request_context_getter.h" + +namespace brightray { + +class BrowserContext::ResourceContext : public content::ResourceContext { +public: + ResourceContext() : getter_(nullptr) {} + + void set_url_request_context_getter(URLRequestContextGetter* getter) { + getter_ = getter; + } + +private: + virtual net::HostResolver* GetHostResolver() OVERRIDE { + return getter_->host_resolver(); + } + + virtual net::URLRequestContext* GetRequestContext() OVERRIDE { + return getter_->GetURLRequestContext(); + } + + URLRequestContextGetter* getter_; + scoped_ptr host_resolver_; +}; + +BrowserContext::BrowserContext() : resource_context_(new ResourceContext) { +} + +BrowserContext::~BrowserContext() { +} + +net::URLRequestContextGetter* BrowserContext::CreateRequestContext(content::ProtocolHandlerMap* protocol_handlers) { + DCHECK(!url_request_getter_); + url_request_getter_.reset(new URLRequestContextGetter( + GetPath(), + content::BrowserThread::UnsafeGetMessageLoopForThread(content::BrowserThread::IO), + content::BrowserThread::UnsafeGetMessageLoopForThread(content::BrowserThread::FILE), + protocol_handlers)); + resource_context_->set_url_request_context_getter(url_request_getter_.get()); + return url_request_getter_.get(); +} + +base::FilePath BrowserContext::GetPath() { + // FIXME: This should be an application-specific path. + base::FilePath path; + CHECK(PathService::Get(base::DIR_APP_DATA, &path)); + return path.Append("Brightray"); +} + +bool BrowserContext::IsOffTheRecord() const { + return false; +} + +net::URLRequestContextGetter* BrowserContext::GetRequestContext() { + return GetDefaultStoragePartition(this)->GetURLRequestContext(); +} + +net::URLRequestContextGetter* BrowserContext::GetRequestContextForRenderProcess(int renderer_child_id) { + return GetRequestContext(); +} + +net::URLRequestContextGetter* BrowserContext::GetMediaRequestContext() { + return GetRequestContext(); +} + +net::URLRequestContextGetter* BrowserContext::GetMediaRequestContextForRenderProcess(int renderer_child_id) { + return GetRequestContext(); +} + +net::URLRequestContextGetter* BrowserContext::GetMediaRequestContextForStoragePartition(const base::FilePath& partition_path, bool in_memory) { + return GetRequestContext(); +} + +content::ResourceContext* BrowserContext::GetResourceContext() { + return resource_context_.get(); +} + +content::DownloadManagerDelegate* BrowserContext::GetDownloadManagerDelegate() { + return nullptr; +} + +content::GeolocationPermissionContext* BrowserContext::GetGeolocationPermissionContext() { + return nullptr; +} + +content::SpeechRecognitionPreferences* BrowserContext::GetSpeechRecognitionPreferences() { + return nullptr; +} + +quota::SpecialStoragePolicy* BrowserContext::GetSpecialStoragePolicy() { + return nullptr; +} + +} diff --git a/brightray/browser/browser_context.h b/brightray/browser/browser_context.h new file mode 100644 index 0000000000..2b2c603c69 --- /dev/null +++ b/brightray/browser/browser_context.h @@ -0,0 +1,46 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#ifndef __brightray__browser_context__ +#define __brightray__browser_context__ + +#include "content/public/browser/browser_context.h" +#include "content/public/browser/content_browser_client.h" + +namespace brightray { + +class URLRequestContextGetter; + +class BrowserContext : public content::BrowserContext { +public: + BrowserContext(); + ~BrowserContext(); + + net::URLRequestContextGetter* CreateRequestContext(content::ProtocolHandlerMap*); + +private: + class ResourceContext; + + virtual base::FilePath GetPath() OVERRIDE; + virtual bool IsOffTheRecord() const OVERRIDE; + virtual net::URLRequestContextGetter* GetRequestContext() OVERRIDE; + virtual net::URLRequestContextGetter* GetRequestContextForRenderProcess(int renderer_child_id); + virtual net::URLRequestContextGetter* GetMediaRequestContext() OVERRIDE; + virtual net::URLRequestContextGetter* GetMediaRequestContextForRenderProcess(int renderer_child_id) OVERRIDE; + virtual net::URLRequestContextGetter* GetMediaRequestContextForStoragePartition(const base::FilePath& partition_path, bool in_memory); + virtual content::ResourceContext* GetResourceContext() OVERRIDE; + virtual content::DownloadManagerDelegate* GetDownloadManagerDelegate() OVERRIDE; + virtual content::GeolocationPermissionContext* GetGeolocationPermissionContext() OVERRIDE; + virtual content::SpeechRecognitionPreferences* GetSpeechRecognitionPreferences() OVERRIDE; + virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE; + + scoped_ptr resource_context_; + scoped_ptr url_request_getter_; + + DISALLOW_COPY_AND_ASSIGN(BrowserContext); +}; + +} + +#endif /* defined(__brightray__browser_context__) */ diff --git a/brightray/browser/browser_main_parts.cc b/brightray/browser/browser_main_parts.cc new file mode 100644 index 0000000000..8784794885 --- /dev/null +++ b/brightray/browser/browser_main_parts.cc @@ -0,0 +1,21 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#include "browser_main_parts.h" + +#include "browser_context.h" + +namespace brightray { + +BrowserMainParts::BrowserMainParts() { +} + +BrowserMainParts::~BrowserMainParts() { +} + +void BrowserMainParts::PreMainMessageLoopRun() { + browser_context_.reset(new BrowserContext); +} + +} diff --git a/brightray/browser/browser_main_parts.h b/brightray/browser/browser_main_parts.h new file mode 100644 index 0000000000..5e8194aa09 --- /dev/null +++ b/brightray/browser/browser_main_parts.h @@ -0,0 +1,38 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#ifndef __brightray__main_parts__ +#define __brightray__main_parts__ + +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/browser/browser_main_parts.h" + +namespace brightray { + +class BrowserContext; + +class BrowserMainParts : public content::BrowserMainParts { +public: + BrowserMainParts(); + ~BrowserMainParts(); + + BrowserContext* browser_context() { return browser_context_.get(); } + +protected: +#if defined(OS_MACOSX) + virtual void PreMainMessageLoopStart() OVERRIDE; +#endif + + virtual void PreMainMessageLoopRun() OVERRIDE; + +private: + scoped_ptr browser_context_; + + DISALLOW_COPY_AND_ASSIGN(BrowserMainParts); +}; + +} + +#endif /* defined(__brightray__main_parts__) */ diff --git a/brightray/browser/browser_main_parts_mac.mm b/brightray/browser/browser_main_parts_mac.mm new file mode 100644 index 0000000000..c3fb162fe1 --- /dev/null +++ b/brightray/browser/browser_main_parts_mac.mm @@ -0,0 +1,21 @@ +#import "browser_main_parts.h" + +#import "base/mac/bundle_locations.h" +#import + +namespace brightray { + +// Replicates NSApplicationMain, but doesn't start a run loop. +void BrowserMainParts::PreMainMessageLoopStart() { + auto infoDictionary = base::mac::OuterBundle().infoDictionary; + + auto principalClass = NSClassFromString([infoDictionary objectForKey:@"NSPrincipalClass"]); + auto application = [principalClass sharedApplication]; + + NSString *mainNibName = [infoDictionary objectForKey:@"NSMainNibFile"]; + auto mainNib = [[NSNib alloc] initWithNibNamed:mainNibName bundle:base::mac::FrameworkBundle()]; + [mainNib instantiateNibWithOwner:application topLevelObjects:nil]; + [mainNib release]; +} + +} diff --git a/brightray/browser/mac/bry_application.h b/brightray/browser/mac/bry_application.h new file mode 100644 index 0000000000..f64d5db4e3 --- /dev/null +++ b/brightray/browser/mac/bry_application.h @@ -0,0 +1,7 @@ +#import "base/mac/scoped_sending_event.h" + +@interface BRYApplication : NSApplication { + BOOL _handlingSendEvent; +} + +@end diff --git a/brightray/browser/mac/bry_application.mm b/brightray/browser/mac/bry_application.mm new file mode 100644 index 0000000000..aca8392bc3 --- /dev/null +++ b/brightray/browser/mac/bry_application.mm @@ -0,0 +1,19 @@ +#import "bry_application.h" + +@interface BRYApplication () + +@property (nonatomic, assign, getter = isHandlingSendEvent) BOOL handlingSendEvent; + +@end + +@implementation BRYApplication + +@synthesize handlingSendEvent = _handlingSendEvent; + +- (void)sendEvent:(NSEvent *)theEvent +{ + base::mac::ScopedSendingEvent scopedSendingEvent; + [super sendEvent:theEvent]; +} + +@end diff --git a/brightray/browser/network_delegate.cc b/brightray/browser/network_delegate.cc new file mode 100644 index 0000000000..8213a744ed --- /dev/null +++ b/brightray/browser/network_delegate.cc @@ -0,0 +1,105 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#include "network_delegate.h" + +#include "net/base/net_errors.h" + +namespace brightray { + +NetworkDelegate::NetworkDelegate() { +} + +NetworkDelegate::~NetworkDelegate() { +} + +int NetworkDelegate::OnBeforeURLRequest( + net::URLRequest* request, + const net::CompletionCallback& callback, + GURL* new_url) { + return net::OK; +} + +int NetworkDelegate::OnBeforeSendHeaders( + net::URLRequest* request, + const net::CompletionCallback& callback, + net::HttpRequestHeaders* headers) { + return net::OK; +} + +void NetworkDelegate::OnSendHeaders( + net::URLRequest* request, + const net::HttpRequestHeaders& headers) { +} + +int NetworkDelegate::OnHeadersReceived( + net::URLRequest* request, + const net::CompletionCallback& callback, + const net::HttpResponseHeaders* original_response_headers, + scoped_refptr* override_response_headers) { + return net::OK; +} + +void NetworkDelegate::OnBeforeRedirect(net::URLRequest* request, + const GURL& new_location) { +} + +void NetworkDelegate::OnResponseStarted(net::URLRequest* request) { +} + +void NetworkDelegate::OnRawBytesRead(const net::URLRequest& request, + int bytes_read) { +} + +void NetworkDelegate::OnCompleted(net::URLRequest* request, bool started) { +} + +void NetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) { +} + +void NetworkDelegate::OnPACScriptError(int line_number, + const string16& error) { +} + +NetworkDelegate::AuthRequiredResponse NetworkDelegate::OnAuthRequired( + net::URLRequest* request, + const net::AuthChallengeInfo& auth_info, + const AuthCallback& callback, + net::AuthCredentials* credentials) { + return AUTH_REQUIRED_RESPONSE_NO_ACTION; +} + +bool NetworkDelegate::OnCanGetCookies(const net::URLRequest& request, + const net::CookieList& cookie_list) { + return true; +} + +bool NetworkDelegate::OnCanSetCookie(const net::URLRequest& request, + const std::string& cookie_line, + net::CookieOptions* options) { + return true; +} + +bool NetworkDelegate::OnCanAccessFile(const net::URLRequest& request, + const base::FilePath& path) const { + return true; +} + +bool NetworkDelegate::OnCanThrottleRequest( + const net::URLRequest& request) const { + return false; +} + +int NetworkDelegate::OnBeforeSocketStreamConnect( + net::SocketStream* socket, + const net::CompletionCallback& callback) { + return net::OK; +} + +void NetworkDelegate::OnRequestWaitStateChange( + const net::URLRequest& request, + RequestWaitState waiting) { +} + +} diff --git a/brightray/browser/network_delegate.h b/brightray/browser/network_delegate.h new file mode 100644 index 0000000000..54c98dca31 --- /dev/null +++ b/brightray/browser/network_delegate.h @@ -0,0 +1,41 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#ifndef __brightray__network_delegate__ +#define __brightray__network_delegate__ + +#include "net/base/network_delegate.h" + +namespace brightray { + +class NetworkDelegate : public net::NetworkDelegate { +public: + NetworkDelegate(); + virtual ~NetworkDelegate(); + +private: + virtual int OnBeforeURLRequest(net::URLRequest* request, const net::CompletionCallback& callback, GURL* new_url) OVERRIDE; + virtual int OnBeforeSendHeaders(net::URLRequest* request, const net::CompletionCallback& callback, net::HttpRequestHeaders* headers) OVERRIDE; + virtual void OnSendHeaders(net::URLRequest* request, const net::HttpRequestHeaders& headers) OVERRIDE; + virtual int OnHeadersReceived(net::URLRequest* request, const net::CompletionCallback& callback, const net::HttpResponseHeaders* original_response_headers, scoped_refptr* override_response_headers) OVERRIDE; + virtual void OnBeforeRedirect(net::URLRequest* request, const GURL& new_location) OVERRIDE; + virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE; + virtual void OnRawBytesRead(const net::URLRequest& request, int bytes_read) OVERRIDE; + virtual void OnCompleted(net::URLRequest* request, bool started) OVERRIDE; + virtual void OnURLRequestDestroyed(net::URLRequest* request) OVERRIDE; + virtual void OnPACScriptError(int line_number, const string16& error) OVERRIDE; + virtual AuthRequiredResponse OnAuthRequired(net::URLRequest* request, const net::AuthChallengeInfo& auth_info, const AuthCallback& callback, net::AuthCredentials* credentials) OVERRIDE; + virtual bool OnCanGetCookies(const net::URLRequest& request, const net::CookieList& cookie_list) OVERRIDE; + virtual bool OnCanSetCookie(const net::URLRequest& request, const std::string& cookie_line, net::CookieOptions* options) OVERRIDE; + virtual bool OnCanAccessFile(const net::URLRequest& request, const base::FilePath& path) const OVERRIDE; + virtual bool OnCanThrottleRequest(const net::URLRequest& request) const OVERRIDE; + virtual int OnBeforeSocketStreamConnect(net::SocketStream* stream, const net::CompletionCallback& callback) OVERRIDE; + virtual void OnRequestWaitStateChange(const net::URLRequest& request, RequestWaitState state) OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(NetworkDelegate); +}; + +} + +#endif /* defined(__brightray__network_delegate__) */ diff --git a/brightray/browser/url_request_context_getter.cc b/brightray/browser/url_request_context_getter.cc new file mode 100644 index 0000000000..137d6a90f8 --- /dev/null +++ b/brightray/browser/url_request_context_getter.cc @@ -0,0 +1,137 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#include "url_request_context_getter.h" + +#include "network_delegate.h" +#include "base/string_util.h" +#include "base/threading/worker_pool.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/common/url_constants.h" +#include "net/base/cert_verifier.h" +#include "net/base/default_server_bound_cert_store.h" +#include "net/base/server_bound_cert_service.h" +#include "net/base/ssl_config_service_defaults.h" +#include "net/cookies/cookie_monster.h" +#include "net/http/http_auth_handler_factory.h" +#include "net/http/http_cache.h" +#include "net/http/http_server_properties_impl.h" +#include "net/proxy/proxy_service.h" +#include "net/url_request/static_http_user_agent_settings.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_storage.h" +#include "net/url_request/url_request_job_factory_impl.h" + +namespace brightray { + +URLRequestContextGetter::URLRequestContextGetter( + const base::FilePath& base_path, + MessageLoop* io_loop, + MessageLoop* file_loop, + content::ProtocolHandlerMap* protocol_handlers) + : base_path_(base_path), + io_loop_(io_loop), + file_loop_(file_loop) { + // Must first be created on the UI thread. + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + + std::swap(protocol_handlers_, *protocol_handlers); + + proxy_config_service_.reset(net::ProxyService::CreateSystemProxyConfigService(io_loop_->message_loop_proxy(), file_loop_)); +} + +URLRequestContextGetter::~URLRequestContextGetter() { +} + +net::HostResolver* URLRequestContextGetter::host_resolver() { + return url_request_context_->host_resolver(); +} + +net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() +{ + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + + if (!url_request_context_.get()) { + url_request_context_.reset(new net::URLRequestContext()); + network_delegate_.reset(new NetworkDelegate); + url_request_context_->set_network_delegate(network_delegate_.get()); + storage_.reset( + new net::URLRequestContextStorage(url_request_context_.get())); + storage_->set_cookie_store(new net::CookieMonster(NULL, NULL)); + storage_->set_server_bound_cert_service(new net::ServerBoundCertService( + new net::DefaultServerBoundCertStore(NULL), + base::WorkerPool::GetTaskRunner(true))); + storage_->set_http_user_agent_settings( + new net::StaticHttpUserAgentSettings( + "en-us,en", "iso-8859-1,*,utf-8", EmptyString())); + + scoped_ptr host_resolver( + net::HostResolver::CreateDefaultResolver(NULL)); + + storage_->set_cert_verifier(net::CertVerifier::CreateDefault()); + // TODO(jam): use v8 if possible, look at chrome code. + storage_->set_proxy_service( + net::ProxyService::CreateUsingSystemProxyResolver( + proxy_config_service_.release(), + 0, + NULL)); + storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults); + storage_->set_http_auth_handler_factory( + net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get())); + storage_->set_http_server_properties(new net::HttpServerPropertiesImpl); + + base::FilePath cache_path = base_path_.Append(FILE_PATH_LITERAL("Cache")); + net::HttpCache::DefaultBackend* main_backend = + new net::HttpCache::DefaultBackend( + net::DISK_CACHE, + cache_path, + 0, + content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::CACHE)); + + net::HttpNetworkSession::Params network_session_params; + network_session_params.cert_verifier = + url_request_context_->cert_verifier(); + network_session_params.server_bound_cert_service = + url_request_context_->server_bound_cert_service(); + network_session_params.proxy_service = + url_request_context_->proxy_service(); + network_session_params.ssl_config_service = + url_request_context_->ssl_config_service(); + network_session_params.http_auth_handler_factory = + url_request_context_->http_auth_handler_factory(); + network_session_params.network_delegate = + url_request_context_->network_delegate(); + network_session_params.http_server_properties = + url_request_context_->http_server_properties(); + network_session_params.ignore_certificate_errors = false; + + // Give |storage_| ownership at the end in case it's |mapped_host_resolver|. + storage_->set_host_resolver(host_resolver.Pass()); + network_session_params.host_resolver = + url_request_context_->host_resolver(); + + net::HttpCache* main_cache = new net::HttpCache( + network_session_params, main_backend); + storage_->set_http_transaction_factory(main_cache); + + scoped_ptr job_factory( + new net::URLRequestJobFactoryImpl()); + for (auto& it : protocol_handlers_) { + bool set_protocol = job_factory->SetProtocolHandler(it.first, it.second.release()); + DCHECK(set_protocol); + } + protocol_handlers_.clear(); + storage_->set_job_factory(job_factory.release()); + } + + return url_request_context_.get(); +} + +scoped_refptr URLRequestContextGetter::GetNetworkTaskRunner() const +{ + return content::BrowserThread::GetMessageLoopProxyForThread(content::BrowserThread::IO); +} + +} diff --git a/brightray/browser/url_request_context_getter.h b/brightray/browser/url_request_context_getter.h new file mode 100644 index 0000000000..89db0ec5b7 --- /dev/null +++ b/brightray/browser/url_request_context_getter.h @@ -0,0 +1,54 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#ifndef __brightray__url_request_context_getter__ +#define __brightray__url_request_context_getter__ + +#include "base/files/file_path.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/browser/content_browser_client.h" +#include "net/url_request/url_request_context_getter.h" + +class MessageLoop; + +namespace net { +class HostResolver; +class NetworkDelegate; +class ProxyConfigService; +class URLRequestContextStorage; +} + +namespace brightray { + +class URLRequestContextGetter : public net::URLRequestContextGetter { +public: + URLRequestContextGetter( + const base::FilePath& base_path, + MessageLoop* io_loop, + MessageLoop* file_loop, + content::ProtocolHandlerMap*); + virtual ~URLRequestContextGetter(); + + net::HostResolver* host_resolver(); + virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE; + +private: + virtual scoped_refptr GetNetworkTaskRunner() const OVERRIDE; + + base::FilePath base_path_; + MessageLoop* io_loop_; + MessageLoop* file_loop_; + + scoped_ptr proxy_config_service_; + scoped_ptr network_delegate_; + scoped_ptr storage_; + scoped_ptr url_request_context_; + content::ProtocolHandlerMap protocol_handlers_; + + DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter); +}; + +} + +#endif /* defined(__brightray__url_request_context_getter__) */ diff --git a/brightray/common/main_delegate.cc b/brightray/common/main_delegate.cc new file mode 100644 index 0000000000..2eb3141a21 --- /dev/null +++ b/brightray/common/main_delegate.cc @@ -0,0 +1,29 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#include "main_delegate.h" + +#include "browser_client.h" +#include "base/command_line.h" +#include "content/public/common/content_switches.h" + +namespace brightray { + +MainDelegate::MainDelegate() { +} + +MainDelegate::~MainDelegate() { +} + +void MainDelegate::PreSandboxStartup() { + // FIXME: We don't currently support running sandboxed. + CommandLine::ForCurrentProcess()->AppendSwitch(switches::kNoSandbox); + +#if defined(OS_MACOSX) + OverrideChildProcessPath(); + OverrideFrameworkBundlePath(); +#endif +} + +} diff --git a/brightray/common/main_delegate.h b/brightray/common/main_delegate.h new file mode 100644 index 0000000000..9b56a7939e --- /dev/null +++ b/brightray/common/main_delegate.h @@ -0,0 +1,31 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#ifndef __brightray__main_delegate__ +#define __brightray__main_delegate__ + +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/app/content_main_delegate.h" + +namespace brightray { + +class MainDelegate : public content::ContentMainDelegate { +public: + MainDelegate(); + ~MainDelegate(); + +private: +#if defined(OS_MACOSX) + static void OverrideChildProcessPath(); + static void OverrideFrameworkBundlePath(); +#endif + + virtual void PreSandboxStartup() OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(MainDelegate); +}; + +} +#endif /* defined(__brightray__main_delegate__) */ diff --git a/brightray/common/main_delegate_mac.mm b/brightray/common/main_delegate_mac.mm new file mode 100644 index 0000000000..e91312ef44 --- /dev/null +++ b/brightray/common/main_delegate_mac.mm @@ -0,0 +1,59 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2013 Adam Roben . All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#import "main_delegate.h" + +#include "base/mac/bundle_locations.h" +#include "base/mac/foundation_util.h" +#include "base/path_service.h" +#include "content/public/common/content_paths.h" + +namespace brightray { + +namespace { + +base::FilePath GetFrameworksPath() { + // Start out with the path to the running executable. + base::FilePath path; + PathService::Get(base::FILE_EXE, &path); + + // Up to Contents. + if (base::mac::IsBackgroundOnlyProcess()) { + // The running executable is the helper. Go up five steps: + // Contents/Frameworks/Helper.app/Contents/MacOS/Helper + // ^ to here ^ from here + path = path.DirName().DirName().DirName().DirName().DirName(); + } else { + // One step up to MacOS, another to Contents. + path = path.DirName().DirName(); + } + DCHECK_EQ(path.BaseName().value(), "Contents"); + + // Go into the frameworks directory. + return path.Append("Frameworks"); +} + +std::string OuterBundleName() { + return [[base::mac::OuterBundle().infoDictionary objectForKey:base::mac::CFToNSCast(kCFBundleNameKey)] UTF8String]; +} + +} + +void MainDelegate::OverrideFrameworkBundlePath() { + base::FilePath helper_path = GetFrameworksPath().Append(OuterBundleName() + ".framework"); + + base::mac::SetOverrideFrameworkBundlePath(helper_path); +} + +void MainDelegate::OverrideChildProcessPath() { + base::FilePath helper_path = GetFrameworksPath().Append(OuterBundleName() + " Helper.app") + .Append("Contents") + .Append("MacOS") + .Append(OuterBundleName() + " Helper"); + + PathService::Override(content::CHILD_PROCESS_EXE, helper_path); +} + +} diff --git a/brightray/script/bootstrap b/brightray/script/bootstrap new file mode 100755 index 0000000000..057a65f314 --- /dev/null +++ b/brightray/script/bootstrap @@ -0,0 +1,26 @@ +#!/bin/sh +#/ Usage: bootstrap https://base.url.com/from/libchromiumcontent/script/upload +#/ Bootstrap this project. + +set -e + +usage() { + grep '^#/' <"$0"| cut -c4- +} + +BASE_URL="${1}" + +if [ -z "${BASE_URL}" ]; then + usage + exit 1 +fi + +cd "$(dirname "$0")/.." + +git submodule sync --quiet +git submodule update --init --recursive + +SOURCE_ROOT="$(pwd -P)" +DOWNLOAD_DIR="${SOURCE_ROOT}/vendor/download" +mkdir -p "${DOWNLOAD_DIR}" +vendor/libchromiumcontent/script/download "${BASE_URL}" "${DOWNLOAD_DIR}/libchromiumcontent" diff --git a/brightray/script/build b/brightray/script/build new file mode 100755 index 0000000000..515feb65f0 --- /dev/null +++ b/brightray/script/build @@ -0,0 +1,8 @@ +#!/bin/sh + +set -e + +cd "$(dirname "$0")/.." + +gyp --depth . brightray.gyp +xcodebuild diff --git a/brightray/tools/mac/change_mach_o_flags.py b/brightray/tools/mac/change_mach_o_flags.py new file mode 100755 index 0000000000..4547cb75f7 --- /dev/null +++ b/brightray/tools/mac/change_mach_o_flags.py @@ -0,0 +1,273 @@ +#!/usr/bin/env python +# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE-CHROMIUM file. + +"""Usage: change_mach_o_flags.py [--executable-heap] [--no-pie] + +Arranges for the executable at |executable_path| to have its data (heap) +pages protected to prevent execution on Mac OS X 10.7 ("Lion"), and to have +the PIE (position independent executable) bit set to enable ASLR (address +space layout randomization). With --executable-heap or --no-pie, the +respective bits are cleared instead of set, making the heap executable or +disabling PIE/ASLR. + +This script is able to operate on thin (single-architecture) Mach-O files +and fat (universal, multi-architecture) files. When operating on fat files, +it will set or clear the bits for each architecture contained therein. + +NON-EXECUTABLE HEAP + +Traditionally in Mac OS X, 32-bit processes did not have data pages set to +prohibit execution. Although user programs could call mprotect and +mach_vm_protect to deny execution of code in data pages, the kernel would +silently ignore such requests without updating the page tables, and the +hardware would happily execute code on such pages. 64-bit processes were +always given proper hardware protection of data pages. This behavior was +controllable on a system-wide level via the vm.allow_data_exec sysctl, which +is set by default to 1. The bit with value 1 (set by default) allows code +execution on data pages for 32-bit processes, and the bit with value 2 +(clear by default) does the same for 64-bit processes. + +In Mac OS X 10.7, executables can "opt in" to having hardware protection +against code execution on data pages applied. This is done by setting a new +bit in the |flags| field of an executable's |mach_header|. When +MH_NO_HEAP_EXECUTION is set, proper protections will be applied, regardless +of the setting of vm.allow_data_exec. See xnu-1699.22.73/osfmk/vm/vm_map.c +override_nx and xnu-1699.22.73/bsd/kern/mach_loader.c load_machfile. + +The Apple toolchain has been revised to set the MH_NO_HEAP_EXECUTION when +producing executables, provided that -allow_heap_execute is not specified +at link time. Only linkers shipping with Xcode 4.0 and later (ld64-123.2 and +later) have this ability. See ld64-123.2.1/src/ld/Options.cpp +Options::reconfigureDefaults() and +ld64-123.2.1/src/ld/HeaderAndLoadCommands.hpp +HeaderAndLoadCommandsAtom::flags(). + +This script sets the MH_NO_HEAP_EXECUTION bit on Mach-O executables. It is +intended for use with executables produced by a linker that predates Apple's +modifications to set this bit itself. It is also useful for setting this bit +for non-i386 executables, including x86_64 executables. Apple's linker only +sets it for 32-bit i386 executables, presumably under the assumption that +the value of vm.allow_data_exec is set in stone. However, if someone were to +change vm.allow_data_exec to 2 or 3, 64-bit x86_64 executables would run +without hardware protection against code execution on data pages. This +script can set the bit for x86_64 executables, guaranteeing that they run +with appropriate protection even when vm.allow_data_exec has been tampered +with. + +POSITION-INDEPENDENT EXECUTABLES/ADDRESS SPACE LAYOUT RANDOMIZATION + +This script sets or clears the MH_PIE bit in an executable's Mach-O header, +enabling or disabling position independence on Mac OS X 10.5 and later. +Processes running position-independent executables have varying levels of +ASLR protection depending on the OS release. The main executable's load +address, shared library load addresess, and the heap and stack base +addresses may be randomized. Position-independent executables are produced +by supplying the -pie flag to the linker (or defeated by supplying -no_pie). +Executables linked with a deployment target of 10.7 or higher have PIE on +by default. + +This script is never strictly needed during the build to enable PIE, as all +linkers used are recent enough to support -pie. However, it's used to +disable the PIE bit as needed on already-linked executables. +""" + +import optparse +import os +import struct +import sys + + +# +FAT_MAGIC = 0xcafebabe +FAT_CIGAM = 0xbebafeca + +# +MH_MAGIC = 0xfeedface +MH_CIGAM = 0xcefaedfe +MH_MAGIC_64 = 0xfeedfacf +MH_CIGAM_64 = 0xcffaedfe +MH_EXECUTE = 0x2 +MH_PIE = 0x00200000 +MH_NO_HEAP_EXECUTION = 0x01000000 + + +class MachOError(Exception): + """A class for exceptions thrown by this module.""" + + pass + + +def CheckedSeek(file, offset): + """Seeks the file-like object at |file| to offset |offset| and raises a + MachOError if anything funny happens.""" + + file.seek(offset, os.SEEK_SET) + new_offset = file.tell() + if new_offset != offset: + raise MachOError, \ + 'seek: expected offset %d, observed %d' % (offset, new_offset) + + +def CheckedRead(file, count): + """Reads |count| bytes from the file-like |file| object, raising a + MachOError if any other number of bytes is read.""" + + bytes = file.read(count) + if len(bytes) != count: + raise MachOError, \ + 'read: expected length %d, observed %d' % (count, len(bytes)) + + return bytes + + +def ReadUInt32(file, endian): + """Reads an unsinged 32-bit integer from the file-like |file| object, + treating it as having endianness specified by |endian| (per the |struct| + module), and returns it as a number. Raises a MachOError if the proper + length of data can't be read from |file|.""" + + bytes = CheckedRead(file, 4) + + (uint32,) = struct.unpack(endian + 'I', bytes) + return uint32 + + +def ReadMachHeader(file, endian): + """Reads an entire |mach_header| structure () from the + file-like |file| object, treating it as having endianness specified by + |endian| (per the |struct| module), and returns a 7-tuple of its members + as numbers. Raises a MachOError if the proper length of data can't be read + from |file|.""" + + bytes = CheckedRead(file, 28) + + magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags = \ + struct.unpack(endian + '7I', bytes) + return magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags + + +def ReadFatArch(file): + """Reads an entire |fat_arch| structure () from the file-like + |file| object, treating it as having endianness specified by |endian| + (per the |struct| module), and returns a 5-tuple of its members as numbers. + Raises a MachOError if the proper length of data can't be read from + |file|.""" + + bytes = CheckedRead(file, 20) + + cputype, cpusubtype, offset, size, align = struct.unpack('>5I', bytes) + return cputype, cpusubtype, offset, size, align + + +def WriteUInt32(file, uint32, endian): + """Writes |uint32| as an unsinged 32-bit integer to the file-like |file| + object, treating it as having endianness specified by |endian| (per the + |struct| module).""" + + bytes = struct.pack(endian + 'I', uint32) + assert len(bytes) == 4 + + file.write(bytes) + + +def HandleMachOFile(file, options, offset=0): + """Seeks the file-like |file| object to |offset|, reads its |mach_header|, + and rewrites the header's |flags| field if appropriate. The header's + endianness is detected. Both 32-bit and 64-bit Mach-O headers are supported + (mach_header and mach_header_64). Raises MachOError if used on a header that + does not have a known magic number or is not of type MH_EXECUTE. The + MH_PIE and MH_NO_HEAP_EXECUTION bits are set or cleared in the |flags| field + according to |options| and written to |file| if any changes need to be made. + If already set or clear as specified by |options|, nothing is written.""" + + CheckedSeek(file, offset) + magic = ReadUInt32(file, '<') + if magic == MH_MAGIC or magic == MH_MAGIC_64: + endian = '<' + elif magic == MH_CIGAM or magic == MH_CIGAM_64: + endian = '>' + else: + raise MachOError, \ + 'Mach-O file at offset %d has illusion of magic' % offset + + CheckedSeek(file, offset) + magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags = \ + ReadMachHeader(file, endian) + assert magic == MH_MAGIC or magic == MH_MAGIC_64 + if filetype != MH_EXECUTE: + raise MachOError, \ + 'Mach-O file at offset %d is type 0x%x, expected MH_EXECUTE' % \ + (offset, filetype) + + original_flags = flags + + if options.no_heap_execution: + flags |= MH_NO_HEAP_EXECUTION + else: + flags &= ~MH_NO_HEAP_EXECUTION + + if options.pie: + flags |= MH_PIE + else: + flags &= ~MH_PIE + + if flags != original_flags: + CheckedSeek(file, offset + 24) + WriteUInt32(file, flags, endian) + + +def HandleFatFile(file, options, fat_offset=0): + """Seeks the file-like |file| object to |offset| and loops over its + |fat_header| entries, calling HandleMachOFile for each.""" + + CheckedSeek(file, fat_offset) + magic = ReadUInt32(file, '>') + assert magic == FAT_MAGIC + + nfat_arch = ReadUInt32(file, '>') + + for index in xrange(0, nfat_arch): + cputype, cpusubtype, offset, size, align = ReadFatArch(file) + assert size >= 28 + + # HandleMachOFile will seek around. Come back here after calling it, in + # case it sought. + fat_arch_offset = file.tell() + HandleMachOFile(file, options, offset) + CheckedSeek(file, fat_arch_offset) + + +def main(me, args): + parser = optparse.OptionParser('%prog [options] ') + parser.add_option('--executable-heap', action='store_false', + dest='no_heap_execution', default=True, + help='Clear the MH_NO_HEAP_EXECUTION bit') + parser.add_option('--no-pie', action='store_false', + dest='pie', default=True, + help='Clear the MH_PIE bit') + (options, loose_args) = parser.parse_args(args) + if len(loose_args) != 1: + parser.print_usage() + return 1 + + executable_path = loose_args[0] + executable_file = open(executable_path, 'rb+') + + magic = ReadUInt32(executable_file, '<') + if magic == FAT_CIGAM: + # Check FAT_CIGAM and not FAT_MAGIC because the read was little-endian. + HandleFatFile(executable_file, options) + elif magic == MH_MAGIC or magic == MH_CIGAM or \ + magic == MH_MAGIC_64 or magic == MH_CIGAM_64: + HandleMachOFile(executable_file, options) + else: + raise MachOError, '%s is not a Mach-O or fat file' % executable_file + + executable_file.close() + return 0 + + +if __name__ == '__main__': + sys.exit(main(sys.argv[0], sys.argv[1:])) diff --git a/brightray/tools/mac/make_more_helpers.sh b/brightray/tools/mac/make_more_helpers.sh new file mode 100755 index 0000000000..ee4f21105b --- /dev/null +++ b/brightray/tools/mac/make_more_helpers.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE-CHROMIUM file. + +# Usage: make_more_helpers.sh +# +# This script creates additional helper .app bundles for Chromium, based on +# the existing helper .app bundle, changing their Mach-O header's flags to +# enable and disable various features. Based on Chromium Helper.app, it will +# create Chromium Helper EH.app, which has the MH_NO_HEAP_EXECUTION bit +# cleared to support Chromium child processes that require an executable heap, +# and Chromium Helper NP.app, which has the MH_PIE bit cleared to support +# Chromium child processes that cannot tolerate ASLR. +# +# This script expects to be called from the chrome_exe target as a postbuild, +# and operates directly within the built-up browser app's versioned directory. +# +# Each helper is adjusted by giving it the proper bundle name, renaming the +# executable, adjusting several Info.plist keys, and changing the executable's +# Mach-O flags. + +set -eu + +make_helper() { + local containing_dir="${1}" + local app_name="${2}" + local feature="${3}" + local flags="${4}" + + local helper_name="${app_name} Helper" + local helper_stem="${containing_dir}/${helper_name}" + local original_helper="${helper_stem}.app" + if [[ ! -d "${original_helper}" ]]; then + echo "${0}: error: ${original_helper} is a required directory" >& 2 + exit 1 + fi + local original_helper_exe="${original_helper}/Contents/MacOS/${helper_name}" + if [[ ! -f "${original_helper_exe}" ]]; then + echo "${0}: error: ${original_helper_exe} is a required file" >& 2 + exit 1 + fi + + local feature_helper="${helper_stem} ${feature}.app" + + rsync -acC --delete --include '*.so' "${original_helper}/" "${feature_helper}" + + local helper_feature="${helper_name} ${feature}" + local helper_feature_exe="${feature_helper}/Contents/MacOS/${helper_feature}" + mv "${feature_helper}/Contents/MacOS/${helper_name}" "${helper_feature_exe}" + + local change_flags="$(dirname "${0}")/change_mach_o_flags.py" + "${change_flags}" ${flags} "${helper_feature_exe}" + + local feature_info="${feature_helper}/Contents/Info" + local feature_info_plist="${feature_info}.plist" + + defaults write "${feature_info}" "CFBundleDisplayName" "${helper_feature}" + defaults write "${feature_info}" "CFBundleExecutable" "${helper_feature}" + + cfbundleid="$(defaults read "${feature_info}" "CFBundleIdentifier")" + feature_cfbundleid="${cfbundleid}.${feature}" + defaults write "${feature_info}" "CFBundleIdentifier" "${feature_cfbundleid}" + + cfbundlename="$(defaults read "${feature_info}" "CFBundleName")" + feature_cfbundlename="${cfbundlename} ${feature}" + defaults write "${feature_info}" "CFBundleName" "${feature_cfbundlename}" + + # As usual, defaults might have put the plist into whatever format excites + # it, but Info.plists get converted back to the expected XML format. + plutil -convert xml1 "${feature_info_plist}" + + # `defaults` also changes the file permissions, so make the file + # world-readable again. + chmod a+r "${feature_info_plist}" +} + +if [[ ${#} -ne 2 ]]; then + echo "usage: ${0} " >& 2 + exit 1 +fi + +DIRECTORY_WITHIN_CONTENTS="${1}" +APP_NAME="${2}" + +CONTENTS_DIR="${BUILT_PRODUCTS_DIR}/${CONTENTS_FOLDER_PATH}" +CONTAINING_DIR="${CONTENTS_DIR}/${DIRECTORY_WITHIN_CONTENTS}" + +make_helper "${CONTAINING_DIR}" "${APP_NAME}" "EH" "--executable-heap" +make_helper "${CONTAINING_DIR}" "${APP_NAME}" "NP" "--no-pie" diff --git a/brightray/vendor/.gitignore b/brightray/vendor/.gitignore new file mode 100644 index 0000000000..0920e14cbc --- /dev/null +++ b/brightray/vendor/.gitignore @@ -0,0 +1 @@ +/download/ diff --git a/brightray/vendor/libchromiumcontent b/brightray/vendor/libchromiumcontent new file mode 160000 index 0000000000..3f6f01c46b --- /dev/null +++ b/brightray/vendor/libchromiumcontent @@ -0,0 +1 @@ +Subproject commit 3f6f01c46be61f36b4e25456bf2c0539ef4d77f3