15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_resource_protocols.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/memory/weak_ptr.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/threading/sequenced_worker_pool.h"
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/threading/thread_checker.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/file_util.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_file_job.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)base::FilePath ResolvePath(const GURL& url) {
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::FilePath root_path;
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PathService::Get(chrome::DIR_RESOURCES_EXTENSION, &root_path);
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return extensions::file_util::ExtensionResourceURLToFilePath(url, root_path);
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionResourcesJob : public net::URLRequestFileJob {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionResourcesJob(net::URLRequest* request,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        net::NetworkDelegate* network_delegate)
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      : net::URLRequestFileJob(
303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            request, network_delegate, base::FilePath(),
313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            content::BrowserThread::GetBlockingPool()->
323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                GetTaskRunnerWithShutdownBehavior(
333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        weak_ptr_factory_(this) {}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Start() OVERRIDE;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  virtual bool IsRedirectResponse(GURL* location,
395b892326406927b709cdaf6c384d4ababf456332Ben Murdoch                                  int* http_status_code) override;
405b892326406927b709cdaf6c384d4ababf456332Ben Murdoch
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~ExtensionResourcesJob() {}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void ResolvePathDone(const base::FilePath& resolved_path);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::WeakPtrFactory<ExtensionResourcesJob> weak_ptr_factory_;
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::ThreadChecker thread_checker_;
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ExtensionResourcesJob);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionResourcesJob::Start() {
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  content::BrowserThread::PostTaskAndReplyWithResult(
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::BrowserThread::FILE, FROM_HERE,
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&ResolvePath, request()->url()),
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&ExtensionResourcesJob::ResolvePathDone,
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          weak_ptr_factory_.GetWeakPtr()));
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635b892326406927b709cdaf6c384d4ababf456332Ben Murdochbool ExtensionResourcesJob::IsRedirectResponse(GURL* location,
645b892326406927b709cdaf6c384d4ababf456332Ben Murdoch                                               int* http_status_code) {
655b892326406927b709cdaf6c384d4ababf456332Ben Murdoch  return false;
665b892326406927b709cdaf6c384d4ababf456332Ben Murdoch}
675b892326406927b709cdaf6c384d4ababf456332Ben Murdoch
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ExtensionResourcesJob::ResolvePathDone(
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const base::FilePath& resolved_path) {
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  file_path_ = resolved_path;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestFileJob::Start();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionResourceProtocolHandler
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public net::URLRequestJobFactory::ProtocolHandler {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionResourceProtocolHandler() {}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ExtensionResourceProtocolHandler() {}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual net::URLRequestJob* MaybeCreateJob(
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::URLRequest* request,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::NetworkDelegate* network_delegate) const OVERRIDE;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ExtensionResourceProtocolHandler);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates URLRequestJobs for chrome-extension-resource:// URLs.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::URLRequestJob*
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionResourceProtocolHandler::MaybeCreateJob(
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequest* request, net::NetworkDelegate* network_delegate) const {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new ExtensionResourcesJob(request, network_delegate);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::URLRequestJobFactory::ProtocolHandler*
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CreateExtensionResourceProtocolHandler() {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new ExtensionResourceProtocolHandler();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
102