diff --git a/README.md b/README.md index a317b81..5cd81f5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,36 @@ # docker-proxy Simple edge HTTP(s) proxy for docker containers + +``` +Application Options: + -l, --listen= listen on host:port (default: 127.0.0.1:8080) [$LISTEN] + -t, --timeout= proxy timeout (default: 5s) [$TIMEOUT] + --max= max response size (default: 64000) [$MAX_SIZE] + -g, --gzip enable gz compression [$GZIP] + -x, --header= proxy headers [$HEADER] + --dbg debug mode [$DEBUG] + +assets: + -a, --assets.location= assets location [$ASSETS_LOCATION] + --assets.root= assets web root (default: /) [$ASSETS_ROOT] + +docker: + --docker.enabled enable docker provider [$DOCKER_ENABLED] + --docker.host= docker host (default: unix:///var/run/docker.sock) [$DOCKER_HOST] + --docker.exclude= excluded containers [$DOCKER_EXCLUDE] + +file: + --file.enabled enable file provider [$FILE_ENABLED] + --file.name= file name (default: dpx.conf) [$FILE_NAME] + --file.interval= file check interval (default: 3s) [$FILE_INTERVAL] + --file.delay= file event delay (default: 500ms) [$FILE_DELAY] + +static: + --static.enabled enable static provider [$STATIC_ENABLED] + --static.rule= routing rules [$STATIC_RULES] + +Help Options: + -h, --help Show this help message + +``` \ No newline at end of file diff --git a/app/main.go b/app/main.go index a584f97..5022586 100644 --- a/app/main.go +++ b/app/main.go @@ -20,10 +20,11 @@ import ( ) var opts struct { - Listen string `short:"l" long:"listen" env:"LISTEN" default:"127.0.0.1:8080" description:"listen on host:port"` - TimeOut time.Duration `short:"t" long:"timeout" env:"TIMEOUT" default:"5s" description:"proxy timeout"` - MaxSize int64 `long:"m" long:"max" env:"MAX_SIZE" default:"64000" description:"max response size"` - GzipEnabled bool `short:"g" long:"gzip" env:"GZIP" description:"enable gz compression"` + Listen string `short:"l" long:"listen" env:"LISTEN" default:"127.0.0.1:8080" description:"listen on host:port"` + TimeOut time.Duration `short:"t" long:"timeout" env:"TIMEOUT" default:"5s" description:"proxy timeout"` + MaxSize int64 `long:"m" long:"max" env:"MAX_SIZE" default:"64000" description:"max response size"` + GzipEnabled bool `short:"g" long:"gzip" env:"GZIP" description:"enable gz compression"` + ProxyHeaders []string `short:"x" long:"header" env:"HEADER" description:"proxy headers"` Assets struct { Location string `short:"a" long:"location" env:"LOCATION" default:"" description:"assets location"` @@ -44,7 +45,7 @@ var opts struct { } `group:"file" namespace:"file" env-namespace:"FILE"` Static struct { - Enabled bool `long:"enabled" env:"ENABLED" description:"enable file provider"` + Enabled bool `long:"enabled" env:"ENABLED" description:"enable static provider"` Rules []string `long:"rule" env:"RULES" description:"routing rules"` } `group:"static" namespace:"static" env-namespace:"STATIC"` diff --git a/app/proxy/middleware/headers.go b/app/proxy/middleware/headers.go new file mode 100644 index 0000000..cfc6862 --- /dev/null +++ b/app/proxy/middleware/headers.go @@ -0,0 +1,25 @@ +package middleware + +import ( + "net/http" + "strings" +) + +// Headers middleware adds headers to request +func Headers(headers []string) func(http.Handler) http.Handler { + + return func(h http.Handler) http.Handler { + + fn := func(w http.ResponseWriter, r *http.Request) { + for _, h := range headers { + elems := strings.Split(h, ":") + if len(elems) != 2 { + continue + } + r.Header.Set(strings.TrimSpace(elems[0]), strings.TrimSpace(elems[1])) + } + h.ServeHTTP(w, r) + } + return http.HandlerFunc(fn) + } +} diff --git a/app/proxy/middleware/headers_test.go b/app/proxy/middleware/headers_test.go new file mode 100644 index 0000000..0079051 --- /dev/null +++ b/app/proxy/middleware/headers_test.go @@ -0,0 +1,23 @@ +package middleware + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestHeaders(t *testing.T) { + req := httptest.NewRequest("GET", "/something", nil) + w := httptest.NewRecorder() + + h := Headers([]string{"h1:v1", "bad", "h2:v2"})(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})) + h.ServeHTTP(w, req) + resp := w.Result() + assert.Equal(t, http.StatusOK, resp.StatusCode) + t.Logf("%+v", req.Header) + assert.Equal(t, "v1", req.Header.Get("h1")) + assert.Equal(t, "v2", req.Header.Get("h2")) + assert.Equal(t, 2, len(req.Header)) +} diff --git a/app/proxy/proxy.go b/app/proxy/proxy.go index 48efb38..8ac0db4 100644 --- a/app/proxy/proxy.go +++ b/app/proxy/proxy.go @@ -21,6 +21,7 @@ type Http struct { AssetsWebRoot string MaxBodySize int64 GzEnabled bool + ProxyHeaders []string Version string } @@ -41,6 +42,7 @@ func (h *Http) Do(ctx context.Context) error { rest.Ping, logger.New(logger.Prefix("[DEBUG] PROXY")).Handler, rest.SizeLimit(h.MaxBodySize), + middleware.Headers(h.ProxyHeaders), h.gzipHandler(), ), ReadHeaderTimeout: 5 * time.Second,