Skip to content

Commit 75d5c47

Browse files
committed
support 'app' protocol; Fix nwjs#363
app://<host>/path. The 'host' part is essential
1 parent 2646a00 commit 75d5c47

12 files changed

+124
-7
lines changed

nw.gypi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@
210210
'src/media/media_capture_devices_dispatcher.h',
211211
'src/media/media_stream_devices_controller.cc',
212212
'src/media/media_stream_devices_controller.h',
213+
'src/net/app_protocol_handler.cc',
214+
'src/net/app_protocol_handler.h',
213215
'src/net/clear_on_exit_policy.h',
214216
'src/net/clear_on_exit_policy.cc',
215217
'src/net/resource_request_job.cc',

src/net/app_protocol_handler.cc

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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
3+
// found in the LICENSE file.
4+
5+
#include "content/nw/src/net/app_protocol_handler.h"
6+
7+
#include "base/logging.h"
8+
#include "net/base/net_errors.h"
9+
#include "net/base/net_util.h"
10+
#include "net/url_request/url_request.h"
11+
#include "net/url_request/url_request_error_job.h"
12+
#include "net/url_request/url_request_file_dir_job.h"
13+
#include "net/url_request/url_request_file_job.h"
14+
15+
namespace net {
16+
17+
AppProtocolHandler::AppProtocolHandler(const base::FilePath& root)
18+
:root_path_(root)
19+
{
20+
}
21+
22+
URLRequestJob* AppProtocolHandler::MaybeCreateJob(
23+
URLRequest* request, NetworkDelegate* network_delegate) const {
24+
base::FilePath file_path;
25+
const bool is_file = FileURLToFilePath(request->url(), &file_path);
26+
27+
file_path = root_path_.Append(file_path);
28+
// Check file access permissions.
29+
if (!network_delegate ||
30+
!network_delegate->CanAccessFile(*request, file_path)) {
31+
return new URLRequestErrorJob(request, network_delegate, ERR_ACCESS_DENIED);
32+
}
33+
34+
// We need to decide whether to create URLRequestFileJob for file access or
35+
// URLRequestFileDirJob for directory access. To avoid accessing the
36+
// filesystem, we only look at the path string here.
37+
// The code in the URLRequestFileJob::Start() method discovers that a path,
38+
// which doesn't end with a slash, should really be treated as a directory,
39+
// and it then redirects to the URLRequestFileDirJob.
40+
if (is_file &&
41+
file_path.EndsWithSeparator() &&
42+
file_path.IsAbsolute()) {
43+
return new URLRequestFileDirJob(request, network_delegate, file_path);
44+
}
45+
46+
// Use a regular file request job for all non-directories (including invalid
47+
// file names).
48+
return new URLRequestFileJob(request, network_delegate, file_path);
49+
}
50+
51+
bool AppProtocolHandler::IsSafeRedirectTarget(const GURL& location) const {
52+
return false;
53+
}
54+
55+
} // namespace net

src/net/app_protocol_handler.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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
3+
// found in the LICENSE file.
4+
5+
#ifndef NW_APP_PROTOCOL_HANDLER_H_
6+
#define NW_APP_PROTOCOL_HANDLER_H_
7+
8+
#include "base/basictypes.h"
9+
#include "base/compiler_specific.h"
10+
#include "base/files/file_path.h"
11+
#include "net/url_request/url_request_job_factory.h"
12+
13+
class GURL;
14+
15+
namespace net {
16+
17+
class NetworkDelegate;
18+
class URLRequestJob;
19+
20+
// Implements a ProtocolHandler for File jobs. If |network_delegate_| is NULL,
21+
// then all file requests will fail with ERR_ACCESS_DENIED.
22+
class AppProtocolHandler :
23+
public URLRequestJobFactory::ProtocolHandler {
24+
public:
25+
AppProtocolHandler(const base::FilePath& root);
26+
virtual URLRequestJob* MaybeCreateJob(
27+
URLRequest* request, NetworkDelegate* network_delegate) const OVERRIDE;
28+
virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE;
29+
30+
private:
31+
base::FilePath root_path_;
32+
DISALLOW_COPY_AND_ASSIGN(AppProtocolHandler);
33+
};
34+
35+
} // namespace net
36+
37+
#endif

