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 = `
TimeoutTimeout
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 {