diff --git a/config/.proxy-example.json b/config/proxy-example.json similarity index 64% rename from config/.proxy-example.json rename to config/proxy-example.json index f5623fc887..03a2a32fa0 100644 --- a/config/.proxy-example.json +++ b/config/proxy-example.json @@ -20,11 +20,19 @@ "backend": "http://localhost:9130" }, { - "endpoint": "/ocs/v1.php/", + "endpoint": "/ocs/", "backend": "http://localhost:9140" }, { - "endpoint": "/remote.php/webdav/", + "endpoint": "/remote.php/", + "backend": "http://localhost:9140" + }, + { + "endpoint": "/dav/", + "backend": "http://localhost:9140" + }, + { + "endpoint": "/webdav/", "backend": "http://localhost:9140" } ] @@ -49,12 +57,24 @@ "backend": "http://localhost:9130" }, { - "endpoint": "/ocs/v1.php/", - "backend": "http://localhost:9140" + "endpoint": "/ocs/", + "backend": "https://demo.owncloud.com", + "apache-vhost": true }, { - "endpoint": "/remote.php/webdav/", - "backend": "http://localhost:9140" + "endpoint": "/remote.php/", + "backend": "https://demo.owncloud.com", + "apache-vhost": true + }, + { + "endpoint": "/dav/", + "backend": "https://demo.owncloud.com", + "apache-vhost": true + }, + { + "endpoint": "/webdav/", + "backend": "https://demo.owncloud.com", + "apache-vhost": true } ] } diff --git a/pkg/command/health.go b/pkg/command/health.go index cdc66b864a..39210e4d8a 100644 --- a/pkg/command/health.go +++ b/pkg/command/health.go @@ -5,7 +5,6 @@ import ( "net/http" "github.com/micro/cli/v2" - "github.com/owncloud/ocis-pkg/v2/log" "github.com/owncloud/ocis-proxy/pkg/config" "github.com/owncloud/ocis-proxy/pkg/flagset" ) @@ -17,7 +16,7 @@ func Health(cfg *config.Config) *cli.Command { Usage: "Check health status", Flags: flagset.HealthWithConfig(cfg), Action: func(c *cli.Context) error { - logger := log.NewLogger() + logger := NewLogger(cfg) resp, err := http.Get( fmt.Sprintf( diff --git a/pkg/command/root.go b/pkg/command/root.go index 94836d70d0..a4691f3f30 100644 --- a/pkg/command/root.go +++ b/pkg/command/root.go @@ -32,7 +32,7 @@ func Execute() error { Flags: flagset.RootWithConfig(cfg), Before: func(c *cli.Context) error { - logger := log.NewLogger() + logger := NewLogger(cfg) viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) viper.SetEnvPrefix("PROXY") @@ -91,3 +91,13 @@ func Execute() error { return app.Run(os.Args) } + +// NewLogger initializes a service-specific logger instance. +func NewLogger(cfg *config.Config) log.Logger { + return log.NewLogger( + log.Name("proxy"), + log.Level(cfg.Log.Level), + log.Pretty(cfg.Log.Pretty), + log.Color(cfg.Log.Color), + ) +} diff --git a/pkg/command/server.go b/pkg/command/server.go index ce809cad76..51bd4d6ee2 100644 --- a/pkg/command/server.go +++ b/pkg/command/server.go @@ -14,7 +14,6 @@ import ( "github.com/oklog/run" openzipkin "github.com/openzipkin/zipkin-go" zipkinhttp "github.com/openzipkin/zipkin-go/reporter/http" - "github.com/owncloud/ocis-pkg/v2/log" "github.com/owncloud/ocis-proxy/pkg/config" "github.com/owncloud/ocis-proxy/pkg/flagset" "github.com/owncloud/ocis-proxy/pkg/metrics" @@ -39,7 +38,7 @@ func Server(cfg *config.Config) *cli.Command { return nil }, Action: func(c *cli.Context) error { - logger := log.NewLogger() + logger := NewLogger(cfg) httpNamespace := c.String("http-namespace") if cfg.Tracing.Enabled { @@ -134,7 +133,10 @@ func Server(cfg *config.Config) *cli.Command { defer cancel() - rp := proxy.NewMultiHostReverseProxy(cfg) + rp := proxy.NewMultiHostReverseProxy( + proxy.Logger(logger), + proxy.Config(cfg), + ) { server, err := http.Server( diff --git a/pkg/config/config.go b/pkg/config/config.go index d53a925ffc..3fe87f8180 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -38,14 +38,15 @@ type Asset struct { // Policy enables us to use multiple directors. type Policy struct { - Name string `json:"name"` - Routes []Route `json:"routes"` + Name string `mapstructure:"name"` + Routes []Route `mapstructure:"routes"` } // Route define forwarding routes type Route struct { - Endpoint string `json:"endpoint"` - Backend string `json:"backend"` + Endpoint string `mapstructure:"endpoint"` + Backend string `mapstructure:"backend"` + ApacheVHost bool `mapstructure:"apache-vhost"` } // Config combines all available configuration parts. @@ -56,7 +57,7 @@ type Config struct { HTTP HTTP Tracing Tracing Asset Asset - Policies []Policy `json:"policies"` + Policies []Policy `mapstructure:"policies"` } // New initializes a new configuration with or without defaults. diff --git a/pkg/flagset/flagset.go b/pkg/flagset/flagset.go index 7f04f1cd0b..00c9d84cb0 100644 --- a/pkg/flagset/flagset.go +++ b/pkg/flagset/flagset.go @@ -24,12 +24,14 @@ func RootWithConfig(cfg *config.Config) []cli.Flag { }, &cli.BoolFlag{ Name: "log-pretty", + Value: true, Usage: "Enable pretty logging", EnvVars: []string{"PROXY_LOG_PRETTY"}, Destination: &cfg.Log.Pretty, }, &cli.BoolFlag{ Name: "log-color", + Value: true, Usage: "Enable colored logging", EnvVars: []string{"PROXY_LOG_COLOR"}, Destination: &cfg.Log.Color, diff --git a/pkg/proxy/option.go b/pkg/proxy/option.go new file mode 100644 index 0000000000..b2de9124dd --- /dev/null +++ b/pkg/proxy/option.go @@ -0,0 +1,40 @@ +package proxy + +import ( + "github.com/owncloud/ocis-pkg/v2/log" + "github.com/owncloud/ocis-proxy/pkg/config" +) + +// Option defines a single option function. +type Option func(o *Options) + +// Options defines the available options for this package. +type Options struct { + Logger log.Logger + Config *config.Config +} + +// newOptions initializes the available default options. +func newOptions(opts ...Option) Options { + opt := Options{} + + for _, o := range opts { + o(&opt) + } + + return opt +} + +// Logger provides a function to set the logger option. +func Logger(val log.Logger) Option { + return func(o *Options) { + o.Logger = val + } +} + +// Config provides a function to set the config option. +func Config(val *config.Config) Option { + return func(o *Options) { + o.Config = val + } +} diff --git a/pkg/proxy/proxy.go b/pkg/proxy/proxy.go index af3d7cff88..a34772ddb4 100644 --- a/pkg/proxy/proxy.go +++ b/pkg/proxy/proxy.go @@ -10,29 +10,38 @@ import ( "github.com/owncloud/ocis-proxy/pkg/config" ) -// initialize a local logger instance -var logger = log.NewLogger() - // MultiHostReverseProxy extends httputil to support multiple hosts with diffent policies type MultiHostReverseProxy struct { httputil.ReverseProxy Directors map[string]map[string]func(req *http.Request) + logger log.Logger } // NewMultiHostReverseProxy undocummented -func NewMultiHostReverseProxy(conf *config.Config) *MultiHostReverseProxy { - reverseProxy := &MultiHostReverseProxy{Directors: make(map[string]map[string]func(req *http.Request))} +func NewMultiHostReverseProxy(opts ...Option) *MultiHostReverseProxy { + options := newOptions(opts...) - for _, policy := range conf.Policies { + reverseProxy := &MultiHostReverseProxy{ + Directors: make(map[string]map[string]func(req *http.Request)), + logger: options.Logger, + } + + for _, policy := range options.Config.Policies { for _, route := range policy.Routes { uri, err := url.Parse(route.Backend) if err != nil { - logger. + reverseProxy.logger. Fatal(). Err(err). Msgf("malformed url: %v", route.Backend) } - reverseProxy.AddHost(policy.Name, uri, route.Endpoint) + + reverseProxy.logger. + Debug(). + Interface("route", route). + Msg("adding route") + + reverseProxy.AddHost(policy.Name, uri, route) } } @@ -52,14 +61,18 @@ func singleJoiningSlash(a, b string) string { } // AddHost undocumented -func (p *MultiHostReverseProxy) AddHost(policy string, target *url.URL, endpoint string) { +func (p *MultiHostReverseProxy) AddHost(policy string, target *url.URL, rt config.Route) { targetQuery := target.RawQuery if p.Directors[policy] == nil { p.Directors[policy] = make(map[string]func(req *http.Request)) } - p.Directors[policy][endpoint] = func(req *http.Request) { + p.Directors[policy][rt.Endpoint] = func(req *http.Request) { req.URL.Scheme = target.Scheme req.URL.Host = target.Host + if rt.ApacheVHost { + req.Host = target.Host + } + req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path) if targetQuery == "" || req.URL.RawQuery == "" { req.URL.RawQuery = targetQuery + req.URL.RawQuery @@ -79,7 +92,7 @@ func (p *MultiHostReverseProxy) ServeHTTP(w http.ResponseWriter, r *http.Request policy := "reva" if _, ok := p.Directors[policy]; !ok { - logger. + p.logger. Error(). Msgf("policy %v is not configured", policy) } @@ -88,6 +101,12 @@ func (p *MultiHostReverseProxy) ServeHTTP(w http.ResponseWriter, r *http.Request if strings.HasPrefix(r.URL.Path, k) && k != "/" { p.Director = p.Directors[policy][k] hit = true + p.logger. + Debug(). + Str("policy", policy). + Str("prefix", k). + Str("path", r.URL.Path). + Msg("director found") } }