1// Copyright 2014 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 NET_BASE_FILENAME_UTIL_H_
6#define NET_BASE_FILENAME_UTIL_H_
7
8#include <string>
9
10#include "base/strings/string16.h"
11#include "net/base/net_export.h"
12
13class GURL;
14
15namespace base {
16class FilePath;
17}
18
19namespace  net {
20
21// Given the full path to a file name, creates a file: URL. The returned URL
22// may not be valid if the input is malformed.
23NET_EXPORT GURL FilePathToFileURL(const base::FilePath& path);
24
25// Converts a file: URL back to a filename that can be passed to the OS. The
26// file URL must be well-formed (GURL::is_valid() must return true); we don't
27// handle degenerate cases here. Returns true on success, false if it isn't a
28// valid file URL. On failure, *file_path will be empty.
29NET_EXPORT bool FileURLToFilePath(const GURL& url, base::FilePath* file_path);
30
31// Generates a filename using the first successful method from the following (in
32// order):
33//
34// 1) The raw Content-Disposition header in |content_disposition| as read from
35//    the network.  |referrer_charset| is used to decode non-ASCII strings.
36// 2) |suggested_name| if specified.  |suggested_name| is assumed to be in
37//    UTF-8.
38// 3) The filename extracted from the |url|.  |referrer_charset| will be used to
39//    interpret the URL if there are non-ascii characters.
40// 4) |default_name|.  If non-empty, |default_name| is assumed to be a filename
41//    and shouldn't contain a path.  |default_name| is not subject to validation
42//    or sanitization, and therefore shouldn't be a user supplied string.
43// 5) The hostname portion from the |url|
44//
45// Then, leading and trailing '.'s will be removed.  On Windows, trailing spaces
46// are also removed.  The string "download" is the final fallback if no filename
47// is found or the filename is empty.
48//
49// Any illegal characters in the filename will be replaced by '-'.  If the
50// filename doesn't contain an extension, and a |mime_type| is specified, the
51// preferred extension for the |mime_type| will be appended to the filename.
52// The resulting filename is then checked against a list of reserved names on
53// Windows.  If the name is reserved, an underscore will be prepended to the
54// filename.
55//
56// Note: |mime_type| should only be specified if this function is called from a
57// thread that allows IO.
58NET_EXPORT base::string16 GetSuggestedFilename(
59    const GURL& url,
60    const std::string& content_disposition,
61    const std::string& referrer_charset,
62    const std::string& suggested_name,
63    const std::string& mime_type,
64    const std::string& default_name);
65
66// Similar to GetSuggestedFilename(), but returns a FilePath.
67NET_EXPORT base::FilePath GenerateFileName(
68    const GURL& url,
69    const std::string& content_disposition,
70    const std::string& referrer_charset,
71    const std::string& suggested_name,
72    const std::string& mime_type,
73    const std::string& default_name);
74
75// Valid components:
76// * are not empty
77// * are not Windows reserved names (CON, NUL.zip, etc.)
78// * do not have trailing separators
79// * do not equal kCurrentDirectory
80// * do not reference the parent directory
81// * do not contain illegal characters
82// * do not end with Windows shell-integrated extensions (even on posix)
83// * do not begin with '.' (which would hide them in most file managers)
84// * do not end with ' ' or '.'
85NET_EXPORT bool IsSafePortablePathComponent(const base::FilePath& component);
86
87// Basenames of valid relative paths are IsSafePortableBasename(), and internal
88// path components of valid relative paths are valid path components as
89// described above IsSafePortableBasename(). Valid relative paths are not
90// absolute paths.
91NET_EXPORT bool IsSafePortableRelativePath(const base::FilePath& path);
92
93// Ensures that the filename and extension is safe to use in the filesystem.
94//
95// Assumes that |file_path| already contains a valid path or file name.  On
96// Windows if the extension causes the file to have an unsafe interaction with
97// the shell (see net_util::IsShellIntegratedExtension()), then it will be
98// replaced by the string 'download'.  If |file_path| doesn't contain an
99// extension or |ignore_extension| is true then the preferred extension, if one
100// exists, for |mime_type| will be used as the extension.
101//
102// On Windows, the filename will be checked against a set of reserved names, and
103// if so, an underscore will be prepended to the name.
104//
105// |file_name| can either be just the file name or it can be a full path to a
106// file.
107//
108// Note: |mime_type| should only be non-empty if this function is called from a
109// thread that allows IO.
110NET_EXPORT void GenerateSafeFileName(const std::string& mime_type,
111                                     bool ignore_extension,
112                                     base::FilePath* file_path);
113
114}  // namespace net
115
116#endif  // NET_BASE_FILENAME_UTIL_H_
117