Merge pull request #36 from demipel8/master

CORS support
This commit is contained in:
Jeromy Streets 2019-10-16 08:33:05 -07:00 committed by GitHub
commit e5e449a275
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 83 additions and 19 deletions

View File

@ -3,7 +3,7 @@
################################################################################
FROM golang:1.13.1 as builder
ENV VERSION 1.6.6
ENV VERSION 1.7.6
ENV BUILD_DIR /build
RUN mkdir -p ${BUILD_DIR}

View File

@ -1,6 +1,6 @@
FROM golang:1.13.1 as builder
ENV VERSION 1.6.6
ENV VERSION 1.7.6
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.6" \
life.apets.schema-version="1.0"

View File

@ -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.
@ -69,6 +72,7 @@ show-listing: true
tls-cert: ""
tls-key: ""
url-prefix: ""
cors: false
```
Example configuration with possible alternative values:

View File

@ -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:
@ -94,6 +98,7 @@ CONFIGURATION FILE
tls-cert: ""
tls-key: ""
url-prefix: ""
cors: false
----------------------------------------------------------------------------
Example config.yml with possible alternative values:

View File

@ -61,6 +61,11 @@ func handlerSelector() (handler http.HandlerFunc) {
if !config.Get.ShowListing {
handler = handle.IgnoreIndex(handler)
}
if config.Get.Cors {
handler = handle.AddCorsHeaders(handler)
}
return
}

View File

@ -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()
})

View File

@ -23,6 +23,7 @@ var (
TLSKey string `yaml:"tls-key"`
URLPrefix string `yaml:"url-prefix"`
Referrers []string `yaml:"referrers"`
Cors bool `yaml:cors`
}
)
@ -36,6 +37,7 @@ const (
tlsCertKey = "TLS_CERT"
tlsKeyKey = "TLS_KEY"
urlPrefixKey = "URL_PREFIX"
corsKey = "CORS"
)
var (
@ -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.
@ -113,6 +117,7 @@ func overrideWithEnvVars() {
Get.TLSKey = envAsStr(tlsKeyKey, Get.TLSKey)
Get.URLPrefix = envAsStr(urlPrefixKey, Get.URLPrefix)
Get.Referrers = envAsStrSlice(referrersKey, Get.Referrers)
Get.Cors = envAsBool(corsKey, Get.Cors)
}
// validate the configuration.

View File

@ -109,6 +109,15 @@ func IgnoreIndex(serve http.HandlerFunc) http.HandlerFunc {
}
}
func AddCorsHeaders(serve http.HandlerFunc) http.HandlerFunc {
return func(writer http.ResponseWriter, request *http.Request) {
writer.Header().Set("Access-Control-Allow-Origin", "*")
writer.Header().Set("Access-Control-Allow-Headers", "*")
serve(writer, request)
}
}
// Listening function for serving the handler function.
func Listening() ListenerFunc {
return func(binding string, handler http.HandlerFunc) error {

View File

@ -9,6 +9,7 @@ import (
"os"
"path"
"testing"
"strings"
)
var (
@ -458,3 +459,32 @@ func TestValidReferrer(t *testing.T) {
})
}
}
func TestAddsCorsHeaders(t *testing.T) {
testCases := []struct {
name string
header string
value string
}{
{"Add Access-Control-Allow-Origin header", "Access-Control-Allow-Origin", "*"},
{"Add Access-Control-Allow-Headers header", "Access-Control-Allow-Headers", "*"},
}
for _, serveFile := range serveFileFuncs {
handler := AddCorsHeaders(Basic(serveFile, baseDir))
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
req := httptest.NewRequest("GET", "http://localhost/", nil)
w := httptest.NewRecorder()
handler(w, req)
resp := w.Result()
headerValue := strings.Join(resp.Header[tc.header], ", ")
if headerValue != tc.value {
t.Errorf("Response header %q = %q, want %q", tc.header, headerValue, tc.value)
}
})
}
}
}