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