diff --git a/HISTORY.md b/HISTORY.md index f62432c0..0e741499 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -28,6 +28,8 @@ The codebase for Dependency Injection, Internationalization and localization and ## Fixes and Improvements +- Add new `URLParamSeparator` to the configuration. Defaults to "," but can be set to an empty string to disable splitting query values on `Context.URLParamSlice` method. + - [PR #1992](https://github.com/kataras/iris/pull/1992): Added support for third party packages on [httptest](https://github.com/kataras/iris/tree/master/httptest). An example using 3rd-party module named [Ginkgo](github.com/onsi/ginkgo) can be found [here](https://github.com/kataras/iris/blob/master/_examples/testing/ginkgotest). - Add `Context.Render` method for compatibility. diff --git a/configuration.go b/configuration.go index 97d554ba..931a5a44 100644 --- a/configuration.go +++ b/configuration.go @@ -350,6 +350,15 @@ var WithResetOnFireErrorCode = func(app *Application) { app.config.ResetOnFireErrorCode = true } +// WithURLParamSeparator sets the URLParamSeparator setting to "sep". +// +// See `Configuration`. +var WithURLParamSeparator = func(sep string) Configurator { + return func(app *Application) { + app.config.URLParamSeparator = &sep + } +} + // WithTimeFormat sets the TimeFormat setting. // // See `Configuration`. @@ -748,6 +757,11 @@ type Configuration struct { // Defaults to false. ResetOnFireErrorCode bool `ini:"reset_on_fire_error_code" json:"resetOnFireErrorCode,omitempty" yaml:"ResetOnFireErrorCode" toml:"ResetOnFireErrorCode"` + // URLParamSeparator defines the character(s) separator for Context.URLParamSlice. + // If empty or null then request url parameters with comma separated values will be retrieved as one. + // + // Defaults to comma ",". + URLParamSeparator *string `ini:"url_param_separator" json:"urlParamSeparator,omitempty" yaml:"URLParamSeparator" toml:"URLParamSeparator"` // EnableOptimization when this field is true // then the application tries to optimize for the best performance where is possible. // @@ -1034,6 +1048,11 @@ func (c *Configuration) GetResetOnFireErrorCode() bool { return c.ResetOnFireErrorCode } +// GetURLParamSeparator returns URLParamSeparator field. +func (c *Configuration) GetURLParamSeparator() *string { + return c.URLParamSeparator +} + // GetTimeFormat returns the TimeFormat field. func (c *Configuration) GetTimeFormat() string { return c.TimeFormat @@ -1221,6 +1240,10 @@ func WithConfiguration(c Configuration) Configurator { main.ResetOnFireErrorCode = v } + if v := c.URLParamSeparator; v != nil { + main.URLParamSeparator = v + } + if v := c.DisableBodyConsumptionOnUnmarshal; v { main.DisableBodyConsumptionOnUnmarshal = v } @@ -1319,6 +1342,10 @@ func WithConfiguration(c Configuration) Configurator { // on expired handlers when timeout handler is registered (see Timeout configuration field). var DefaultTimeoutMessage = `Timeout

Timeout

