Merge pull request #36 from demipel8/master

CORS support
pull/37/head
Jeromy Streets 5 years ago committed by GitHub
commit e5e449a275
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      Dockerfile
  2. 4
      Dockerfile.all
  3. 4
      README.md
  4. 5
      cli/help/help.go
  5. 5
      cli/server/server.go
  6. 38
      cli/server/server_test.go
  7. 5
      config/config.go
  8. 9
      handle/handle.go
  9. 30
      handle/handle_test.go

@ -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.6
ENV BUILD_DIR /build ENV BUILD_DIR /build
RUN mkdir -p ${BUILD_DIR} RUN mkdir -p ${BUILD_DIR}

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

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

@ -61,6 +61,11 @@ func handlerSelector() (handler http.HandlerFunc) {
if !config.Get.ShowListing { if !config.Get.ShowListing {
handler = handle.IgnoreIndex(handler) handler = handle.IgnoreIndex(handler)
} }
if config.Get.Cors {
handler = handle.AddCorsHeaders(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()
}) })

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

@ -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. // 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 {

@ -9,6 +9,7 @@ import (
"os" "os"
"path" "path"
"testing" "testing"
"strings"
) )
var ( 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)
}
})
}
}
}

Loading…
Cancel
Save