Skip to content

Commit

Permalink
Implement logic to add a prefix.
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickdappollonio committed Apr 6, 2018
1 parent 98d6794 commit dc052de
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 18 deletions.
44 changes: 35 additions & 9 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@ var (
return humansize(s)
},
"mergepath": func(a ...string) string {
return path.Join(a...)
return path.Clean(path.Join(a...))
},
"mergepathtrail": func(a ...string) string {
m := path.Clean(path.Join(a...)) + "/"
if m == "//" {
return "/"
}
return m
},
"contenttype": func(path string, f os.FileInfo) string {
// Try finding the content type based off the extension
Expand Down Expand Up @@ -55,7 +62,7 @@ func init() {
Parse(httpServerTemplate))
}

func handler(path, givenTitle, givenColor string) http.Handler {
func handler(prefix, p, givenTitle, givenColor string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// If the method is GET, then we continue, we fail with "Method Not Allowed"
// otherwise, since all request are for files.
Expand All @@ -64,6 +71,15 @@ func handler(path, givenTitle, givenColor string) http.Handler {
return
}

// Check if the prefix isn't "/", if so, remove it
if prefix != "/" {
r.URL.Path = strings.TrimPrefix(r.URL.Path, prefix)

if r.URL.Path == "" {
r.URL.Path = "/"
}
}

// Check if the URL ends on "/index.html", if so, redirect to the folder, because
// we can handle it later down the road
if strings.HasSuffix(r.URL.Path, "/index.html") {
Expand All @@ -74,7 +90,7 @@ func handler(path, givenTitle, givenColor string) http.Handler {
// Get the full path to the file or directory, since
// we don't need the current working directory, we can
// omit the error
fullpath, _ := filepath.Abs(filepath.Join(path, r.URL.Path))
fullpath, _ := filepath.Abs(filepath.Join(p, r.URL.Path))

// Find if there's a file or folder here
info, err := os.Stat(fullpath)
Expand All @@ -93,19 +109,20 @@ func handler(path, givenTitle, givenColor string) http.Handler {
// Check if it's a folder, if so, walk and present the contents on screen
if info.IsDir() {
if !strings.HasSuffix(r.URL.Path, "/") {
http.Redirect(w, r, fmt.Sprintf("%s/", r.URL.Path), http.StatusFound)
to := path.Join("/", prefix, r.URL.Path) + "/"
http.Redirect(w, r, to, http.StatusFound)
return
}

walk(fullpath, givenTitle, givenColor, w, r)
walk(prefix, fullpath, givenTitle, givenColor, w, r)
return
}

http.ServeFile(w, r, fullpath)
})
}

func walk(fpath, givenTitle, givenColor string, w http.ResponseWriter, r *http.Request) {
func walk(prefix, fpath, givenTitle, givenColor string, w http.ResponseWriter, r *http.Request) {
// Check if there's an index file, and if so, present it on screen
indexPath := filepath.Join(fpath, "index.html")
if _, err := os.Stat(indexPath); err == nil {
Expand Down Expand Up @@ -135,13 +152,18 @@ func walk(fpath, givenTitle, givenColor string, w http.ResponseWriter, r *http.R

// Get the path to a parent folder
parentFolder := ""
if p := r.URL.Path; p != "/" {
if p := path.Join(prefix, r.URL.Path); p != "/" {
// If the path is not root, we're in a folder, but since folders
// are enforced to use trailing slash then we need to remove it
// so path.Dir() can work
parentFolder = path.Dir(strings.TrimSuffix(p, "/"))
}

// Update prefix to be nothing if it's just "/"
// if prefix == "/" {
// prefix = ""
// }

// If we reached this point, we're ready to print the template
// so we create a bag, and we save the information there
bag := map[string]interface{}{
Expand All @@ -154,6 +176,7 @@ func walk(fpath, givenTitle, givenColor string, w http.ResponseWriter, r *http.R
"PageTitle": "HTTP File Server",
"TagTitle": fmt.Sprintf("Browsing directory: %s", r.URL.Path),
"GivenColor": givenColor,
"PathPrefix": prefix,
}

// Check if we need to change the title
Expand All @@ -177,13 +200,16 @@ func logrequest(next http.Handler) http.Handler {
// to measure how long it took
start := time.Now()

// Save URL before sending the next handler
u := r.URL.String()

// Serve the request
next.ServeHTTP(lrw, r)

// Now get the status code and print the log statement
log.Printf(
"%s %s -- %s %d %s served in %v",
r.Method, r.URL.String(), r.Proto, lrw.statusCode, http.StatusText(lrw.statusCode), time.Now().Sub(start),
"%s %q -- %s %d %s served in %v",
r.Method, u, r.Proto, lrw.statusCode, http.StatusText(lrw.statusCode), time.Now().Sub(start),
)
})
}
Expand Down
30 changes: 25 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ const (
)

var (
fileServerPath = "/html"
fileServerPort = "0.0.0.0:5000"
fileServerPath = "/html"
fileServerPrefix = "/"
fileServerPort = "0.0.0.0:5000"

pathFlag = flag.String("path", "", "The path you want to serve via HTTP")
pathFlag = flag.String("path", "", "The path you want to serve via HTTP")
pathprefixFlag = flag.String("pathprefix", "/", "A URL path prefix on where to serve these")
)

// exists returns whether a folder exists or not in the filesystem
Expand All @@ -49,9 +51,27 @@ func main() {
if v := os.Getenv("FILE_SERVER_PATH"); v != "" {
fileServerPath = v
} else {
if flag.Parse(); *pathFlag != "" {
flag.Parse()

if *pathFlag != "" {
fileServerPath = *pathFlag
}

if *pathprefixFlag != "/" {
fileServerPrefix = *pathprefixFlag
}
}

// Check if the prefix matches what we want
if !strings.HasSuffix(fileServerPrefix, "/") || !strings.HasPrefix(fileServerPrefix, "/") {
log.Println("Unable to start a server with a path prefix not starting or ending in \"/\"... Aborting...")
return
}

// Check if the prefix matches what we want
if fileServerPrefix == "//" {
log.Printf("Incorrect prefix supplied: %q. Aborting...", fileServerPrefix)
return
}

// Define a default title
Expand Down Expand Up @@ -86,7 +106,7 @@ func main() {
}

// Create the file server
http.Handle("/", logrequest(handler(fileServerPath, givenTitle, givenColor)))
http.Handle(fileServerPrefix, logrequest(handler(fileServerPrefix, fileServerPath, givenTitle, givenColor)))

// Graceful shutdown
sigquit := make(chan os.Signal, 1)
Expand Down
8 changes: 4 additions & 4 deletions template.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--2-col mdl-cell--hide-tablet mdl-cell--hide-phone"></div>
<div class="list-contents mdl-color--white mdl-shadow--4dp content mdl-color-text--grey-800 mdl-cell mdl-cell--8-col">
{{ if .Breadcrumb -}}
<ul id="breadcrumb">{{ range .Breadcrumb }} <li><a href="{{ .URL }}" title="Browse to {{ .URL }}">{{ .Name }}</a></li> {{ end }}</ul>
{{ if .Breadcrumb -}}{{ $prefix := .PathPrefix }}
<ul id="breadcrumb">{{ range .Breadcrumb }} <li><a href="{{ mergepathtrail $prefix .URL }}" title="Browse to {{ mergepathtrail $prefix .URL }}">{{ .Name }}</a></li> {{ end }}</ul>
{{- end }}
{{ if and (not .IncludeBack) (not .Files) }}
<div>
Expand All @@ -120,13 +120,13 @@
</span>
</li>
{{- end }}
{{ $path := .Path }}{{ $filepath := .FilePath -}}
{{ $path := .Path }}{{ $prefix := .PathPrefix }}{{ $filepath := .FilePath -}}
{{- range .Files -}}
<li class="mdl-list__item mdl-list__item--two-line" data-name="{{ .Name }}">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-icon">{{ if .IsDir }}folder{{ else }}description{{ end }}</i>
<span>
<a class="file-link" href="{{ mergepath $path .Name }}{{ if .IsDir }}/{{ end }}">{{ .Name }}</a>
<a class="file-link" href="{{ mergepath $prefix $path .Name }}{{ if .IsDir }}/{{ end }}">{{ .Name }}</a>
{{ if not .IsDir -}}
<i id="file-{{ .Name | genid }}" class="material-icons info-tooltip">info_outline</i>
<div class="mdl-tooltip" data-mdl-for="file-{{ .Name | genid }}">
Expand Down

0 comments on commit dc052de

Please sign in to comment.