mirror of
https://github.com/halverneus/static-file-server.git
synced 2024-11-12 21:45:29 +00:00
Merge pull request #37 from halverneus/dev
Added CORS wildcard support.
This commit is contained in:
commit
3ddb069d05
@ -3,7 +3,7 @@
|
||||
################################################################################
|
||||
FROM golang:1.13.1 as builder
|
||||
|
||||
ENV VERSION 1.6.6
|
||||
ENV VERSION 1.7.0
|
||||
ENV BUILD_DIR /build
|
||||
|
||||
RUN mkdir -p ${BUILD_DIR}
|
||||
@ -31,5 +31,5 @@ LABEL life.apets.vendor="Halverneus" \
|
||||
life.apets.url="https://github.com/halverneus/static-file-server" \
|
||||
life.apets.name="Static File Server" \
|
||||
life.apets.description="A tiny static file server" \
|
||||
life.apets.version="v1.6.6" \
|
||||
life.apets.version="v1.7.0" \
|
||||
life.apets.schema-version="1.0"
|
||||
|
@ -1,6 +1,6 @@
|
||||
FROM golang:1.13.1 as builder
|
||||
|
||||
ENV VERSION 1.6.6
|
||||
ENV VERSION 1.7.0
|
||||
ENV BUILD_DIR /build
|
||||
|
||||
RUN mkdir -p ${BUILD_DIR}
|
||||
@ -21,5 +21,5 @@ LABEL life.apets.vendor="Halverneus" \
|
||||
life.apets.url="https://github.com/halverneus/static-file-server" \
|
||||
life.apets.name="Static File Server" \
|
||||
life.apets.description="A tiny static file server" \
|
||||
life.apets.version="v1.6.6" \
|
||||
life.apets.version="v1.7.0" \
|
||||
life.apets.schema-version="1.0"
|
||||
|
@ -14,6 +14,9 @@ Install from any of the following locations:
|
||||
Default values are shown with the associated environment variable.
|
||||
|
||||
```bash
|
||||
# Enables resource access from any domain.
|
||||
CORS=false
|
||||
|
||||
# Enable debugging for troubleshooting. If set to 'true' this prints extra
|
||||
# information during execution. IMPORTANT NOTE: The configuration summary is
|
||||
# printed to stdout while logs generated during execution are printed to stderr.
|
||||
@ -60,6 +63,7 @@ the path to the configuration file using the command line option
|
||||
('-c', '-config', '--config').
|
||||
|
||||
```yaml
|
||||
cors: false
|
||||
debug: false
|
||||
folder: /web
|
||||
host: ""
|
||||
|
@ -33,6 +33,10 @@ DEPENDENCIES
|
||||
None... not even libc!
|
||||
|
||||
ENVIRONMENT VARIABLES
|
||||
CORS
|
||||
When set to 'true' it enables resource access from any domain. All
|
||||
responses will include the headers 'Access-Control-Allow-Origin' and
|
||||
'Access-Control-Allow-Headers' with a wildcard value ('*').
|
||||
DEBUG
|
||||
When set to 'true' enables additional logging, including the
|
||||
configuration used and an access log for each request. IMPORTANT NOTE:
|
||||
@ -85,6 +89,7 @@ CONFIGURATION FILE
|
||||
|
||||
Example config.yml with defaults:
|
||||
----------------------------------------------------------------------------
|
||||
cors: false
|
||||
debug: false
|
||||
folder: /web
|
||||
host: ""
|
||||
|
@ -61,6 +61,12 @@ func handlerSelector() (handler http.HandlerFunc) {
|
||||
if !config.Get.ShowListing {
|
||||
handler = handle.IgnoreIndex(handler)
|
||||
}
|
||||
|
||||
// If configured, apply wildcard CORS support.
|
||||
if config.Get.Cors {
|
||||
handler = handle.AddCorsWildcardHeaders(handler)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -42,23 +42,28 @@ func TestHandlerSelector(t *testing.T) {
|
||||
listing bool
|
||||
debug bool
|
||||
refer []string
|
||||
cors bool
|
||||
}{
|
||||
{"Basic handler w/o debug", testFolder, "", true, false, ignoreReferrer},
|
||||
{"Prefix handler w/o debug", testFolder, testPrefix, true, false, ignoreReferrer},
|
||||
{"Basic and hide listing handler w/o debug", testFolder, "", false, false, ignoreReferrer},
|
||||
{"Prefix and hide listing handler w/o debug", testFolder, testPrefix, false, false, ignoreReferrer},
|
||||
{"Basic handler w/debug", testFolder, "", true, true, ignoreReferrer},
|
||||
{"Prefix handler w/debug", testFolder, testPrefix, true, true, ignoreReferrer},
|
||||
{"Basic and hide listing handler w/debug", testFolder, "", false, true, ignoreReferrer},
|
||||
{"Prefix and hide listing handler w/debug", testFolder, testPrefix, false, true, ignoreReferrer},
|
||||
{"Basic handler w/o debug w/refer", testFolder, "", true, false, testReferrer},
|
||||
{"Prefix handler w/o debug w/refer", testFolder, testPrefix, true, false, testReferrer},
|
||||
{"Basic and hide listing handler w/o debug w/refer", testFolder, "", false, false, testReferrer},
|
||||
{"Prefix and hide listing handler w/o debug w/refer", testFolder, testPrefix, false, false, testReferrer},
|
||||
{"Basic handler w/debug w/refer", testFolder, "", true, true, testReferrer},
|
||||
{"Prefix handler w/debug w/refer", testFolder, testPrefix, true, true, testReferrer},
|
||||
{"Basic and hide listing handler w/debug w/refer", testFolder, "", false, true, testReferrer},
|
||||
{"Prefix and hide listing handler w/debug w/refer", testFolder, testPrefix, false, true, testReferrer},
|
||||
{"Basic handler w/o debug", testFolder, "", true, false, ignoreReferrer, false},
|
||||
{"Prefix handler w/o debug", testFolder, testPrefix, true, false, ignoreReferrer, false},
|
||||
{"Basic and hide listing handler w/o debug", testFolder, "", false, false, ignoreReferrer, false},
|
||||
{"Prefix and hide listing handler w/o debug", testFolder, testPrefix, false, false, ignoreReferrer, false},
|
||||
{"Basic handler w/debug", testFolder, "", true, true, ignoreReferrer, false},
|
||||
{"Prefix handler w/debug", testFolder, testPrefix, true, true, ignoreReferrer, false},
|
||||
{"Basic and hide listing handler w/debug", testFolder, "", false, true, ignoreReferrer, false},
|
||||
{"Prefix and hide listing handler w/debug", testFolder, testPrefix, false, true, ignoreReferrer, false},
|
||||
{"Basic handler w/o debug w/refer", testFolder, "", true, false, testReferrer, false},
|
||||
{"Prefix handler w/o debug w/refer", testFolder, testPrefix, true, false, testReferrer, false},
|
||||
{"Basic and hide listing handler w/o debug w/refer", testFolder, "", false, false, testReferrer, false},
|
||||
{"Prefix and hide listing handler w/o debug w/refer", testFolder, testPrefix, false, false, testReferrer, false},
|
||||
{"Basic handler w/debug w/refer w/o cors", testFolder, "", true, true, testReferrer, false},
|
||||
{"Prefix handler w/debug w/refer w/o cors", testFolder, testPrefix, true, true, testReferrer, false},
|
||||
{"Basic and hide listing handler w/debug w/refer w/o cors", testFolder, "", false, true, testReferrer, false},
|
||||
{"Prefix and hide listing handler w/debug w/refer w/o cors", testFolder, testPrefix, false, true, testReferrer, false},
|
||||
{"Basic handler w/debug w/refer w/cors", testFolder, "", true, true, testReferrer, true},
|
||||
{"Prefix handler w/debug w/refer w/cors", testFolder, testPrefix, true, true, testReferrer, true},
|
||||
{"Basic and hide listing handler w/debug w/refer w/cors", testFolder, "", false, true, testReferrer, true},
|
||||
{"Prefix and hide listing handler w/debug w/refer w/cors", testFolder, testPrefix, false, true, testReferrer, true},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@ -68,6 +73,7 @@ func TestHandlerSelector(t *testing.T) {
|
||||
config.Get.ShowListing = tc.listing
|
||||
config.Get.URLPrefix = tc.prefix
|
||||
config.Get.Referrers = tc.refer
|
||||
config.Get.Cors = tc.cors
|
||||
|
||||
handlerSelector()
|
||||
})
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
var (
|
||||
// Get the desired configuration value.
|
||||
Get struct {
|
||||
Cors bool `yaml:"cors"`
|
||||
Debug bool `yaml:"debug"`
|
||||
Folder string `yaml:"folder"`
|
||||
Host string `yaml:"host"`
|
||||
@ -27,6 +28,7 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
corsKey = "CORS"
|
||||
debugKey = "DEBUG"
|
||||
folderKey = "FOLDER"
|
||||
hostKey = "HOST"
|
||||
@ -48,6 +50,7 @@ var (
|
||||
defaultTLSCert = ""
|
||||
defaultTLSKey = ""
|
||||
defaultURLPrefix = ""
|
||||
defaultCors = false
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -65,6 +68,7 @@ func setDefaults() {
|
||||
Get.TLSCert = defaultTLSCert
|
||||
Get.TLSKey = defaultTLSKey
|
||||
Get.URLPrefix = defaultURLPrefix
|
||||
Get.Cors = defaultCors
|
||||
}
|
||||
|
||||
// Load the configuration file.
|
||||
@ -104,6 +108,7 @@ func Log() {
|
||||
// overrideWithEnvVars the default values and the configuration file values.
|
||||
func overrideWithEnvVars() {
|
||||
// Assign envvars, if set.
|
||||
Get.Cors = envAsBool(corsKey, Get.Cors)
|
||||
Get.Debug = envAsBool(debugKey, Get.Debug)
|
||||
Get.Folder = envAsStr(folderKey, Get.Folder)
|
||||
Get.Host = envAsStr(hostKey, Get.Host)
|
||||
|
@ -109,6 +109,16 @@ func IgnoreIndex(serve http.HandlerFunc) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// AddCorsWildcardHeaders wraps an HTTP request to notify client browsers that
|
||||
// resources should be allowed to be retrieved by any other domain.
|
||||
func AddCorsWildcardHeaders(serve http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.Header().Set("Access-Control-Allow-Headers", "*")
|
||||
serve(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
// Listening function for serving the handler function.
|
||||
func Listening() ListenerFunc {
|
||||
return func(binding string, handler http.HandlerFunc) error {
|
||||
|
@ -458,3 +458,76 @@ func TestValidReferrer(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddCorsWildcardHeaders(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
corsEnabled bool
|
||||
}{
|
||||
{"CORS disabled", false},
|
||||
{"CORS enabled", true},
|
||||
}
|
||||
|
||||
corsHeaders := map[string]string{
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Headers": "*",
|
||||
}
|
||||
|
||||
for _, serveFile := range serveFileFuncs {
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
var handler http.HandlerFunc
|
||||
if tc.corsEnabled {
|
||||
handler = AddCorsWildcardHeaders(Basic(serveFile, baseDir))
|
||||
} else {
|
||||
handler = Basic(serveFile, baseDir)
|
||||
}
|
||||
|
||||
fullpath := "http://localhost/" + tmpFileName
|
||||
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 ok != resp.StatusCode {
|
||||
t.Errorf(
|
||||
"While retrieving %s expected status code of %d but got %d",
|
||||
fullpath, ok, resp.StatusCode,
|
||||
)
|
||||
}
|
||||
if tmpFile != contents {
|
||||
t.Errorf(
|
||||
"While retrieving %s expected contents '%s' but got '%s'",
|
||||
fullpath, tmpFile, contents,
|
||||
)
|
||||
}
|
||||
|
||||
if tc.corsEnabled {
|
||||
for k, v := range corsHeaders {
|
||||
if v != resp.Header.Get(k) {
|
||||
t.Errorf(
|
||||
"With CORS enabled expect header '%s' to return '%s' but got '%s'",
|
||||
k, v, resp.Header.Get(k),
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for k := range corsHeaders {
|
||||
if "" != resp.Header.Get(k) {
|
||||
t.Errorf(
|
||||
"With CORS disabled expected header '%s' to return '' but got '%s'",
|
||||
k, resp.Header.Get(k),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user