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.assign(header->front_as<char>(), header->size());
29
30 result.append("<script>start(");
31 base::EscapeJSONString(title, true, &result);
32 result.append(");</script>\n");
33
34 return result;
35 }
36
GetDirectoryListingEntry(const std::u16string & name,const std::string & raw_bytes,bool is_dir,int64_t size,base::Time modified)37 std::string GetDirectoryListingEntry(const std::u16string& name,
38 const std::string& raw_bytes,
39 bool is_dir,
40 int64_t size,
41 base::Time modified) {
42 std::string result;
43 result.append("<script>addRow(");
44 base::EscapeJSONString(name, true, &result);
45 result.append(",");
46 if (raw_bytes.empty()) {
47 base::EscapeJSONString(base::EscapePath(base::UTF16ToUTF8(name)), true,
48 &result);
49 } else {
50 base::EscapeJSONString(base::EscapePath(raw_bytes), true, &result);
51 }
52
53 if (is_dir) {
54 result.append(",1,");
55 } else {
56 result.append(",0,");
57 }
58
59 // Negative size means unknown or not applicable (e.g. directory).
60 std::stringstream raw_size_string_stream;
61 raw_size_string_stream << size << ",";
62 result.append(raw_size_string_stream.str());
63
64 std::u16string size_string;
65 if (size >= 0)
66 size_string = base::FormatBytesUnlocalized(size);
67 base::EscapeJSONString(size_string, true, &result);
68
69 result.append(",");
70
71 // |modified| can be NULL in FTP listings.
72 std::u16string modified_str;
73 if (modified.is_null()) {
74 result.append("0,");
75 } else {
76 std::stringstream raw_time_string_stream;
77 // Certain access paths can only get up to seconds resolution, so here we
78 // output the raw time value in seconds for consistency.
79 raw_time_string_stream << modified.InMillisecondsSinceUnixEpoch() /
80 base::Time::kMillisecondsPerSecond
81 << ",";
82 result.append(raw_time_string_stream.str());
83
84 modified_str = base::TimeFormatShortDateAndTime(modified);
85 }
86
87 base::EscapeJSONString(modified_str, true, &result);
88 result.append(");</script>\n");
89
90 return result;
91 }
92
GetParentDirectoryLink()93 std::string GetParentDirectoryLink() {
94 return std::string("<script>onHasParentDirectory();</script>\n");
95 }
96
97 } // namespace net
98