src/net/shell_url_request_context_getter.cc

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "content/public/common/url_constants.h"
2929
#include "content/nw/src/net/shell_network_delegate.h"
3030
#include "content/public/browser/cookie_store_factory.h"
31+
#include "content/nw/src/net/app_protocol_handler.h"
3132
#include "content/nw/src/nw_protocol_handler.h"
3233
#include "content/nw/src/nw_shell.h"
3334
#include "net/cert/cert_verifier.h"
@@ -77,12 +78,14 @@ void InstallProtocolHandlers(net::URLRequestJobFactoryImpl* job_factory,
7778

7879
ShellURLRequestContextGetter::ShellURLRequestContextGetter(
7980
bool ignore_certificate_errors,
80-
const FilePath& base_path,
81+
const FilePath& data_path,
82+
const FilePath& root_path,
8183
MessageLoop* io_loop,
8284
MessageLoop* file_loop,
8385
ProtocolHandlerMap* protocol_handlers)
8486
: ignore_certificate_errors_(ignore_certificate_errors),
85-
base_path_(base_path),
87+
data_path_(data_path),
88+
root_path_(root_path),
8689
io_loop_(io_loop),
8790
file_loop_(file_loop) {
8891
// Must first be created on the UI thread.
@@ -111,7 +114,7 @@ net::URLRequestContext* ShellURLRequestContextGetter::GetURLRequestContext() {
111114
storage_.reset(
112115
new net::URLRequestContextStorage(url_request_context_.get()));
113116

114-
FilePath cookie_path = base_path_.Append(FILE_PATH_LITERAL("cookies"));
117+
FilePath cookie_path = data_path_.Append(FILE_PATH_LITERAL("cookies"));
115118
scoped_refptr<net::CookieStore> cookie_store = NULL;
116119
cookie_store = content::CreatePersistentCookieStore(
117120
cookie_path,
@@ -149,7 +152,7 @@ net::URLRequestContext* ShellURLRequestContextGetter::GetURLRequestContext() {
149152
net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get()));
150153
storage_->set_http_server_properties(new net::HttpServerPropertiesImpl);
151154

152-
FilePath cache_path = base_path_.Append(FILE_PATH_LITERAL("Cache"));
155+
FilePath cache_path = data_path_.Append(FILE_PATH_LITERAL("Cache"));
153156
net::HttpCache::DefaultBackend* main_backend =
154157
new net::HttpCache::DefaultBackend(
155158
net::DISK_CACHE,
@@ -191,6 +194,8 @@ net::URLRequestContext* ShellURLRequestContextGetter::GetURLRequestContext() {
191194
InstallProtocolHandlers(job_factory.get(), &protocol_handlers_);
192195
job_factory->SetProtocolHandler(chrome::kFileScheme,
193196
new net::FileProtocolHandler);
197+
job_factory->SetProtocolHandler("app",
198+
new net::AppProtocolHandler(root_path_));
194199
job_factory->SetProtocolHandler("nw", new nw::NwProtocolHandler());
195200

196201
storage_->set_job_factory(job_factory.release());

src/net/shell_url_request_context_getter.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ class ShellURLRequestContextGetter : public net::URLRequestContextGetter {
4747
public:
4848
ShellURLRequestContextGetter(
4949
bool ignore_certificate_errors,
50-
const base::FilePath& base_path,
50+
const base::FilePath& data_path,
51+
const base::FilePath& root_path,
5152
base::MessageLoop* io_loop,
5253
base::MessageLoop* file_loop,
5354
ProtocolHandlerMap* protocol_handlers);
@@ -64,7 +65,8 @@ class ShellURLRequestContextGetter : public net::URLRequestContextGetter {
6465

6566
private:
6667
bool ignore_certificate_errors_;
67-
base::FilePath base_path_;
68+
base::FilePath data_path_;
69+
base::FilePath root_path_;
6870
base::MessageLoop* io_loop_;
6971
base::MessageLoop* file_loop_;
7072

src/nw_package.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ bool Package::GetImage(const FilePath& icon_path, gfx::Image* image) {
204204
}
205205

206206
GURL Package::GetStartupURL() {
207-
std::string url;
207+
std::string url;
208208
// Specify URL in --url
209209
CommandLine* command_line = CommandLine::ForCurrentProcess();
210210
if (command_line->HasSwitch(switches::kUrl)) {

src/nw_shell.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ void Shell::ShowDevTools(const char* jail_id, bool headless) {
367367

368368
int rh_id = shell->web_contents_->GetRenderProcessHost()->GetID();
369369
ChildProcessSecurityPolicyImpl::GetInstance()->GrantScheme(rh_id, chrome::kFileScheme);
370+
ChildProcessSecurityPolicyImpl::GetInstance()->GrantScheme(rh_id, "app");
370371
shell->is_devtools_ = true;
371372
shell->force_close_ = true;
372373
shell->LoadURL(url);

src/renderer/shell_content_renderer_client.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,10 @@ void ShellContentRendererClient::RenderThreadStarted() {
156156
shell_observer_.reset(new ShellRenderProcessObserver());
157157

158158
WebString file_scheme(ASCIIToUTF16("file"));
159+
WebString app_scheme(ASCIIToUTF16("app"));
159160
// file: resources should be allowed to receive CORS requests.
160161
WebSecurityPolicy::registerURLSchemeAsCORSEnabled(file_scheme);
162+
WebSecurityPolicy::registerURLSchemeAsCORSEnabled(app_scheme);
161163

162164
}
163165

src/shell_browser_context.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ net::URLRequestContextGetter* ShellBrowserContext::CreateRequestContext(
152152
url_request_getter_ = new ShellURLRequestContextGetter(
153153
ignore_certificate_errors_,
154154
GetPath(),
155+
package_->path(),
155156
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
156157
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE),
157158
protocol_handlers);

src/shell_content_browser_client.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,8 @@ void ShellContentBrowserClient::RenderProcessHostCreated(
289289
// per-view access checks.
290290
content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
291291
host->GetID(), chrome::kFileScheme);
292+
content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
293+
host->GetID(), "app");
292294

293295
#if defined(ENABLE_PRINTING)
294296
host->GetChannel()->AddFilter(new PrintingMessageFilter(id));
@@ -304,6 +306,7 @@ bool ShellContentBrowserClient::IsHandledURL(const GURL& url) {
304306
static const char* const kProtocolList[] = {
305307
chrome::kFileSystemScheme,
306308
chrome::kFileScheme,
309+
"app",
307310
};
308311
for (size_t i = 0; i < arraysize(kProtocolList); ++i) {
309312
if (url.scheme() == kProtocolList[i])

src/shell_content_client.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,10 @@ bool ShellContentClient::CanHandleWhileSwappedOut(
7878
return false;
7979
}
8080

81+
void ShellContentClient::AddAdditionalSchemes(
82+
std::vector<std::string>* standard_schemes,
83+
std::vector<std::string>* savable_schemes) {
84+
standard_schemes->push_back("app");
85+
}
86+
8187
} // namespace content

src/shell_content_client.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ class ShellContentClient : public ContentClient {
2626
int resource_id) const OVERRIDE;
2727
virtual gfx::Image& GetNativeImageNamed(int resource_id) const OVERRIDE;
2828
virtual bool CanHandleWhileSwappedOut(const IPC::Message& msg) OVERRIDE;
29+
virtual void AddAdditionalSchemes(
30+
std::vector<std::string>* standard_schemes,
31+
std::vector<std::string>* saveable_shemes) OVERRIDE;
2932
};
3033

3134
} // namespace content

0 commit comments

Comments
 (0)