mirror of
https://github.com/halverneus/static-file-server.git
synced 2024-11-13 21:55:31 +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
|
FROM golang:1.13.1 as builder
|
||||||
|
|
||||||
ENV VERSION 1.6.6
|
ENV VERSION 1.7.0
|
||||||
ENV BUILD_DIR /build
|
ENV BUILD_DIR /build
|
||||||
|
|
||||||
RUN mkdir -p ${BUILD_DIR}
|
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.url="https://github.com/halverneus/static-file-server" \
|
||||||
life.apets.name="Static File Server" \
|
life.apets.name="Static File Server" \
|
||||||
life.apets.description="A tiny 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"
|
life.apets.schema-version="1.0"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
FROM golang:1.13.1 as builder
|
FROM golang:1.13.1 as builder
|
||||||
|
|
||||||
ENV VERSION 1.6.6
|
ENV VERSION 1.7.0
|
||||||
ENV BUILD_DIR /build
|
ENV BUILD_DIR /build
|
||||||
|
|
||||||
RUN mkdir -p ${BUILD_DIR}
|
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.url="https://github.com/halverneus/static-file-server" \
|
||||||
life.apets.name="Static File Server" \
|
life.apets.name="Static File Server" \
|
||||||
life.apets.description="A tiny 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"
|
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.
|
Default values are shown with the associated environment variable.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# Enables resource access from any domain.
|
||||||
|
CORS=false
|
||||||
|
|
||||||
# Enable debugging for troubleshooting. If set to 'true' this prints extra
|
# Enable debugging for troubleshooting. If set to 'true' this prints extra
|
||||||
# information during execution. IMPORTANT NOTE: The configuration summary is
|
# information during execution. IMPORTANT NOTE: The configuration summary is
|
||||||
# printed to stdout while logs generated during execution are printed to stderr.
|
# 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').
|
('-c', '-config', '--config').
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
cors: false
|
||||||
debug: false
|
debug: false
|
||||||
folder: /web
|
folder: /web
|
||||||
host: ""
|
host: ""
|
||||||
|
@ -33,6 +33,10 @@ DEPENDENCIES
|
|||||||
None... not even libc!
|
None... not even libc!
|
||||||
|
|
||||||
ENVIRONMENT VARIABLES
|
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
|
DEBUG
|
||||||
When set to 'true' enables additional logging, including the
|
When set to 'true' enables additional logging, including the
|
||||||
configuration used and an access log for each request. IMPORTANT NOTE:
|
configuration used and an access log for each request. IMPORTANT NOTE:
|
||||||
@ -85,6 +89,7 @@ CONFIGURATION FILE
|
|||||||
|
|
||||||
Example config.yml with defaults:
|
Example config.yml with defaults:
|
||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
|
cors: false
|
||||||
debug: false
|
debug: false
|
||||||
folder: /web
|
folder: /web
|
||||||
host: ""
|
host: ""
|
||||||
|
@ -61,6 +61,12 @@ func handlerSelector() (handler http.HandlerFunc) {
|
|||||||
if !config.Get.ShowListing {
|
if !config.Get.ShowListing {
|
||||||
handler = handle.IgnoreIndex(handler)
|
handler = handle.IgnoreIndex(handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If configured, apply wildcard CORS support.
|
||||||
|
if config.Get.Cors {
|
||||||
|
handler = handle.AddCorsWildcardHeaders(handler)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,23 +42,28 @@ func TestHandlerSelector(t *testing.T) {
|
|||||||
listing bool
|
listing bool
|
||||||
debug bool
|
debug bool
|
||||||
refer []string
|
refer []string
|
||||||
|
cors bool
|
||||||
}{
|
}{
|
||||||
{"Basic handler w/o debug", testFolder, "", true, false, ignoreReferrer},
|
{"Basic handler w/o debug", testFolder, "", true, false, ignoreReferrer, false},
|
||||||
{"Prefix handler w/o debug", testFolder, testPrefix, true, false, ignoreReferrer},
|
{"Prefix handler w/o debug", testFolder, testPrefix, true, false, ignoreReferrer, false},
|
||||||
{"Basic and hide listing handler w/o debug", testFolder, "", false, false, ignoreReferrer},
|
{"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},
|
{"Prefix and hide listing handler w/o debug", testFolder, testPrefix, false, false, ignoreReferrer, false},
|
||||||
{"Basic handler w/debug", testFolder, "", true, true, ignoreReferrer},
|
{"Basic handler w/debug", testFolder, "", true, true, ignoreReferrer, false},
|
||||||
{"Prefix handler w/debug", testFolder, testPrefix, true, true, ignoreReferrer},
|
{"Prefix handler w/debug", testFolder, testPrefix, true, true, ignoreReferrer, false},
|
||||||
{"Basic and hide listing handler w/debug", testFolder, "", false, true, ignoreReferrer},
|
{"Basic and hide listing handler w/debug", testFolder, "", false, true, ignoreReferrer, false},
|
||||||
{"Prefix and hide listing handler w/debug", testFolder, testPrefix, false, true, ignoreReferrer},
|
{"Prefix and hide listing handler w/debug", testFolder, testPrefix, false, true, ignoreReferrer, false},
|
||||||
{"Basic handler w/o debug w/refer", testFolder, "", true, false, testReferrer},
|
{"Basic handler w/o debug w/refer", testFolder, "", true, false, testReferrer, false},
|
||||||
{"Prefix handler w/o debug w/refer", testFolder, testPrefix, true, false, testReferrer},
|
{"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},
|
{"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},
|
{"Prefix and hide listing handler w/o debug w/refer", testFolder, testPrefix, false, false, testReferrer, false},
|
||||||
{"Basic handler w/debug w/refer", testFolder, "", true, true, testReferrer},
|
{"Basic handler w/debug w/refer w/o cors", testFolder, "", true, true, testReferrer, false},
|
||||||
{"Prefix handler w/debug w/refer", testFolder, testPrefix, true, true, testReferrer},
|
{"Prefix handler w/debug w/refer w/o cors", testFolder, testPrefix, true, true, testReferrer, false},
|
||||||
{"Basic and hide listing handler w/debug w/refer", testFolder, "", false, true, testReferrer},
|
{"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", testFolder, testPrefix, false, true, testReferrer},
|
{"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 {
|
for _, tc := range testCases {
|
||||||
@ -68,6 +73,7 @@ func TestHandlerSelector(t *testing.T) {
|
|||||||
config.Get.ShowListing = tc.listing
|
config.Get.ShowListing = tc.listing
|
||||||
config.Get.URLPrefix = tc.prefix
|
config.Get.URLPrefix = tc.prefix
|
||||||
config.Get.Referrers = tc.refer
|
config.Get.Referrers = tc.refer
|
||||||
|
config.Get.Cors = tc.cors
|
||||||
|
|
||||||
handlerSelector()
|
handlerSelector()
|
||||||
})
|
})
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
// Get the desired configuration value.
|
// Get the desired configuration value.
|
||||||
Get struct {
|
Get struct {
|
||||||
|
Cors bool `yaml:"cors"`
|
||||||
Debug bool `yaml:"debug"`
|
Debug bool `yaml:"debug"`
|
||||||
Folder string `yaml:"folder"`
|
Folder string `yaml:"folder"`
|
||||||
Host string `yaml:"host"`
|
Host string `yaml:"host"`
|
||||||
@ -27,6 +28,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
corsKey = "CORS"
|
||||||
debugKey = "DEBUG"
|
debugKey = "DEBUG"
|
||||||
folderKey = "FOLDER"
|
folderKey = "FOLDER"
|
||||||
hostKey = "HOST"
|
hostKey = "HOST"
|
||||||
@ -48,6 +50,7 @@ var (
|
|||||||
defaultTLSCert = ""
|
defaultTLSCert = ""
|
||||||
defaultTLSKey = ""
|
defaultTLSKey = ""
|
||||||
defaultURLPrefix = ""
|
defaultURLPrefix = ""
|
||||||
|
defaultCors = false
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -65,6 +68,7 @@ func setDefaults() {
|
|||||||
Get.TLSCert = defaultTLSCert
|
Get.TLSCert = defaultTLSCert
|
||||||
Get.TLSKey = defaultTLSKey
|
Get.TLSKey = defaultTLSKey
|
||||||
Get.URLPrefix = defaultURLPrefix
|
Get.URLPrefix = defaultURLPrefix
|
||||||
|
Get.Cors = defaultCors
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the configuration file.
|
// Load the configuration file.
|
||||||
@ -104,6 +108,7 @@ func Log() {
|
|||||||
// overrideWithEnvVars the default values and the configuration file values.
|
// overrideWithEnvVars the default values and the configuration file values.
|
||||||
func overrideWithEnvVars() {
|
func overrideWithEnvVars() {
|
||||||
// Assign envvars, if set.
|
// Assign envvars, if set.
|
||||||
|
Get.Cors = envAsBool(corsKey, Get.Cors)
|
||||||
Get.Debug = envAsBool(debugKey, Get.Debug)
|
Get.Debug = envAsBool(debugKey, Get.Debug)
|
||||||
Get.Folder = envAsStr(folderKey, Get.Folder)
|
Get.Folder = envAsStr(folderKey, Get.Folder)
|
||||||
Get.Host = envAsStr(hostKey, Get.Host)
|
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.
|
// Listening function for serving the handler function.
|
||||||
func Listening() ListenerFunc {
|
func Listening() ListenerFunc {
|
||||||
return func(binding string, handler http.HandlerFunc) error {
|
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