diff --git a/core/router/api_builder.go b/core/router/api_builder.go index 6e591430..8f9c81c4 100644 --- a/core/router/api_builder.go +++ b/core/router/api_builder.go @@ -974,12 +974,14 @@ func (api *APIBuilder) Favicon(favPath string, requestPath ...string) *Route { // OnErrorCode registers a handlers chain for this `Party` for a specific HTTP status code. // Read more at: http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml // Look `OnAnyErrorCode` too. -func (api *APIBuilder) OnErrorCode(statusCode int, handlers ...context.Handler) { - api.handle(statusCode, "", "/", handlers...) +func (api *APIBuilder) OnErrorCode(statusCode int, handlers ...context.Handler) (routes []*Route) { + routes = append(routes, api.handle(statusCode, "", "/", handlers...)) if api.relativePath != "/" { - api.handle(statusCode, "", "/{tail:path}", handlers...) + routes = append(routes, api.handle(statusCode, "", "/{tail:path}", handlers...)) } + + return } // ClientErrorCodes holds the 4xx Client errors. @@ -1083,10 +1085,12 @@ func StatusText(code int) string { // OnAnyErrorCode registers a handlers chain for all error codes // (4xxx and 5xxx, change the `ClientErrorCodes` and `ServerErrorCodes` variables to modify those) // Look `OnErrorCode` too. -func (api *APIBuilder) OnAnyErrorCode(handlers ...context.Handler) { +func (api *APIBuilder) OnAnyErrorCode(handlers ...context.Handler) (routes []*Route) { for _, statusCode := range append(ClientErrorCodes, ServerErrorCodes...) { - api.OnErrorCode(statusCode, handlers...) + routes = append(routes, api.OnErrorCode(statusCode, handlers...)...) } + + return } // Layout overrides the parent template layout with a more specific layout for this Party. diff --git a/core/router/api_container.go b/core/router/api_container.go index ab1d4f03..9b9c1175 100644 --- a/core/router/api_container.go +++ b/core/router/api_container.go @@ -97,6 +97,14 @@ func (api *APIContainer) convertHandlerFuncs(relativePath string, handlersFn ... return handlers } +func fixRouteInfo(route *Route, handlersFn []interface{}) { + // Fix main handler name and source modified by execution rules wrapper. + route.MainHandlerName, route.MainHandlerIndex = context.MainHandlerName(handlersFn...) + if len(handlersFn) > route.MainHandlerIndex { + route.SourceFileName, route.SourceLineNumber = context.HandlerFileLineRel(handlersFn[route.MainHandlerIndex]) + } +} + // Handler receives a function which can receive dependencies and output result // and returns a common Iris Handler, useful for Versioning API integration otherwise // the `Handle/Get/Post...` methods are preferable. @@ -134,13 +142,7 @@ func (api *APIContainer) Done(handlersFn ...interface{}) { func (api *APIContainer) Handle(method, relativePath string, handlersFn ...interface{}) *Route { handlers := api.convertHandlerFuncs(relativePath, handlersFn...) route := api.Self.Handle(method, relativePath, handlers...) - - // Fix main handler name and source modified by execution rules wrapper. - route.MainHandlerName, route.MainHandlerIndex = context.MainHandlerName(handlersFn...) - if len(handlersFn) > route.MainHandlerIndex { - route.SourceFileName, route.SourceLineNumber = context.HandlerFileLineRel(handlersFn[route.MainHandlerIndex]) - } - + fixRouteInfo(route, handlersFn) return route } diff --git a/core/router/party.go b/core/router/party.go index 6fd2d403..b553aa93 100644 --- a/core/router/party.go +++ b/core/router/party.go @@ -36,11 +36,11 @@ type Party interface { // OnErrorCode registers a handlers chain for this `Party` for a specific HTTP status code. // Read more at: http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml // Look `OnAnyErrorCode` too. - OnErrorCode(statusCode int, handlers ...context.Handler) + OnErrorCode(statusCode int, handlers ...context.Handler) []*Route // OnAnyErrorCode registers a handlers chain for all error codes // (4xxx and 5xxx, change the `ClientErrorCodes` and `ServerErrorCodes` variables to modify those) // Look `OnErrorCode` too. - OnAnyErrorCode(handlers ...context.Handler) + OnAnyErrorCode(handlers ...context.Handler) []*Route // Party groups routes which may have the same prefix and share same handlers, // returns that new rich subrouter. diff --git a/sessions/sessiondb/redis/database.go b/sessions/sessiondb/redis/database.go index a83f907b..a731b5da 100644 --- a/sessions/sessiondb/redis/database.go +++ b/sessions/sessiondb/redis/database.go @@ -1,6 +1,7 @@ package redis import ( + "crypto/tls" "errors" "time" @@ -45,6 +46,11 @@ type Config struct { // Delim the delimeter for the keys on the sessiondb. Defaults to "-". Delim string + // TLSConfig will cause Dial to perform a TLS handshake using the provided + // config. If is nil then no TLS is used. + // See https://golang.org/pkg/crypto/tls/#Config + TLSConfig *tls.Config + // Driver supports `Redigo()` or `Radix()` go clients for redis. // Configure each driver by the return value of their constructors. // @@ -63,6 +69,7 @@ func DefaultConfig() Config { Timeout: DefaultRedisTimeout, Prefix: "", Delim: DefaultDelim, + TLSConfig: nil, Driver: Redigo(), } } diff --git a/sessions/sessiondb/redis/driver_radix.go b/sessions/sessiondb/redis/driver_radix.go index be0b3680..1ec53c25 100644 --- a/sessions/sessiondb/redis/driver_radix.go +++ b/sessions/sessiondb/redis/driver_radix.go @@ -45,6 +45,10 @@ func (r *RadixDriver) Connect(c Config) error { var options []radix.DialOpt + if c.TLSConfig != nil { + options = append(options, radix.DialUseTLS(c.TLSConfig)) + } + if c.Password != "" { options = append(options, radix.DialAuthPass(c.Password)) } diff --git a/sessions/sessiondb/redis/driver_redigo.go b/sessions/sessiondb/redis/driver_redigo.go index d730c6fa..81ee0044 100644 --- a/sessions/sessiondb/redis/driver_redigo.go +++ b/sessions/sessiondb/redis/driver_redigo.go @@ -271,62 +271,61 @@ func (r *RedigoDriver) Delete(key string) error { return err } -func dial(network string, addr string, pass string, timeout time.Duration) (redis.Conn, error) { - if network == "" { - network = DefaultRedisNetwork - } - if addr == "" { - addr = DefaultRedisAddr - } - - var options []redis.DialOption - - if timeout > 0 { - options = append(options, - redis.DialConnectTimeout(timeout), - redis.DialReadTimeout(timeout), - redis.DialWriteTimeout(timeout)) - } - - c, err := redis.Dial(network, addr, options...) - if err != nil { - return nil, err - } - - if pass != "" { - if _, err = c.Do("AUTH", pass); err != nil { - c.Close() - return nil, err - } - } - return c, err -} - -// Connect connects to the redis, called only once +// Connect connects to the redis, called only once. func (r *RedigoDriver) Connect(c Config) error { + if c.Network == "" { + c.Network = DefaultRedisNetwork + } + + if c.Addr == "" { + c.Addr = DefaultRedisAddr + } + pool := &redis.Pool{IdleTimeout: r.IdleTimeout, MaxIdle: r.MaxIdle, Wait: r.Wait, MaxActive: c.MaxActive} pool.TestOnBorrow = func(c redis.Conn, t time.Time) error { _, err := c.Do("PING") return err } - if c.Database != "" { - pool.Dial = func() (redis.Conn, error) { - red, err := dial(c.Network, c.Addr, c.Password, c.Timeout) - if err != nil { - return nil, err - } - if _, err = red.Do("SELECT", c.Database); err != nil { - red.Close() - return nil, err - } - return red, err - } - } else { - pool.Dial = func() (redis.Conn, error) { - return dial(c.Network, c.Addr, c.Password, c.Timeout) - } + var options []redis.DialOption + + if c.Timeout > 0 { + options = append(options, + redis.DialConnectTimeout(c.Timeout), + redis.DialReadTimeout(c.Timeout), + redis.DialWriteTimeout(c.Timeout)) } + + if c.TLSConfig != nil { + options = append(options, + redis.DialTLSConfig(c.TLSConfig), + redis.DialUseTLS(true), + ) + } + + pool.Dial = func() (redis.Conn, error) { + conn, err := redis.Dial(c.Network, c.Addr, options...) + if err != nil { + return nil, err + } + + if c.Password != "" { + if _, err = conn.Do("AUTH", c.Password); err != nil { + conn.Close() + return nil, err + } + } + + if c.Database != "" { + if _, err = conn.Do("SELECT", c.Database); err != nil { + conn.Close() + return nil, err + } + } + + return conn, err + } + r.Connected = true r.pool = pool r.Config = c