1 // Copyright 2015 The Chromium Authors
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 "net/base/directory_listing.h"
6
7 #include "base/i18n/time_formatting.h"
8 #include "base/json/string_escape.h"
9 #include "base/logging.h"
10 #include "base/memory/ref_counted_memory.h"
11 #include "base/strings/escape.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/time/time.h"
15 #include "net/base/net_module.h"
16 #include "net/grit/net_resources.h"
17
18 namespace net {
19
GetDirectoryListingHeader(const std::u16string & title)20 std::string GetDirectoryListingHeader(const std::u16string& title) {
21 scoped_refptr<base::RefCountedMemory> header(
22 NetModule::GetResource(IDR_DIR_HEADER_HTML));
23 // This can be null in unit tests.
24 DLOG_IF(WARNING, !header) << "Missing resource: directory listing header";
25
26 std::string result;
27 if (header) {
28 result = base::as_string_view(*header);
29 }
30
31 result.append("<script>start(");
32 base::EscapeJSONString(title, true, &result);
33 result.append(");</script>\n");
34
35 return result;
36 }
37
GetDirectoryListingEntry(const std::u16string & name,const std::string & raw_bytes,bool is_dir,int64_t size,base::Time modified)38 std::string GetDirectoryListingEntry(const std::u16string& name,
39 const std::string& raw_bytes,
40 bool is_dir,
41 int64_t size,
42 base::Time modified) {
43 std::string result;
44 result.append("<script>addRow(");
45 base::EscapeJSONString(name, true, &result);
46 result.append(",");
47 if (raw_bytes.empty()) {
48 base::EscapeJSONString(base::EscapePath(base::UTF16ToUTF8(name)), true,
49 &result);
50 } else {
51 base::EscapeJSONString(base::EscapePath(raw_bytes), true, &result);
52 }
53
54 if (is_dir) {
55 result.append(",1,");
56 } else {
57 result.append(",0,");
58 }
59
60 // Negative size means unknown or not applicable (e.g. directory).
61 std::stringstream raw_size_string_stream;
62 raw_size_string_stream << size << ",";
63 result.append(raw_size_string_stream.str());
64
65 std::u16string size_string;
66 if (size >= 0)
67 size_string = base::FormatBytesUnlocalized(size);
68 base::EscapeJSONString(size_string, true, &result);
69
70 result.append(",");
71
72 // |modified| can be NULL in FTP listings.
73 std::u16string modified_str;
74 if (modified.is_null()) {
75 result.append("0,");
76 } else {
77 std::stringstream raw_time_string_stream;
78 // Certain access paths can only get up to seconds resolution, so here we
79 // output the raw time value in seconds for consistency.
80 raw_time_string_stream << modified.InMillisecondsSinceUnixEpoch() /
81 base::Time::kMillisecondsPerSecond
82 << ",";
83 result.append(raw_time_string_stream.str());
84
85 modified_str = base::TimeFormatShortDateAndTime(modified);
86 }
87
88 base::EscapeJSONString(modified_str, true, &result);
89 result.append(");</script>\n");
90
91 return result;
92 }
93
GetParentDirectoryLink()94 std::string GetParentDirectoryLink() {
95 return std::string("<script>onHasParentDirectory();</script>\n");
96 }
97
98 } // namespace net
99