Merge branch 'feature/show_listing_option' into integration

pull/3/head
Jeromy Streets 6 years ago
commit 4454460785
  1. 5
      README.md
  2. 98
      serve.go

@ -10,6 +10,9 @@ Environment variables with defaults:
HOST= HOST=
# If assigned, must be a valid port number. # If assigned, must be a valid port number.
PORT=8080 PORT=8080
# Automatically serve the index file for a given directory (default). If set to
# 'false', URLs ending with a '/' will return 'NOT FOUND'.
SHOW_LISTING=true
# Folder with the content to serve. # Folder with the content to serve.
FOLDER=/web FOLDER=/web
# URL path prefix. If 'my.file' is in the root of $FOLDER and $URL_PREFIX is # URL path prefix. If 'my.file' is in the root of $FOLDER and $URL_PREFIX is
@ -20,8 +23,6 @@ URL_PREFIX=
# served using HTTP. # served using HTTP.
TLS_CERT= TLS_CERT=
TLS_KEY= TLS_KEY=
# Hide Listing (Only available when URL_PREFIX is set)
SHOW_LISTING=
``` ```
### Without Docker ### Without Docker

@ -39,6 +39,12 @@ ENVIRONMENT VARIABLES
to a client without regard for the hostname. to a client without regard for the hostname.
PORT PORT
The port used for binding. If not supplied, defaults to port '8080'. The port used for binding. If not supplied, defaults to port '8080'.
SHOW_LISTING
Automatically serve the index file for the directory if requested. For
example, if the client requests 'http://127.0.0.1/' the 'index.html'
file in the root of the directory being served is returned. If the value
is set to 'false', the same request will return a 'NOT FOUND'. Default
value is 'true'.
TLS_CERT TLS_CERT
Path to the TLS certificate file to serve files using HTTPS. If supplied Path to the TLS certificate file to serve files using HTTPS. If supplied
then TLS_KEY must also be supplied. If not supplied, contents will be then TLS_KEY must also be supplied. If not supplied, contents will be
@ -50,13 +56,12 @@ ENVIRONMENT VARIABLES
URL_PREFIX URL_PREFIX
The prefix to use in the URL path. If supplied, then the prefix must The prefix to use in the URL path. If supplied, then the prefix must
start with a forward-slash and NOT end with a forward-slash. If not start with a forward-slash and NOT end with a forward-slash. If not
supplied then no prefix is used. supplied then no prefix is used.
SHOW_LISTING
This will allow you to hide the file inside the directory
USAGE USAGE
FILE LAYOUT FILE LAYOUT
/var/www/sub/my.file /var/www/sub/my.file
/var/www/index.html
COMMAND COMMAND
export FOLDER=/var/www/sub export FOLDER=/var/www/sub
@ -73,8 +78,7 @@ USAGE
export FOLDER=/var/www/sub export FOLDER=/var/www/sub
export HOST=my.machine export HOST=my.machine
export PORT=80 export PORT=80
export URL_PREFIX=/my/stuff export URL_PREFIX=/my/stuff
export SHOW_LISTING=true
static-file-server static-file-server
Retrieve with: wget http://my.machine/my/stuff/my.file Retrieve with: wget http://my.machine/my/stuff/my.file
@ -90,6 +94,18 @@ USAGE
export TLS_KEY=/etc/server/my.machine.key export TLS_KEY=/etc/server/my.machine.key
static-file-server static-file-server
Retrieve with: wget https://my.machine/my.file Retrieve with: wget https://my.machine/my.file
export FOLDER=/var/www
export PORT=80
export SHOW_LISTING=true # Default behavior
static-file-server
Retrieve 'index.html' with: wget http://my.machine/
export FOLDER=/var/www
export PORT=80
export SHOW_LISTING=false
static-file-server
Returns 'NOT FOUND': wget http://my.machine/
` `
) )
@ -113,10 +129,10 @@ func main() {
folder := env("FOLDER", "/web") + "/" folder := env("FOLDER", "/web") + "/"
host := env("HOST", "") host := env("HOST", "")
port := env("PORT", "8080") port := env("PORT", "8080")
showListing := envAsBool("SHOW_LISTING", true)
tlsCert := env("TLS_CERT", "") tlsCert := env("TLS_CERT", "")
tlsKey := env("TLS_KEY", "") tlsKey := env("TLS_KEY", "")
urlPrefix := env("URL_PREFIX", "") urlPrefix := env("URL_PREFIX", "")
showListing := env("SHOW_LISTING", "true")
// If HTTPS is to be used, verify both TLS_* environment variables are set. // If HTTPS is to be used, verify both TLS_* environment variables are set.
if 0 < len(tlsCert) || 0 < len(tlsKey) { if 0 < len(tlsCert) || 0 < len(tlsKey) {
@ -141,13 +157,9 @@ func main() {
// Choose and set the appropriate, optimized static file serving function. // Choose and set the appropriate, optimized static file serving function.
var handler http.HandlerFunc var handler http.HandlerFunc
if 0 == len(urlPrefix) { if 0 == len(urlPrefix) {
handler = basicHandler(folder) handler = handleListing(showListing, basicHandler(folder))
} else { } else {
if showListing == "false" { handler = handleListing(showListing, prefixHandler(folder, urlPrefix))
handler = prefixHandlerWithoutListingFilesInDirectory(folder, urlPrefix)
} else {
handler = prefixHandler(folder, urlPrefix)
}
} }
http.HandleFunc("/", handler) http.HandleFunc("/", handler)
@ -159,28 +171,23 @@ func main() {
} }
} }
// basicHandler serves files from the folder passed. // handleListing wraps an HTTP request. In the event of a folder root request,
func basicHandler(folder string) http.HandlerFunc { // setting 'show' to false will automatically return 'NOT FOUND' whereas true
// will attempt to retrieve the index file of that directory.
func handleListing(show bool, serve http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, folder+r.URL.Path) if show || strings.HasSuffix(r.URL.Path, "/") {
}
}
// prefixHandler removes the URL path prefix before serving files from the
// folder passed.
func prefixHandlerWithoutListingFilesInDirectory(folder, urlPrefix string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if !strings.HasPrefix(r.URL.Path, urlPrefix) {
http.NotFound(w, r)
return
}
// dont list file in directory
if strings.HasSuffix(r.URL.Path, "/") {
http.NotFound(w, r) http.NotFound(w, r)
return return
} }
serve(w, r)
}
}
http.ServeFile(w, r, folder+strings.TrimPrefix(r.URL.Path, urlPrefix)) // basicHandler serves files from the folder passed.
func basicHandler(folder string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, folder+r.URL.Path)
} }
} }
@ -192,7 +199,6 @@ func prefixHandler(folder, urlPrefix string) http.HandlerFunc {
http.NotFound(w, r) http.NotFound(w, r)
return return
} }
http.ServeFile(w, r, folder+strings.TrimPrefix(r.URL.Path, urlPrefix)) http.ServeFile(w, r, folder+strings.TrimPrefix(r.URL.Path, urlPrefix))
} }
} }
@ -205,3 +211,35 @@ func env(key, fallback string) string {
} }
return fallback return fallback
} }
// strAsBool converts the intent of the passed value into a boolean
// representation.
func strAsBool(value string) (result bool, err error) {
lvalue := strings.ToLower(value)
switch lvalue {
case "0", "false", "f", "no", "n":
result = false
case "1", "true", "t", "yes", "y":
result = true
default:
result = false
msg := "Unknown conversion from string to bool for value '%s'"
err = fmt.Errorf(msg, value)
}
return
}
// envAsBool returns the value for an environment variable or, if not set, a
// fallback value as a boolean.
func envAsBool(key string, fallback bool) bool {
value := env(key, fmt.Sprintf("%t", fallback))
result, err := strAsBool(value)
if nil != err {
log.Printf(
"Invalid value for '%s': %v\nUsing fallback: %t",
key, err, fallback,
)
return fallback
}
return result
}

Loading…
Cancel
Save