@marcel91200 / caddy Mirror · read-only / commits / bd34cb6b
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 13, 01:45 UTC

fileserver: More filetypes for browse icons

Matthew Holt committed May 19, 2023 at 09:59 UTC bd34cb6b4e171567243ff541ca303ac32fec91d8
3 files changed +190 -26
modules/caddyhttp/fileserver/browse.go
+4 -4
@@ -93,7 +93,7 @@ func (fsrv *FileServer) serveBrowse(root, dirPath string, w http.ResponseWriter,
93 return caddyhttp.Error(http.StatusInternalServerError, err)
94 }
95
96 - fsrv.browseApplyQueryParams(w, r, &listing)
96 + fsrv.browseApplyQueryParams(w, r, listing)
97
98 buf := bufPool.Get().(*bytes.Buffer)
99 buf.Reset()
@@ -137,10 +137,10 @@ func (fsrv *FileServer) serveBrowse(root, dirPath string, w http.ResponseWriter,
137 return nil
138 }
139
140 -func (fsrv *FileServer) loadDirectoryContents(ctx context.Context, dir fs.ReadDirFile, root, urlPath string, repl *caddy.Replacer) (browseTemplateContext, error) {
140 +func (fsrv *FileServer) loadDirectoryContents(ctx context.Context, dir fs.ReadDirFile, root, urlPath string, repl *caddy.Replacer) (*browseTemplateContext, error) {
141 files, err := dir.ReadDir(10000) // TODO: this limit should probably be configurable
142 if err != nil && err != io.EOF {
143 - return browseTemplateContext{}, err
143 + return nil, err
144 }
145
146 // user can presumably browse "up" to parent folder if path is longer than "/"
@@ -237,7 +237,7 @@ func isSymlink(f fs.FileInfo) bool {
237 // features.
238 type templateContext struct {
239 templates.TemplateContext
240 - browseTemplateContext
240 + *browseTemplateContext
241 }
242
243 // bufPool is used to increase the efficiency of file listings.
modules/caddyhttp/fileserver/browse.html
+169 -7
@@ -4,9 +4,26 @@
4 <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
5 <path d="M9 3a1 1 0 0 1 .608 .206l.1 .087l2.706 2.707h6.586a3 3 0 0 1 2.995 2.824l.005 .176v8a3 3 0 0 1 -2.824 2.995l-.176 .005h-14a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-11a3 3 0 0 1 2.824 -2.995l.176 -.005h4z" stroke-width="0" fill="currentColor"></path>
6 </svg>
7 - {{- else if .HasExt ".jpg" ".jpeg" ".png" ".gif" ".webp"}}
8 - <img src="{{html .Name}}">
9 - {{- else if .HasExt ".mp4" ".mov" ".mpeg" ".avi" ".ogg" ".webm"}}
7 + {{- else if or (eq .Name "LICENSE") (eq .Name "README")}}
8 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-license" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
9 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
10 + <path d="M15 21h-9a3 3 0 0 1 -3 -3v-1h10v2a2 2 0 0 0 4 0v-14a2 2 0 1 1 2 2h-2m2 -4h-11a3 3 0 0 0 -3 3v11"></path>
11 + <path d="M9 7l4 0"></path>
12 + <path d="M9 11l4 0"></path>
13 + </svg>
14 + {{- else if .HasExt ".jpg" ".jpeg" ".png" ".gif" ".webp" ".tiff" ".bmp" ".heif" ".heic"}}
15 + {{- if eq .Tpl.Layout "grid"}}
16 + <img src="{{html .Name}}">
17 + {{- else}}
18 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-photo" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
19 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
20 + <path d="M15 8h.01"></path>
21 + <path d="M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12z"></path>
22 + <path d="M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5"></path>
23 + <path d="M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3"></path>
24 + </svg>
25 + {{- end}}
26 + {{- else if .HasExt ".mp4" ".mov" ".mpeg" ".mpg" ".avi" ".ogg" ".webm" ".mkv" ".vob" ".gifv" ".3gp"}}
27 <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-movie" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
28 <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
29 <path d="M4 4m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z"></path>
@@ -18,7 +35,7 @@
35 <path d="M16 8l4 0"></path>
36 <path d="M16 16l4 0"></path>
37 </svg>
21 - {{- else if .HasExt ".mp3" ".flac" ".wav" ".wma"}}
38 + {{- else if .HasExt ".mp3" ".m4a" ".aac" ".ogg" ".flac" ".wav" ".wma" ".midi" ".cda"}}
39 <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-music" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
40 <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
41 <path d="M6 17m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0"></path>
@@ -34,7 +51,7 @@
51 <path d="M17 12h3"></path>
52 <path d="M21 8h-4v8"></path>
53 </svg>
37 - {{- else if .HasExt ".txt"}}
54 + {{- else if .HasExt ".txt" ".doc" ".docx" ".odt" ".fodt" ".rtf"}}
55 <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-text" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
56 <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
57 <path d="M14 3v4a1 1 0 0 0 1 1h4"></path>
@@ -43,7 +60,27 @@
60 <path d="M9 13l6 0"></path>
61 <path d="M9 17l6 0"></path>
62 </svg>
46 - {{- else if .HasExt ".zip" ".gz" ".xz" ".tar"}}
63 + {{- else if .HasExt ".xls" ".xlsx" ".ods" ".fods"}}
64 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-spreadsheet" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
65 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
66 + <path d="M14 3v4a1 1 0 0 0 1 1h4"></path>
67 + <path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z"></path>
68 + <path d="M8 11h8v7h-8z"></path>
69 + <path d="M8 15h8"></path>
70 + <path d="M11 11v7"></path>
71 + </svg>
72 + {{- else if .HasExt ".ppt" ".pptx" ".odp" ".fodp"}}
73 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-presentation-analytics" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
74 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
75 + <path d="M9 12v-4"></path>
76 + <path d="M15 12v-2"></path>
77 + <path d="M12 12v-1"></path>
78 + <path d="M3 4h18"></path>
79 + <path d="M4 4v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-10"></path>
80 + <path d="M12 16v4"></path>
81 + <path d="M9 20h6"></path>
82 + </svg>
83 + {{- else if .HasExt ".zip" ".gz" ".xz" ".tar" ".7z" ".rar" ".xz" ".zst"}}
84 <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-zip" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
85 <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
86 <path d="M6 20.735a2 2 0 0 1 -1 -1.735v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2h-1"></path>
@@ -55,6 +92,59 @@
92 <path d="M11 13l-1 0"></path>
93 <path d="M13 15l-1 0"></path>
94 </svg>
95 + {{- else if .HasExt ".deb" ".dpkg"}}
96 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brand-debian" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
97 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
98 + <path d="M12 17c-2.397 -.943 -4 -3.153 -4 -5.635c0 -2.19 1.039 -3.14 1.604 -3.595c2.646 -2.133 6.396 -.27 6.396 3.23c0 2.5 -2.905 2.121 -3.5 1.5c-.595 -.621 -1 -1.5 -.5 -2.5"></path>
99 + <path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0"></path>
100 + </svg>
101 + {{- else if .HasExt ".rpm" ".exe" ".flatpak" ".appimage" ".jar" ".msi" ".apk"}}
102 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-package" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
103 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
104 + <path d="M12 3l8 4.5l0 9l-8 4.5l-8 -4.5l0 -9l8 -4.5"></path>
105 + <path d="M12 12l8 -4.5"></path>
106 + <path d="M12 12l0 9"></path>
107 + <path d="M12 12l-8 -4.5"></path>
108 + <path d="M16 5.25l-8 4.5"></path>
109 + </svg>
110 + {{- else if .HasExt ".ps1"}}
111 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brand-powershell" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
112 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
113 + <path d="M4.887 20h11.868c.893 0 1.664 -.665 1.847 -1.592l2.358 -12c.212 -1.081 -.442 -2.14 -1.462 -2.366a1.784 1.784 0 0 0 -.385 -.042h-11.868c-.893 0 -1.664 .665 -1.847 1.592l-2.358 12c-.212 1.081 .442 2.14 1.462 2.366c.127 .028 .256 .042 .385 .042z"></path>
114 + <path d="M9 8l4 4l-6 4"></path>
115 + <path d="M12 16h3"></path>
116 + </svg>
117 + {{- else if .HasExt ".py" ".pyc" ".pyo"}}
118 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brand-python" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
119 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
120 + <path d="M12 9h-7a2 2 0 0 0 -2 2v4a2 2 0 0 0 2 2h3"></path>
121 + <path d="M12 15h7a2 2 0 0 0 2 -2v-4a2 2 0 0 0 -2 -2h-3"></path>
122 + <path d="M8 9v-4a2 2 0 0 1 2 -2h4a2 2 0 0 1 2 2v5a2 2 0 0 1 -2 2h-4a2 2 0 0 0 -2 2v5a2 2 0 0 0 2 2h4a2 2 0 0 0 2 -2v-4"></path>
123 + <path d="M11 6l0 .01"></path>
124 + <path d="M13 18l0 .01"></path>
125 + </svg>
126 + {{- else if .HasExt ".bash" ".sh" ".com" ".bat" ".dll" ".so"}}
127 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-script" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
128 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
129 + <path d="M17 20h-11a3 3 0 0 1 0 -6h11a3 3 0 0 0 0 6h1a3 3 0 0 0 3 -3v-11a2 2 0 0 0 -2 -2h-10a2 2 0 0 0 -2 2v8"></path>
130 + </svg>
131 + {{- else if .HasExt ".dmg"}}
132 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brand-finder" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
133 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
134 + <path d="M3 4m0 1a1 1 0 0 1 1 -1h16a1 1 0 0 1 1 1v14a1 1 0 0 1 -1 1h-16a1 1 0 0 1 -1 -1z"></path>
135 + <path d="M7 8v1"></path>
136 + <path d="M17 8v1"></path>
137 + <path d="M12.5 4c-.654 1.486 -1.26 3.443 -1.5 9h2.5c-.19 2.867 .094 5.024 .5 7"></path>
138 + <path d="M7 15.5c3.667 2 6.333 2 10 0"></path>
139 + </svg>
140 + {{- else if .HasExt ".iso" ".img"}}
141 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-disc" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
142 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
143 + <path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0"></path>
144 + <path d="M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path>
145 + <path d="M7 12a5 5 0 0 1 5 -5"></path>
146 + <path d="M12 17a5 5 0 0 0 5 -5"></path>
147 + </svg>
148 {{- else if .HasExt ".md" ".mdown" ".markdown"}}
149 <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-markdown" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
150 <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
@@ -62,6 +152,15 @@
152 <path d="M7 15v-6l2 2l2 -2v6"></path>
153 <path d="M14 13l2 2l2 -2m-2 2v-6"></path>
154 </svg>
155 + {{- else if .HasExt ".ttf" ".otf" ".woff" ".woff2" ".eof"}}
156 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-typography" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
157 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
158 + <path d="M14 3v4a1 1 0 0 0 1 1h4"></path>
159 + <path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z"></path>
160 + <path d="M11 18h2"></path>
161 + <path d="M12 18v-7"></path>
162 + <path d="M9 12v-1h6v1"></path>
163 + </svg>
164 {{- else if .HasExt ".go"}}
165 <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brand-golang" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
166 <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
@@ -71,6 +170,69 @@
170 <path d="M6 9h-2"></path>
171 <path d="M5 12h-3"></path>
172 </svg>
173 + {{- else if .HasExt ".html" ".htm"}}
174 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-html" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
175 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
176 + <path d="M13 16v-8l2 5l2 -5v8"></path>
177 + <path d="M1 16v-8"></path>
178 + <path d="M5 8v8"></path>
179 + <path d="M1 12h4"></path>
180 + <path d="M7 8h4"></path>
181 + <path d="M9 8v8"></path>
182 + <path d="M20 8v8h3"></path>
183 + </svg>
184 + {{- else if .HasExt ".js"}}
185 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brand-javascript" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
186 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
187 + <path d="M20 4l-2 14.5l-6 2l-6 -2l-2 -14.5z"></path>
188 + <path d="M7.5 8h3v8l-2 -1"></path>
189 + <path d="M16.5 8h-2.5a.5 .5 0 0 0 -.5 .5v3a.5 .5 0 0 0 .5 .5h1.423a.5 .5 0 0 1 .495 .57l-.418 2.93l-2 .5"></path>
190 + </svg>
191 + {{- else if .HasExt ".json" ".json5" ".jsonc"}}
192 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-json" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
193 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
194 + <path d="M20 16v-8l3 8v-8"></path>
195 + <path d="M15 8a2 2 0 0 1 2 2v4a2 2 0 1 1 -4 0v-4a2 2 0 0 1 2 -2z"></path>
196 + <path d="M1 8h3v6.5a1.5 1.5 0 0 1 -3 0v-.5"></path>
197 + <path d="M7 15a1 1 0 0 0 1 1h1a1 1 0 0 0 1 -1v-2a1 1 0 0 0 -1 -1h-1a1 1 0 0 1 -1 -1v-2a1 1 0 0 1 1 -1h1a1 1 0 0 1 1 1"></path>
198 + </svg>
199 + {{- else if .HasExt ".sql"}}
200 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-sql" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
201 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
202 + <path d="M12 8a2 2 0 0 1 2 2v4a2 2 0 1 1 -4 0v-4a2 2 0 0 1 2 -2z"></path>
203 + <path d="M17 8v8h4"></path>
204 + <path d="M13 15l1 1"></path>
205 + <path d="M3 15a1 1 0 0 0 1 1h2a1 1 0 0 0 1 -1v-2a1 1 0 0 0 -1 -1h-2a1 1 0 0 1 -1 -1v-2a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1"></path>
206 + </svg>
207 + {{- else if .HasExt ".db" ".sqlite" ".bak" ".mdb"}}
208 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-database" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
209 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
210 + <path d="M12 6m-8 0a8 3 0 1 0 16 0a8 3 0 1 0 -16 0"></path>
211 + <path d="M4 6v6a8 3 0 0 0 16 0v-6"></path>
212 + <path d="M4 12v6a8 3 0 0 0 16 0v-6"></path>
213 + </svg>
214 + {{- else if .HasExt ".eml" ".email" ".mailbox" ".mbox" ".msg"}}
215 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-mail" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
216 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
217 + <path d="M3 7a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-10z"></path>
218 + <path d="M3 7l9 6l9 -6"></path>
219 + </svg>
220 + {{- else if .HasExt ".crt" ".pem" ".x509" ".cer" ".ca-bundle"}}
221 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-certificate" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
222 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
223 + <path d="M15 15m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0"></path>
224 + <path d="M13 17.5v4.5l2 -1.5l2 1.5v-4.5"></path>
225 + <path d="M10 19h-5a2 2 0 0 1 -2 -2v-10c0 -1.1 .9 -2 2 -2h14a2 2 0 0 1 2 2v10a2 2 0 0 1 -1 1.73"></path>
226 + <path d="M6 9l12 0"></path>
227 + <path d="M6 12l3 0"></path>
228 + <path d="M6 15l2 0"></path>
229 + </svg>
230 + {{- else if .HasExt ".key" ".keystore" ".jks" ".p12" ".pfx" ".pub"}}
231 + <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-key" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
232 + <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
233 + <path d="M16.555 3.843l3.602 3.602a2.877 2.877 0 0 1 0 4.069l-2.643 2.643a2.877 2.877 0 0 1 -4.069 0l-.301 -.301l-6.558 6.558a2 2 0 0 1 -1.239 .578l-.175 .008h-1.172a1 1 0 0 1 -.993 -.883l-.007 -.117v-1.172a2 2 0 0 1 .467 -1.284l.119 -.13l.414 -.414h2v-2h2v-2l2.144 -2.144l-.301 -.301a2.877 2.877 0 0 1 0 -4.069l2.643 -2.643a2.877 2.877 0 0 1 4.069 0z"></path>
234 + <path d="M15 9h.01"></path>
235 + </svg>
236 {{- else}}
237 {{- if .IsSymlink}}
238 <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-symlink" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
@@ -918,7 +1080,7 @@ footer {
1080 return;
1081 }
1082 }
921 - e.textContent = d.toLocaleString([], {day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit", second: "2-digit"});
1083 + e.textContent = d.toLocaleString();
1084 }
1085 var timeList = Array.prototype.slice.call(document.getElementsByTagName("time"));
1086 timeList.forEach(localizeDatetime);
modules/caddyhttp/fileserver/browsetplcontext.go
+17 -15
@@ -31,11 +31,16 @@ import (
31 "go.uber.org/zap"
32 )
33
34 -func (fsrv *FileServer) directoryListing(ctx context.Context, entries []fs.DirEntry, canGoUp bool, root, urlPath string, repl *caddy.Replacer) browseTemplateContext {
34 +func (fsrv *FileServer) directoryListing(ctx context.Context, entries []fs.DirEntry, canGoUp bool, root, urlPath string, repl *caddy.Replacer) *browseTemplateContext {
35 filesToHide := fsrv.transformHidePaths(repl)
36
37 - var dirCount, fileCount int
38 - fileInfos := []fileInfo{}
37 + name, _ := url.PathUnescape(urlPath)
38 +
39 + tplCtx := &browseTemplateContext{
40 + Name: path.Base(name),
41 + Path: urlPath,
42 + CanGoUp: canGoUp,
43 + }
44
45 for _, entry := range entries {
46 if err := ctx.Err(); err != nil {
@@ -61,9 +66,9 @@ func (fsrv *FileServer) directoryListing(ctx context.Context, entries []fs.DirEn
66 // add the slash after the escape of path to avoid escaping the slash as well
67 if isDir {
68 name += "/"
64 - dirCount++
69 + tplCtx.NumDirs++
70 } else {
66 - fileCount++
71 + tplCtx.NumFiles++
72 }
73
74 size := info.Size()
@@ -82,7 +87,7 @@ func (fsrv *FileServer) directoryListing(ctx context.Context, entries []fs.DirEn
87
88 u := url.URL{Path: "./" + name} // prepend with "./" to fix paths with ':' in the name
89
85 - fileInfos = append(fileInfos, fileInfo{
90 + tplCtx.Items = append(tplCtx.Items, fileInfo{
91 IsDir: isDir,
92 IsSymlink: fileIsSymlink,
93 Name: name,
@@ -90,17 +95,11 @@ func (fsrv *FileServer) directoryListing(ctx context.Context, entries []fs.DirEn
95 URL: u.String(),
96 ModTime: info.ModTime().UTC(),
97 Mode: info.Mode(),
98 + Tpl: tplCtx, // a reference up to the template context is useful
99 })
100 }
95 - name, _ := url.PathUnescape(urlPath)
96 - return browseTemplateContext{
97 - Name: path.Base(name),
98 - Path: urlPath,
99 - CanGoUp: canGoUp,
100 - Items: fileInfos,
101 - NumDirs: dirCount,
102 - NumFiles: fileCount,
103 - }
101 +
102 + return tplCtx
103 }
104
105 // browseTemplateContext provides the template context for directory listings.
@@ -230,6 +229,9 @@ type fileInfo struct {
229 Mode os.FileMode `json:"mode"`
230 IsDir bool `json:"is_dir"`
231 IsSymlink bool `json:"is_symlink"`
232 +
233 + // a pointer to the template context is useful inside nested templates
234 + Tpl *browseTemplateContext `json:"-"`
235 }
236
237 // HasExt returns true if the filename has any of the given suffixes, case-insensitive.