Looks like the server is taking too long to respond, this can be caused by either poor connectivity or an error with our servers. Please try again in a while.` +func toStringPtr(s string) *string { + return &s +} + // DefaultConfiguration returns the default configuration for an iris station, fills the main Configuration func DefaultConfiguration() Configuration { return Configuration{ @@ -1336,6 +1363,8 @@ func DefaultConfiguration() Configuration { DisableBodyConsumptionOnUnmarshal: false, FireEmptyFormError: false, DisableAutoFireStatusCode: false, + ResetOnFireErrorCode: false, + URLParamSeparator: toStringPtr(","), TimeFormat: "Mon, 02 Jan 2006 15:04:05 GMT", Charset: "utf-8", diff --git a/context/configuration.go b/context/configuration.go index a961e6f9..255aab4d 100644 --- a/context/configuration.go +++ b/context/configuration.go @@ -40,7 +40,8 @@ type ConfigurationReadOnly interface { GetDisableAutoFireStatusCode() bool // GetResetOnFireErrorCode returns the ResetOnFireErrorCode field. GetResetOnFireErrorCode() bool - + // GetURLParamSeparator returns URLParamSeparator field. + GetURLParamSeparator() *string // GetEnableOptimizations returns the EnableOptimizations field. GetEnableOptimizations() bool // GetEnableProtoJSON returns the EnableProtoJSON field. diff --git a/context/context.go b/context/context.go index 55d75824..8cffa0d2 100644 --- a/context/context.go +++ b/context/context.go @@ -1519,7 +1519,7 @@ func (ctx *Context) URLParam(name string) string { // URLParamSlice a shortcut of ctx.Request().URL.Query()[name]. // Like `URLParam` but it returns all values instead of a single string separated by commas. // Returns the values of a url query of the given "name" as string slice, e.g. -// ?name=john&name=doe&name=kataras will return [ john doe kataras]. +// ?names=john&names=doe&names=kataras and ?names=john,doe,kataras will return [ john doe kataras]. // // Note that, this method skips any empty entries. // @@ -1530,14 +1530,23 @@ func (ctx *Context) URLParamSlice(name string) []string { if n == 0 { return values } + + sepPtr := ctx.app.ConfigurationReadOnly().GetURLParamSeparator() normalizedValues := make([]string, 0, n) - for _, v := range values { if v == "" { continue } + if sepPtr != nil { + if sep := *sepPtr; sep != "" { + values := strings.Split(v, sep) + normalizedValues = append(normalizedValues, values...) + continue + } + } + normalizedValues = append(normalizedValues, v) } diff --git a/go.mod b/go.mod index 8a48547a..8351479c 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/kataras/blocks v0.0.7 github.com/kataras/golog v0.1.8 github.com/kataras/jwt v0.1.8 - github.com/kataras/neffos v0.0.20 + github.com/kataras/neffos v0.0.21-0.20221128161812-e8e0f317accd github.com/kataras/pio v0.0.11 github.com/kataras/sitemap v0.0.6 github.com/kataras/tunnel v0.0.4 @@ -76,12 +76,12 @@ require ( github.com/jtolds/gls v4.20.0+incompatible // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/mattn/go-isatty v0.0.16 // indirect - github.com/mediocregopher/radix/v3 v3.8.0 // indirect + github.com/mediocregopher/radix/v3 v3.8.1 // indirect github.com/minio/highwayhash v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/nats-io/jwt/v2 v2.3.0 // indirect - github.com/nats-io/nats.go v1.16.0 // indirect + github.com/nats-io/nats.go v1.20.0 // indirect github.com/nats-io/nkeys v0.3.0 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pkg/errors v0.8.1 // indirect diff --git a/go.sum b/go.sum index d0d8f119..e31e4e59 100644 --- a/go.sum +++ b/go.sum @@ -111,8 +111,8 @@ github.com/kataras/golog v0.1.8 h1:isP8th4PJH2SrbkciKnylaND9xoTtfxv++NB+DF0l9g= github.com/kataras/golog v0.1.8/go.mod h1:rGPAin4hYROfk1qT9wZP6VY2rsb4zzc37QpdPjdkqVw= github.com/kataras/jwt v0.1.8 h1:u71baOsYD22HWeSOg32tCHbczPjdCk7V4MMeJqTtmGk= github.com/kataras/jwt v0.1.8/go.mod h1:Q5j2IkcIHnfwy+oNY3TVWuEBJNw0ADgCcXK9CaZwV4o= -github.com/kataras/neffos v0.0.20 h1:swTzKZ3Mo2sIQ8ATKSKf0xDG1tuhr6w4tZmmRsvCYlg= -github.com/kataras/neffos v0.0.20/go.mod h1:srdvC/Uo8mgrApWW0AYtiiLgMbyNPf69qPsd2FhE6MQ= +github.com/kataras/neffos v0.0.21-0.20221128161812-e8e0f317accd h1:K88DPQmfghQUVnbEfT452BiQaX5AyOZ6cl/73GyYYUk= +github.com/kataras/neffos v0.0.21-0.20221128161812-e8e0f317accd/go.mod h1:4iWKOqOXXCQRLYkvA2Xg5rrdJg0+3UukvKU/rVQlcyI= github.com/kataras/pio v0.0.11 h1:kqreJ5KOEXGMwHAWHDwIl+mjfNCPhAwZPa8gK7MKlyw= github.com/kataras/pio v0.0.11/go.mod h1:38hH6SWH6m4DKSYmRhlrCJ5WItwWgCVrTNU62XZyUvI= github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY= @@ -138,8 +138,8 @@ github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mediocregopher/radix/v3 v3.8.0 h1:HI8EgkaM7WzsrFpYAkOXIgUKbjNonb2Ne7K6Le61Pmg= -github.com/mediocregopher/radix/v3 v3.8.0/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= +github.com/mediocregopher/radix/v3 v3.8.1 h1:rOkHflVuulFKlwsLY01/M2cM2tWCjDoETcMqKbAWu1M= +github.com/mediocregopher/radix/v3 v3.8.1/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.21 h1:dNH3e4PSyE4vNX+KlRGHT5KrSvjeUkoNPwEORjffHJg= github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= @@ -153,8 +153,8 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/nats-io/jwt/v2 v2.3.0 h1:z2mA1a7tIf5ShggOFlR1oBPgd6hGqcDYsISxZByUzdI= github.com/nats-io/jwt/v2 v2.3.0/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k= github.com/nats-io/nats-server/v2 v2.8.4 h1:0jQzze1T9mECg8YZEl8+WYUXb9JKluJfCBriPUtluB4= -github.com/nats-io/nats.go v1.16.0 h1:zvLE7fGBQYW6MWaFaRdsgm9qT39PJDQoju+DS8KsO1g= -github.com/nats-io/nats.go v1.16.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= +github.com/nats-io/nats.go v1.20.0 h1:T8JJnQfVSdh1CzGiwAOv5hEobYCBho/0EupGznYw0oM= +github.com/nats-io/nats.go v1.20.0/go.mod h1:tLqubohF7t4z3du1QDPYJIQQyhb4wl6DhjxEajSI7UA= github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8= github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= diff --git a/websocket/websocket.go b/websocket/websocket.go index fb65ad6a..0168a54f 100644 --- a/websocket/websocket.go +++ b/websocket/websocket.go @@ -185,6 +185,8 @@ func Handler(s *neffos.Server, idGenerator ...IDGenerator) context.Handler { // Upgrade upgrades the request and returns a new websocket Conn. // Use `Handler` for higher-level implementation instead. func Upgrade(ctx *context.Context, idGen IDGenerator, s *neffos.Server) *neffos.Conn { + /* Do NOT return the error as it is captured on the OnUpgradeError listener, + the end-developer should not be able to write to this http client directly. */ ctx.DisablePoolRelease() conn, upgradeErr := s.Upgrade(ctx.ResponseWriter(), ctx.Request(), func(socket neffos.Socket) neffos.Socket {