1
0
mirror of https://github.com/golang/go synced 2024-11-25 08:37:57 -07:00

nice directory listings

R=rsc
http://go/go-review/1026020
This commit is contained in:
Robert Griesemer 2009-11-07 21:12:46 -08:00
parent e67161ee3f
commit 171ef39949
2 changed files with 69 additions and 9 deletions

23
lib/godoc/listing.html Normal file
View File

@ -0,0 +1,23 @@
<!--
Copyright 2009 The Go Authors. All rights reserved.
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file.
-->
<p>
<table class="layout">
<tr>
<th align="left">File</th>
<th width="100" align="right">Size</th>
</tr>
<tr>
<td><a href=".." class="noline">..</a></td>
</tr>
{.repeated section @}
<tr>
<td align="left"><a href="{Name|html}" class="noline">{Name|html}</a></td>
<td align="right">{Size|html}</td>
</tr>
{.end}
</table>
</p>

View File

@ -554,6 +554,7 @@ func readTemplate(name string) *template.Template {
var ( var (
dirsHtml, dirsHtml,
godocHtml, godocHtml,
listingHtml,
packageHtml, packageHtml,
packageText, packageText,
parseerrorHtml, parseerrorHtml,
@ -566,6 +567,7 @@ func readTemplates() {
// so that main has chdir'ed to goroot. // so that main has chdir'ed to goroot.
dirsHtml = readTemplate("dirs.html"); dirsHtml = readTemplate("dirs.html");
godocHtml = readTemplate("godoc.html"); godocHtml = readTemplate("godoc.html");
listingHtml = readTemplate("listing.html");
packageHtml = readTemplate("package.html"); packageHtml = readTemplate("package.html");
packageText = readTemplate("package.txt"); packageText = readTemplate("package.txt");
parseerrorHtml = readTemplate("parseerror.html"); parseerrorHtml = readTemplate("parseerror.html");
@ -673,6 +675,36 @@ func serveGoSource(c *http.Conn, filename string, styler printer.Styler) {
} }
func redirect(c *http.Conn, r *http.Request) (redirected bool) {
if canonical := pathutil.Clean(r.Url.Path) + "/"; r.Url.Path != canonical {
http.Redirect(c, canonical, http.StatusMovedPermanently);
redirected = true;
}
return;
}
func serveDirectory(c *http.Conn, r *http.Request) {
if redirect(c, r) {
return;
}
path := pathutil.Join(".", r.Url.Path);
list, err := io.ReadDir(path);
if err != nil {
http.NotFound(c, r);
return;
}
var buf bytes.Buffer;
if err := listingHtml.Execute(list, &buf); err != nil {
log.Stderrf("listingHtml.Execute: %s", err);
}
servePage(c, "Directory " + path, "", buf.Bytes());
}
var fileServer = http.FileServer(".", "") var fileServer = http.FileServer(".", "")
func serveFile(c *http.Conn, r *http.Request) { func serveFile(c *http.Conn, r *http.Request) {
@ -694,9 +726,17 @@ func serveFile(c *http.Conn, r *http.Request) {
serveGoSource(c, path, &Styler{highlight: r.FormValue("h")}); serveGoSource(c, path, &Styler{highlight: r.FormValue("h")});
default: default:
// TODO: dir, err := os.Lstat(pathutil.Join(".", path));
// - need to decide what to serve and what not to serve if err != nil {
// - don't want to download files, want to see them http.NotFound(c, r);
return;
}
if dir != nil && dir.IsDirectory() {
serveDirectory(c, r);
return;
}
fileServer.ServeHTTP(c, r); fileServer.ServeHTTP(c, r);
} }
} }
@ -783,15 +823,12 @@ func (h *httpHandler) getPageInfo(path string) PageInfo {
func (h *httpHandler) ServeHTTP(c *http.Conn, r *http.Request) { func (h *httpHandler) ServeHTTP(c *http.Conn, r *http.Request) {
path := r.Url.Path; if redirect(c, r) {
path = path[len(h.pattern):len(path)];
// canonicalize URL path and redirect if necessary
if canonical := pathutil.Clean(h.pattern + path) + "/"; r.Url.Path != canonical {
http.Redirect(c, canonical, http.StatusMovedPermanently);
return; return;
} }
path := r.Url.Path;
path = path[len(h.pattern):len(path)];
info := h.getPageInfo(path); info := h.getPageInfo(path);
var buf bytes.Buffer; var buf bytes.Buffer;