xref: /aosp_15_r20/external/cronet/net/base/directory_listing.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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