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 "net/url_request/file_protocol_handler.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/task_runner.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_error_job.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_file_dir_job.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_file_job.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FileProtocolHandler::FileProtocolHandler(
193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const scoped_refptr<base::TaskRunner>& file_task_runner)
203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    : file_task_runner_(file_task_runner) {}
213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FileProtocolHandler::~FileProtocolHandler() {}
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestJob* FileProtocolHandler::MaybeCreateJob(
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLRequest* request, NetworkDelegate* network_delegate) const {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath file_path;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool is_file = FileURLToFilePath(request->url(), &file_path);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check file access permissions.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!network_delegate ||
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !network_delegate->CanAccessFile(*request, file_path)) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new URLRequestErrorJob(request, network_delegate, ERR_ACCESS_DENIED);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We need to decide whether to create URLRequestFileJob for file access or
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URLRequestFileDirJob for directory access. To avoid accessing the
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // filesystem, we only look at the path string here.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The code in the URLRequestFileJob::Start() method discovers that a path,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which doesn't end with a slash, should really be treated as a directory,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and it then redirects to the URLRequestFileDirJob.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_file &&
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      file_path.EndsWithSeparator() &&
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_path.IsAbsolute()) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new URLRequestFileDirJob(request, network_delegate, file_path);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use a regular file request job for all non-directories (including invalid
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file names).
493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return new URLRequestFileJob(request, network_delegate, file_path,
503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               file_task_runner_);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool FileProtocolHandler::IsSafeRedirectTarget(const GURL& location) const {
54b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return false;
55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
56b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
58