mirror of
https://github.com/halverneus/static-file-server.git
synced 2024-11-24 09:05:30 +00:00
commit
0c18d4bd54
@ -34,8 +34,11 @@ HOST=
|
||||
# If assigned, must be a valid port number.
|
||||
PORT=8080
|
||||
|
||||
# Automatically serve the index file for a given directory (default). If set to
|
||||
# 'false', URLs ending with a '/' will return 'NOT FOUND'.
|
||||
# When set to 'true' the index.html file in the folder will be served. And
|
||||
# the file list will not be served.
|
||||
ALLOW_INDEX=true
|
||||
|
||||
# Automatically serve the index of file list for a given directory (default).
|
||||
SHOW_LISTING=true
|
||||
|
||||
# Folder with the content to serve.
|
||||
|
@ -61,6 +61,12 @@ ENVIRONMENT VARIABLES
|
||||
Examples:
|
||||
REFERRERS='http://localhost,https://some.site,http://other.site:8080'
|
||||
REFERRERS=',http://localhost,https://some.site,http://other.site:8080'
|
||||
ALLOW_INDEX
|
||||
When set to 'true' the index.html file in the folder(not include the
|
||||
sub folders) will be served. And the file list will not be served.
|
||||
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. Default value
|
||||
is 'true'.
|
||||
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'
|
||||
@ -161,12 +167,22 @@ USAGE
|
||||
|
||||
export FOLDER=/var/www
|
||||
export PORT=80
|
||||
export ALLOW_INDEX=true # Default behavior
|
||||
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 ALLOW_INDEX=true # Default behavior
|
||||
export SHOW_LISTING=false
|
||||
static-file-server
|
||||
Retrieve 'index.html' with: wget http://my.machine/
|
||||
Returns 'NOT FOUND': wget http://my.machine/dir/
|
||||
|
||||
export FOLDER=/var/www
|
||||
export PORT=80
|
||||
export ALLOW_INDEX=false
|
||||
export SHOW_LISTING=false
|
||||
static-file-server
|
||||
Returns 'NOT FOUND': wget http://my.machine/
|
||||
|
@ -59,9 +59,12 @@ func handlerSelector() (handler http.HandlerFunc) {
|
||||
|
||||
// Determine whether index files should hidden.
|
||||
if !config.Get.ShowListing {
|
||||
handler = handle.IgnoreIndex(handler)
|
||||
if config.Get.AllowIndex {
|
||||
handler = handle.PreventListings(handler, config.Get.Folder, config.Get.URLPrefix)
|
||||
} else {
|
||||
handler = handle.IgnoreIndex(handler)
|
||||
}
|
||||
}
|
||||
|
||||
// If configured, apply wildcard CORS support.
|
||||
if config.Get.Cors {
|
||||
handler = handle.AddCorsWildcardHeaders(handler)
|
||||
|
@ -21,6 +21,7 @@ var (
|
||||
Folder string `yaml:"folder"`
|
||||
Host string `yaml:"host"`
|
||||
Port uint16 `yaml:"port"`
|
||||
AllowIndex bool `yaml:"allow-index"`
|
||||
ShowListing bool `yaml:"show-listing"`
|
||||
TLSCert string `yaml:"tls-cert"`
|
||||
TLSKey string `yaml:"tls-key"`
|
||||
@ -39,6 +40,7 @@ const (
|
||||
hostKey = "HOST"
|
||||
portKey = "PORT"
|
||||
referrersKey = "REFERRERS"
|
||||
allowIndexKey = "ALLOW_INDEX"
|
||||
showListingKey = "SHOW_LISTING"
|
||||
tlsCertKey = "TLS_CERT"
|
||||
tlsKeyKey = "TLS_KEY"
|
||||
@ -53,6 +55,7 @@ var (
|
||||
defaultHost = ""
|
||||
defaultPort = uint16(8080)
|
||||
defaultReferrers = []string{}
|
||||
defaultAllowIndex = true
|
||||
defaultShowListing = true
|
||||
defaultTLSCert = ""
|
||||
defaultTLSKey = ""
|
||||
@ -73,6 +76,7 @@ func setDefaults() {
|
||||
Get.Host = defaultHost
|
||||
Get.Port = defaultPort
|
||||
Get.Referrers = defaultReferrers
|
||||
Get.AllowIndex = defaultAllowIndex
|
||||
Get.ShowListing = defaultShowListing
|
||||
Get.TLSCert = defaultTLSCert
|
||||
Get.TLSKey = defaultTLSKey
|
||||
@ -124,6 +128,7 @@ func overrideWithEnvVars() {
|
||||
Get.Folder = envAsStr(folderKey, Get.Folder)
|
||||
Get.Host = envAsStr(hostKey, Get.Host)
|
||||
Get.Port = envAsUint16(portKey, Get.Port)
|
||||
Get.AllowIndex = envAsBool(allowIndexKey, Get.AllowIndex)
|
||||
Get.ShowListing = envAsBool(showListingKey, Get.ShowListing)
|
||||
Get.TLSCert = envAsStr(tlsCertKey, Get.TLSCert)
|
||||
Get.TLSKey = envAsStr(tlsKeyKey, Get.TLSKey)
|
||||
|
@ -82,6 +82,7 @@ func TestOverrideWithEnvvars(t *testing.T) {
|
||||
testFolder := "/my/directory"
|
||||
testHost := "apets.life"
|
||||
testPort := uint16(666)
|
||||
testAllowIndex := false
|
||||
testShowListing := false
|
||||
testTLSCert := "my.pem"
|
||||
testTLSKey := "my.key"
|
||||
@ -92,6 +93,7 @@ func TestOverrideWithEnvvars(t *testing.T) {
|
||||
os.Setenv(folderKey, testFolder)
|
||||
os.Setenv(hostKey, testHost)
|
||||
os.Setenv(portKey, strconv.Itoa(int(testPort)))
|
||||
os.Setenv(allowIndexKey, fmt.Sprintf("%t", testAllowIndex))
|
||||
os.Setenv(showListingKey, fmt.Sprintf("%t", testShowListing))
|
||||
os.Setenv(tlsCertKey, testTLSCert)
|
||||
os.Setenv(tlsKeyKey, testTLSKey)
|
||||
|
@ -6,6 +6,8 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -130,6 +132,23 @@ func Prefix(serveFile FileServerFunc, folder, urlPrefix string) http.HandlerFunc
|
||||
}
|
||||
}
|
||||
|
||||
// PreventListings returns a function that prevents listing of directories but
|
||||
// still allows index.html to be served.
|
||||
func PreventListings(serve http.HandlerFunc, folder string, urlPrefix string) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if strings.HasSuffix(r.URL.Path, "/") {
|
||||
// If the directory does not contain an index.html file, then
|
||||
// return 'NOT FOUND' to prevent listing of the directory.
|
||||
stat, err := os.Stat(path.Join(folder, strings.TrimPrefix(r.URL.Path, urlPrefix), "index.html"))
|
||||
if err != nil || (err == nil && !stat.Mode().IsRegular()) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
serve(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
// IgnoreIndex wraps an HTTP request. In the event of a folder root request,
|
||||
// this function will automatically return 'NOT FOUND' as opposed to default
|
||||
// behavior where the index file for that directory is retrieved.
|
||||
|
@ -27,6 +27,8 @@ var (
|
||||
tmpSubDeepIndexName = "sub/deep/index.html"
|
||||
tmpSubDeepFileName = "sub/deep/file.txt"
|
||||
tmpSubDeepBadName = "sub/deep/bad.txt"
|
||||
tmpNoIndexDir = "noindex/"
|
||||
tmpNoIndexName = "noindex/noindex.txt"
|
||||
|
||||
tmpIndex = "Space: the final frontier"
|
||||
tmpFile = "These are the voyages of the starship Enterprise."
|
||||
@ -48,6 +50,7 @@ var (
|
||||
baseDir + tmpSubFileName: tmpSubFile,
|
||||
baseDir + tmpSubDeepIndexName: tmpSubDeepIndex,
|
||||
baseDir + tmpSubDeepFileName: tmpSubDeepFile,
|
||||
baseDir + tmpNoIndexName: tmpSubDeepFile,
|
||||
}
|
||||
|
||||
serveFileFuncs = []FileServerFunc{
|
||||
@ -337,6 +340,56 @@ func TestIgnoreIndex(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPreventListings(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
path string
|
||||
code int
|
||||
contents string
|
||||
}{
|
||||
{"Good base dir", "", ok, tmpIndex},
|
||||
{"Good base index", tmpIndexName, redirect, nothing},
|
||||
{"Good base file", tmpFileName, ok, tmpFile},
|
||||
{"Bad base file", tmpBadName, missing, notFound},
|
||||
{"Good subdir dir", subDir, ok, tmpSubIndex},
|
||||
{"Good subdir index", tmpSubIndexName, redirect, nothing},
|
||||
{"Good subdir file", tmpSubFileName, ok, tmpSubFile},
|
||||
{"Dir without index", tmpNoIndexDir, missing, notFound},
|
||||
}
|
||||
|
||||
for _, serveFile := range serveFileFuncs {
|
||||
handler := PreventListings(Basic(serveFile, baseDir), baseDir, "")
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
fullpath := "http://localhost/" + tc.path
|
||||
req := httptest.NewRequest("GET", fullpath, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
handler(w, req)
|
||||
|
||||
resp := w.Result()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if nil != err {
|
||||
t.Errorf("While reading body got %v", err)
|
||||
}
|
||||
contents := string(body)
|
||||
if tc.code != resp.StatusCode {
|
||||
t.Errorf(
|
||||
"While retrieving %s expected status code of %d but got %d",
|
||||
fullpath, tc.code, resp.StatusCode,
|
||||
)
|
||||
}
|
||||
if tc.contents != contents {
|
||||
t.Errorf(
|
||||
"While retrieving %s expected contents '%s' but got '%s'",
|
||||
fullpath, tc.contents, contents,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddAccessKey(t *testing.T) {
|
||||
// Prepare testing data.
|
||||
accessKey := "my-access-key"
|
||||
|
Loading…
Reference in New Issue
Block a user