diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..85fbf7d4 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,5 @@ +# patreon: # Replace with a single Patreon username +# open_collective: # Replace with a single Open Collective username +# ko_fi: # Replace with a single Ko-fi username +# tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +custom: https://iris-go.com/donate # Replace with a single custom sponsorship URL diff --git a/_benchmarks/benchmarks_third_party_source_snapshot_go_01_march_2019.png b/_benchmarks/benchmarks_third_party_source_snapshot_go_01_march_2019.png new file mode 100644 index 00000000..cfab7400 Binary files /dev/null and b/_benchmarks/benchmarks_third_party_source_snapshot_go_01_march_2019.png differ diff --git a/_examples/cache/simple/main.go b/_examples/cache/simple/main.go index 3b3fd88b..b5531c7f 100644 --- a/_examples/cache/simple/main.go +++ b/_examples/cache/simple/main.go @@ -61,7 +61,7 @@ func main() { app.Logger().SetLevel("debug") app.Get("/", cache.Handler(10*time.Second), writeMarkdown) // saves its content on the first request and serves it instead of re-calculating the content. - // After 10 seconds it will be cleared and resetted. + // After 10 seconds it will be cleared and reset. app.Run(iris.Addr(":8080")) } diff --git a/_examples/http-listening/custom-httpserver/easy-way/main.go b/_examples/http-listening/custom-httpserver/easy-way/main.go index ff260302..158b2c5a 100644 --- a/_examples/http-listening/custom-httpserver/easy-way/main.go +++ b/_examples/http-listening/custom-httpserver/easy-way/main.go @@ -17,7 +17,7 @@ func main() { ctx.Writef("Hello from %s", ctx.Path()) }) - // Any custom fields here. Handler and ErrorLog are setted to the server automatically + // Any custom fields here. Handler and ErrorLog are set to the server automatically srv := &http.Server{Addr: ":8080"} // http://localhost:8080/ diff --git a/_examples/miscellaneous/i18n/main.go b/_examples/miscellaneous/i18n/main.go index 8b0e93d9..ef103723 100644 --- a/_examples/miscellaneous/i18n/main.go +++ b/_examples/miscellaneous/i18n/main.go @@ -22,10 +22,10 @@ func newApp() *iris.Application { // it tries to find the language by: // ctx.Values().GetString("language") // if that was empty then - // it tries to find from the URLParameter setted on the configuration + // it tries to find from the URLParameter set on the configuration // if not found then // it tries to find the language by the "language" cookie - // if didn't found then it it set to the Default setted on the configuration + // if didn't found then it it set to the Default set on the configuration // hi is the key, 'iris' is the %s on the .ini file // the second parameter is optional diff --git a/_examples/routing/README.md b/_examples/routing/README.md index c37b75b2..225b0d3b 100644 --- a/_examples/routing/README.md +++ b/_examples/routing/README.md @@ -966,7 +966,7 @@ type Context interface { // ContentType sets the response writer's header key "Content-Type" to the 'cType'. ContentType(cType string) // GetContentType returns the response writer's header value of "Content-Type" - // which may, setted before with the 'ContentType'. + // which may, set before with the 'ContentType'. GetContentType() string // GetContentType returns the request's header value of "Content-Type". GetContentTypeRequested() string @@ -1259,7 +1259,7 @@ type Context interface { // // This function may be used in the following cases: // - // * if response body is too big (more than iris.LimitRequestBodySize(if setted)). + // * if response body is too big (more than iris.LimitRequestBodySize(if set)). // * if response body is streamed from slow external sources. // * if response body must be streamed to the client in chunks. // (aka `http server push`). @@ -1299,7 +1299,7 @@ type Context interface { // is being called afterwards, in the same request. // Useful when need to set or/and change a layout based on the previous handlers in the chain. // - // Note that the 'layoutTmplFile' argument can be setted to iris.NoLayout || view.NoLayout + // Note that the 'layoutTmplFile' argument can be set to iris.NoLayout || view.NoLayout // to disable the layout for a specific view render action, // it disables the engine's configuration's layout property. // diff --git a/_examples/sessions/database/badger/main.go b/_examples/sessions/database/badger/main.go index 4f24b317..fb5a9646 100644 --- a/_examples/sessions/database/badger/main.go +++ b/_examples/sessions/database/badger/main.go @@ -44,7 +44,7 @@ func main() { //set session values s.Set("name", "iris") - //test if setted here + //test if set here ctx.Writef("All ok session value of the 'name' is: %s", s.GetString("name")) }) @@ -54,7 +54,7 @@ func main() { // set session values s.Set(key, value) - // test if setted here + // test if set here ctx.Writef("All ok session value of the '%s' is: %s", key, s.GetString(key)) }) diff --git a/_examples/sessions/database/boltdb/main.go b/_examples/sessions/database/boltdb/main.go index 3e2d894f..721be3ae 100644 --- a/_examples/sessions/database/boltdb/main.go +++ b/_examples/sessions/database/boltdb/main.go @@ -45,7 +45,7 @@ func main() { //set session values s.Set("name", "iris") - //test if setted here + //test if set here ctx.Writef("All ok session value of the 'name' is: %s", s.GetString("name")) }) @@ -55,7 +55,7 @@ func main() { // set session values s.Set(key, value) - // test if setted here + // test if set here ctx.Writef("All ok session value of the '%s' is: %s", key, s.GetString(key)) }) diff --git a/_examples/sessions/database/redis/main.go b/_examples/sessions/database/redis/main.go index 36d7cca2..e48f736f 100644 --- a/_examples/sessions/database/redis/main.go +++ b/_examples/sessions/database/redis/main.go @@ -53,7 +53,7 @@ func main() { //set session values s.Set("name", "iris") - //test if setted here + //test if set here ctx.Writef("All ok session value of the 'name' is: %s", s.GetString("name")) }) @@ -63,7 +63,7 @@ func main() { // set session values s.Set(key, value) - // test if setted here + // test if set here ctx.Writef("All ok session value of the '%s' is: %s", key, s.GetString(key)) }) @@ -74,7 +74,7 @@ func main() { // set session values s.Set(key, value) valueSet := s.Get(key) - // test if setted here + // test if set here ctx.Writef("All ok session value of the '%s' is: %v", key, valueSet) }) diff --git a/_examples/sessions/flash-messages/main.go b/_examples/sessions/flash-messages/main.go index 55be2594..cfece6d6 100644 --- a/_examples/sessions/flash-messages/main.go +++ b/_examples/sessions/flash-messages/main.go @@ -13,7 +13,7 @@ func main() { app.Get("/set", func(ctx iris.Context) { s := sess.Start(ctx) s.SetFlash("name", "iris") - ctx.Writef("Message setted, is available for the next request") + ctx.Writef("Message set, is available for the next request") }) app.Get("/get", func(ctx iris.Context) { diff --git a/_examples/sessions/securecookie/main.go b/_examples/sessions/securecookie/main.go index f4e1730d..da2a4101 100644 --- a/_examples/sessions/securecookie/main.go +++ b/_examples/sessions/securecookie/main.go @@ -39,8 +39,8 @@ func newApp() *iris.Application { s := mySessions.Start(ctx) s.Set("name", "iris") - //test if setted here - ctx.Writef("All ok session setted to: %s", s.GetString("name")) + //test if set here + ctx.Writef("All ok session set to: %s", s.GetString("name")) }) app.Get("/get", func(ctx iris.Context) { diff --git a/_examples/sessions/securecookie/main_test.go b/_examples/sessions/securecookie/main_test.go index e9b40797..a972680a 100644 --- a/_examples/sessions/securecookie/main_test.go +++ b/_examples/sessions/securecookie/main_test.go @@ -14,14 +14,14 @@ func TestSessionsEncodeDecode(t *testing.T) { es := e.GET("/set").Expect() es.Status(iris.StatusOK) es.Cookies().NotEmpty() - es.Body().Equal("All ok session setted to: iris") + es.Body().Equal("All ok session set to: iris") e.GET("/get").Expect().Status(iris.StatusOK).Body().Equal("The name on the /set was: iris") // delete and re-get e.GET("/delete").Expect().Status(iris.StatusOK) e.GET("/get").Expect().Status(iris.StatusOK).Body().Equal("The name on the /set was: ") // set, clear and re-get - e.GET("/set").Expect().Body().Equal("All ok session setted to: iris") + e.GET("/set").Expect().Body().Equal("All ok session set to: iris") e.GET("/clear").Expect().Status(iris.StatusOK) e.GET("/get").Expect().Status(iris.StatusOK).Body().Equal("The name on the /set was: ") } diff --git a/_examples/sessions/standalone/main.go b/_examples/sessions/standalone/main.go index 343ac5e6..e413b0e9 100644 --- a/_examples/sessions/standalone/main.go +++ b/_examples/sessions/standalone/main.go @@ -44,8 +44,8 @@ func main() { s := sess.Start(ctx) s.Set("name", "iris") - //test if setted here. - ctx.Writef("All ok session setted to: %s", s.GetString("name")) + //test if set here. + ctx.Writef("All ok session set to: %s", s.GetString("name")) // Set will set the value as-it-is, // if it's a slice or map diff --git a/_examples/view/context-view-data/main.go b/_examples/view/context-view-data/main.go index 732a1a3c..322ae804 100644 --- a/_examples/view/context-view-data/main.go +++ b/_examples/view/context-view-data/main.go @@ -29,7 +29,7 @@ func main() { }) app.Get("/", func(ctx iris.Context) { - ctx.ViewData("BodyMessage", "a sample text here... setted by the route handler") + ctx.ViewData("BodyMessage", "a sample text here... set by the route handler") if err := ctx.View("index.html"); err != nil { ctx.Application().Logger().Infof(err.Error()) } @@ -37,7 +37,7 @@ func main() { app.Get("/about", func(ctx iris.Context) { ctx.ViewData("Title", "My About Page") - ctx.ViewData("BodyMessage", "about text here... setted by the route handler") + ctx.ViewData("BodyMessage", "about text here... set by the route handler") // same file, just to keep things simple. if err := ctx.View("index.html"); err != nil { diff --git a/cache/browser_test.go b/cache/browser_test.go index f7e05085..8c691df5 100644 --- a/cache/browser_test.go +++ b/cache/browser_test.go @@ -91,13 +91,13 @@ func TestETag(t *testing.T) { e := httptest.New(t, app) r := e.GET("/").Expect().Status(httptest.StatusOK) - r.Header("ETag").Equal("/") // test if header setted. + r.Header("ETag").Equal("/") // test if header set. r.Body().Equal("_") e.GET("/").WithHeader("ETag", "/").WithHeader("If-None-Match", "/").Expect(). Status(httptest.StatusNotModified).Body().Equal("") // browser is responsible, no the test engine. r = e.GET("/").Expect().Status(httptest.StatusOK) - r.Header("ETag").Equal("/") // test if header setted. + r.Header("ETag").Equal("/") // test if header set. r.Body().Equal("__") } diff --git a/cache/cfg/cfg.go b/cache/cfg/cfg.go index dbd20f3e..b97947ed 100644 --- a/cache/cfg/cfg.go +++ b/cache/cfg/cfg.go @@ -16,7 +16,7 @@ var ( RequestCacheTimeout = 5 * time.Second ) -// NoCacheHeader is the static header key which is setted to the response when NoCache is called, +// NoCacheHeader is the static header key which is set to the response when NoCache is called, // used inside nethttp and fhttp Skippers. var NoCacheHeader = "X-No-Cache" diff --git a/cache/entry/response.go b/cache/entry/response.go index 7e24f44b..5e103dcb 100644 --- a/cache/entry/response.go +++ b/cache/entry/response.go @@ -3,7 +3,7 @@ package entry import "net/http" // Response is the cached response will be send to the clients -// its fields setted at runtime on each of the non-cached executions +// its fields set at runtime on each of the non-cached executions // non-cached executions = first execution, and each time after // cache expiration datetime passed. type Response struct { diff --git a/cache/uri/uribuilder.go b/cache/uri/uribuilder.go index 383336f3..83ee3efd 100644 --- a/cache/uri/uribuilder.go +++ b/cache/uri/uribuilder.go @@ -62,7 +62,7 @@ func (r *URIBuilder) ContentType(s string) *URIBuilder { } // String returns the full url which should be passed to get a cache entry response back -// (it could be setted by server too but we need some client-freedom on the requested key) +// (it could be set by server too but we need some client-freedom on the requested key) // in order to be sure that the registered cache entries are unique among different clients with the same key // note1: we do it manually*, // note2: on fasthttp that is not required because the query args added as expected but we will use it there too to be align with net/http diff --git a/configuration.go b/configuration.go index e4bc892f..cf236879 100644 --- a/configuration.go +++ b/configuration.go @@ -588,7 +588,7 @@ func (tc TunnelingConfiguration) createTunnel(tunnelAPIRequest ngrokTunnel, publ // these can be passed via options also, look at the top of this file(configuration.go). // Configuration is a valid OptionSetter. type Configuration struct { - // vhost is private and setted only with .Run method, it cannot be changed after the first set. + // vhost is private and set only with .Run method, it cannot be changed after the first set. // It can be retrieved by the context if needed (i.e router for subdomains) vhost string @@ -609,11 +609,11 @@ type Configuration struct { // Defaults to an empty slice. IgnoreServerErrors []string `json:"ignoreServerErrors,omitempty" yaml:"IgnoreServerErrors" toml:"IgnoreServerErrors"` - // DisableStartupLog if setted to true then it turns off the write banner on server startup. + // DisableStartupLog if set to true then it turns off the write banner on server startup. // // Defaults to false. DisableStartupLog bool `json:"disableStartupLog,omitempty" yaml:"DisableStartupLog" toml:"DisableStartupLog"` - // DisableInterruptHandler if setted to true then it disables the automatic graceful server shutdown + // DisableInterruptHandler if set to true then it disables the automatic graceful server shutdown // when control/cmd+C pressed. // Turn this to true if you're planning to handle this by your own via a custom host.Task. // @@ -662,11 +662,11 @@ type Configuration struct { FireMethodNotAllowed bool `json:"fireMethodNotAllowed,omitempty" yaml:"FireMethodNotAllowed" toml:"FireMethodNotAllowed"` // DisableBodyConsumptionOnUnmarshal manages the reading behavior of the context's body readers/binders. - // If setted to true then it + // If set to true then it // disables the body consumption by the `context.UnmarshalBody/ReadJSON/ReadXML`. // // By-default io.ReadAll` is used to read the body from the `context.Request.Body which is an `io.ReadCloser`, - // if this field setted to true then a new buffer will be created to read from and the request body. + // if this field set to true then a new buffer will be created to read from and the request body. // The body will not be changed and existing data before the // context.UnmarshalBody/ReadJSON/ReadXML will be not consumed. DisableBodyConsumptionOnUnmarshal bool `json:"disableBodyConsumptionOnUnmarshal,omitempty" yaml:"DisableBodyConsumptionOnUnmarshal" toml:"DisableBodyConsumptionOnUnmarshal"` @@ -678,7 +678,7 @@ type Configuration struct { // By-default a custom http error handler will be fired when "context.StatusCode(code)" called, // code should be equal with the result of the the `context.StatusCodeNotSuccessful` in order to be received as an "http error handler". // - // Developer may want this option to setted as true in order to manually call the + // Developer may want this option to set as true in order to manually call the // error handlers when needed via "context#FireStatusCode(< 200 || >= 400)". // HTTP Custom error handlers are being registered via app.OnErrorCode(code, handler)". // @@ -807,7 +807,7 @@ func (c Configuration) GetFireMethodNotAllowed() bool { // is disabled. // // By-default io.ReadAll` is used to read the body from the `context.Request.Body which is an `io.ReadCloser`, -// if this field setted to true then a new buffer will be created to read from and the request body. +// if this field set to true then a new buffer will be created to read from and the request body. // The body will not be changed and existing data before the // context.UnmarshalBody/ReadJSON/ReadXML will be not consumed. func (c Configuration) GetDisableBodyConsumptionOnUnmarshal() bool { diff --git a/configuration_test.go b/configuration_test.go index 32f5bcf8..052da0eb 100644 --- a/configuration_test.go +++ b/configuration_test.go @@ -61,7 +61,7 @@ func TestConfigurationOptions(t *testing.T) { t.Fatalf("Expected configuration DisableStartupLog to be: %#v but got: %#v", disableBanner, got) } - // now check if other default values are setted (should be setted automatically) + // now check if other default values are set (should be set automatically) expected := DefaultConfiguration() expected.Charset = charset diff --git a/context/configuration.go b/context/configuration.go index 95039516..9eaee9f2 100644 --- a/context/configuration.go +++ b/context/configuration.go @@ -41,7 +41,7 @@ type ConfigurationReadOnly interface { // is disabled. // // By-default io.ReadAll` is used to read the body from the `context.Request.Body which is an `io.ReadCloser`, - // if this field setted to true then a new buffer will be created to read from and the request body. + // if this field set to true then a new buffer will be created to read from and the request body. // The body will not be changed and existing data before the // context.UnmarshalBody/ReadJSON/ReadXML will be not consumed. GetDisableBodyConsumptionOnUnmarshal() bool diff --git a/context/context.go b/context/context.go index aa76f9f5..44270a85 100644 --- a/context/context.go +++ b/context/context.go @@ -369,7 +369,7 @@ type Context interface { // ContentType sets the response writer's header key "Content-Type" to the 'cType'. ContentType(cType string) // GetContentType returns the response writer's header value of "Content-Type" - // which may, setted before with the 'ContentType'. + // which may, set before with the 'ContentType'. GetContentType() string // GetContentType returns the request's header value of "Content-Type". GetContentTypeRequested() string @@ -669,7 +669,7 @@ type Context interface { // // This function may be used in the following cases: // - // * if response body is too big (more than iris.LimitRequestBodySize(if setted)). + // * if response body is too big (more than iris.LimitRequestBodySize(if set)). // * if response body is streamed from slow external sources. // * if response body must be streamed to the client in chunks. // (aka `http server push`). @@ -709,7 +709,7 @@ type Context interface { // is being called afterwards, in the same request. // Useful when need to set or/and change a layout based on the previous handlers in the chain. // - // Note that the 'layoutTmplFile' argument can be setted to iris.NoLayout || view.NoLayout + // Note that the 'layoutTmplFile' argument can be set to iris.NoLayout || view.NoLayout // to disable the layout for a specific view render action, // it disables the engine's configuration's layout property. // @@ -1762,7 +1762,7 @@ func (ctx *context) ContentType(cType string) { } // GetContentType returns the response writer's header value of "Content-Type" -// which may, setted before with the 'ContentType'. +// which may, set before with the 'ContentType'. func (ctx *context) GetContentType() string { return ctx.writer.Header().Get(ContentTypeHeaderKey) } @@ -2597,7 +2597,7 @@ func (ctx *context) WriteWithExpiration(body []byte, modtime time.Time) (int, er // // This function may be used in the following cases: // -// * if response body is too big (more than iris.LimitRequestBodySize(if setted)). +// * if response body is too big (more than iris.LimitRequestBodySize(if set)). // * if response body is streamed from slow external sources. // * if response body must be streamed to the client in chunks. // (aka `http server push`). @@ -2714,7 +2714,7 @@ const ( // is being called afterwards, in the same request. // Useful when need to set or/and change a layout based on the previous handlers in the chain. // -// Note that the 'layoutTmplFile' argument can be setted to iris.NoLayout || view.NoLayout || context.NoLayout +// Note that the 'layoutTmplFile' argument can be set to iris.NoLayout || view.NoLayout || context.NoLayout // to disable the layout for a specific view render action, // it disables the engine's configuration's layout property. // diff --git a/context/gzip_response_writer.go b/context/gzip_response_writer.go index a4379d9d..6213e915 100644 --- a/context/gzip_response_writer.go +++ b/context/gzip_response_writer.go @@ -18,7 +18,7 @@ type compressionPool struct { // |GZIP raw io.writer, our gzip response writer will use that. | // +------------------------------------------------------------+ -// default writer pool with Compressor's level setted to -1 +// default writer pool with Compressor's level set to -1 var gzipPool = &compressionPool{Level: -1} // acquireGzipWriter prepares a gzip writer and returns it. diff --git a/context/response_writer.go b/context/response_writer.go index 9cd05f20..27d5dd85 100644 --- a/context/response_writer.go +++ b/context/response_writer.go @@ -70,7 +70,7 @@ type ResponseWriter interface { // SetBeforeFlush registers the unique callback which called exactly before the response is flushed to the client. SetBeforeFlush(cb func()) - // GetBeforeFlush returns (not execute) the before flush callback, or nil if not setted by SetBeforeFlush. + // GetBeforeFlush returns (not execute) the before flush callback, or nil if not set by SetBeforeFlush. GetBeforeFlush() func() // FlushResponse should be called only once before EndResponse. // it tries to send the status code if not sent already diff --git a/context/transaction.go b/context/transaction.go index fb0916b7..f6b2dfb3 100644 --- a/context/transaction.go +++ b/context/transaction.go @@ -155,7 +155,7 @@ var RequestTransactionScope = TransactionScopeFunc(func(maybeErr TransactionErrR // we need to register a beforeResponseFlush event here in order // to execute last the FireStatusCode - // (which will reset the whole response's body, status code and headers setted from normal flow or other transactions too) + // (which will reset the whole response's body, status code and headers set from normal flow or other transactions too) ctx.ResponseWriter().SetBeforeFlush(func() { // we need to re-take the context's response writer // because inside here the response writer is changed to the original's diff --git a/core/memstore/memstore.go b/core/memstore/memstore.go index af933c07..30a701d0 100644 --- a/core/memstore/memstore.go +++ b/core/memstore/memstore.go @@ -582,7 +582,7 @@ func (e Entry) BoolDefault(def bool) (bool, error) { // respects the immutable. func (e Entry) Value() interface{} { if e.immutable { - // take its value, no pointer even if setted with a reference. + // take its value, no pointer even if set with a reference. vv := reflect.Indirect(reflect.ValueOf(e.ValueRaw)) // return copy of that slice diff --git a/core/netutil/addr.go b/core/netutil/addr.go index 131da3d4..2844dee1 100644 --- a/core/netutil/addr.go +++ b/core/netutil/addr.go @@ -127,7 +127,7 @@ func ResolveAddr(addr string) string { if a[portIdx:] == ":https" { a = defaultServerHostname + ":443" } else { - // if contains only :port ,then the : is the first letter, so we dont have setted a hostname, lets set it + // if contains only :port ,then the : is the first letter, so we dont have set a hostname, lets set it a = defaultServerHostname + a } } diff --git a/core/router/status.go b/core/router/status.go index fc41fe81..d0b391c9 100644 --- a/core/router/status.go +++ b/core/router/status.go @@ -26,7 +26,7 @@ func (ch *ErrorCodeHandler) Fire(ctx context.Context) { // if we can reset the body if w, ok := ctx.IsRecording(); ok { if statusCodeSuccessful(w.StatusCode()) { // if not an error status code - w.WriteHeader(ch.StatusCode) // then set it manually here, otherwise it should be setted via ctx.StatusCode(...) + w.WriteHeader(ch.StatusCode) // then set it manually here, otherwise it should be set via ctx.StatusCode(...) } // reset if previous content and it's recorder, keep the status code. w.ClearHeaders() diff --git a/httptest/httptest.go b/httptest/httptest.go index 2d349521..a34a2469 100644 --- a/httptest/httptest.go +++ b/httptest/httptest.go @@ -48,7 +48,7 @@ func (c Configuration) Set(main *Configuration) { } var ( - // URL if setted then it sets the httptest's BaseURL. + // URL if set then it sets the httptest's BaseURL. // Defaults to empty string "". URL = func(schemeAndHost string) OptionSet { return func(c *Configuration) { diff --git a/macro/interpreter/parser/parser.go b/macro/interpreter/parser/parser.go index 1a0b8608..d4dcb0ec 100644 --- a/macro/interpreter/parser/parser.go +++ b/macro/interpreter/parser/parser.go @@ -78,7 +78,7 @@ func (p *ParamParser) appendErr(format string, a ...interface{}) { const ( // DefaultParamErrorCode is the default http error code, 404 not found, - // per-parameter. An error code can be setted via + // per-parameter. An error code can be set via // the "else" keyword inside a route's path. DefaultParamErrorCode = 404 ) diff --git a/middleware/i18n/i18n.go b/middleware/i18n/i18n.go index 923398ea..9f3175cf 100644 --- a/middleware/i18n/i18n.go +++ b/middleware/i18n/i18n.go @@ -102,7 +102,7 @@ func New(c Config) context.Handler { } } } - // if not default language setted then set to the first of the i.config.Languages + // if not default language set then set to the first of the i.config.Languages if c.Default == "" { c.Default = firstlanguage } diff --git a/middleware/logger/config.go b/middleware/logger/config.go index 3bb8974f..bf72e801 100644 --- a/middleware/logger/config.go +++ b/middleware/logger/config.go @@ -48,7 +48,7 @@ type Config struct { // the contents with `ctx.Values().Get(MessageContextKey)` // and if available then these contents will be // appended as part of the logs (with `%v`, in order to be able to set a struct too), - // if Columns field was setted to true then + // if Columns field was set to true then // a new column will be added named 'Message'. // // Defaults to empty. @@ -59,7 +59,7 @@ type Config struct { // the contents with `ctx.Values().Get(MessageHeaderKey)` // and if available then these contents will be // appended as part of the logs (with `%v`, in order to be able to set a struct too), - // if Columns field was setted to true then + // if Columns field was set to true then // a new column will be added named 'HeaderMessage'. // // Defaults to empty. diff --git a/sessions/config.go b/sessions/config.go index f7c15570..19760f58 100644 --- a/sessions/config.go +++ b/sessions/config.go @@ -19,7 +19,7 @@ type Encoding interface { // Encode the cookie value if not nil. // Should accept as first argument the cookie name (config.Name) // as second argument the server's generated session id. - // Should return the new session id, if error the session id setted to empty which is invalid. + // Should return the new session id, if error the session id set to empty which is invalid. // // Note: Errors are not printed, so you have to know what you're doing, // and remember: if you use AES it only supports key sizes of 16, 24 or 32 bytes. @@ -49,10 +49,10 @@ type ( Cookie string // CookieSecureTLS set to true if server is running over TLS - // and you need the session's cookie "Secure" field to be setted true. + // and you need the session's cookie "Secure" field to be set true. // - // Note: The user should fill the Decode configuration field in order for this to work. - // Recommendation: You don't need this to be setted to true, just fill the Encode and Decode fields + // Note: The user should fill the Decode configuation field in order for this to work. + // Recommendation: You don't need this to be set to true, just fill the Encode and Decode fields // with a third-party library like secure cookie, example is provided at the _examples folder. // // Defaults to false. @@ -69,7 +69,7 @@ type ( // Encode the cookie value if not nil. // Should accept as first argument the cookie name (config.Cookie) // as second argument the server's generated session id. - // Should return the new session id, if error the session id setted to empty which is invalid. + // Should return the new session id, if error the session id set to empty which is invalid. // // Note: Errors are not printed, so you have to know what you're doing, // and remember: if you use AES it only supports key sizes of 16, 24 or 32 bytes. diff --git a/sessions/sessiondb/redis/service/service.go b/sessions/sessiondb/redis/service/service.go new file mode 100644 index 00000000..9931f82d --- /dev/null +++ b/sessions/sessiondb/redis/service/service.go @@ -0,0 +1,331 @@ +package service + +import ( + "fmt" + "time" + + "github.com/gomodule/redigo/redis" + "github.com/kataras/iris/core/errors" +) + +var ( + // ErrRedisClosed an error with message 'Redis is already closed' + ErrRedisClosed = errors.New("Redis is already closed") + // ErrKeyNotFound an error with message 'Key $thekey doesn't found' + ErrKeyNotFound = errors.New("Key '%s' doesn't found") +) + +// Service the Redis service, contains the config and the redis pool +type Service struct { + // Connected is true when the Service has already connected + Connected bool + // Config the redis config for this redis + Config *Config + pool *redis.Pool +} + +// PingPong sends a ping and receives a pong, if no pong received then returns false and filled error +func (r *Service) PingPong() (bool, error) { + c := r.pool.Get() + defer c.Close() + msg, err := c.Do("PING") + if err != nil || msg == nil { + return false, err + } + return (msg == "PONG"), nil +} + +// CloseConnection closes the redis connection +func (r *Service) CloseConnection() error { + if r.pool != nil { + return r.pool.Close() + } + return ErrRedisClosed +} + +// Set sets a key-value to the redis store. +// The expiration is set by the MaxAgeSeconds. +func (r *Service) Set(key string, value interface{}, secondsLifetime int64) (err error) { + c := r.pool.Get() + defer c.Close() + if c.Err() != nil { + return c.Err() + } + + // if has expiration, then use the "EX" to delete the key automatically. + if secondsLifetime > 0 { + _, err = c.Do("SETEX", r.Config.Prefix+key, secondsLifetime, value) + } else { + _, err = c.Do("SET", r.Config.Prefix+key, value) + } + + return +} + +// Get returns value, err by its key +//returns nil and a filled error if something bad happened. +func (r *Service) Get(key string) (interface{}, error) { + c := r.pool.Get() + defer c.Close() + if err := c.Err(); err != nil { + return nil, err + } + + redisVal, err := c.Do("GET", r.Config.Prefix+key) + + if err != nil { + return nil, err + } + if redisVal == nil { + return nil, ErrKeyNotFound.Format(key) + } + return redisVal, nil +} + +// TTL returns the seconds to expire, if the key has expiration and error if action failed. +// Read more at: https://redis.io/commands/ttl +func (r *Service) TTL(key string) (seconds int64, hasExpiration bool, found bool) { + c := r.pool.Get() + defer c.Close() + redisVal, err := c.Do("TTL", r.Config.Prefix+key) + if err != nil { + return -2, false, false + } + seconds = redisVal.(int64) + // if -1 means the key has unlimited life time. + hasExpiration = seconds > -1 + // if -2 means key does not exist. + found = !(c.Err() != nil || seconds == -2) + return +} + +func (r *Service) updateTTLConn(c redis.Conn, key string, newSecondsLifeTime int64) error { + reply, err := c.Do("EXPIRE", r.Config.Prefix+key, newSecondsLifeTime) + + if err != nil { + return err + } + + // https://redis.io/commands/expire#return-value + // + // 1 if the timeout was set. + // 0 if key does not exist. + if hadTTLOrExists, ok := reply.(int); ok { + if hadTTLOrExists == 1 { + return nil + } else if hadTTLOrExists == 0 { + return fmt.Errorf("unable to update expiration, the key '%s' was stored without ttl", key) + } // do not check for -1. + } + + return nil +} + +// UpdateTTL will update the ttl of a key. +// Using the "EXPIRE" command. +// Read more at: https://redis.io/commands/expire#refreshing-expires +func (r *Service) UpdateTTL(key string, newSecondsLifeTime int64) error { + c := r.pool.Get() + defer c.Close() + err := c.Err() + if err != nil { + return err + } + + return r.updateTTLConn(c, key, newSecondsLifeTime) +} + +// UpdateTTLMany like `UpdateTTL` but for all keys starting with that "prefix", +// it is a bit faster operation if you need to update all sessions keys (although it can be even faster if we used hash but this will limit other features), +// look the `sessions/Database#OnUpdateExpiration` for example. +func (r *Service) UpdateTTLMany(prefix string, newSecondsLifeTime int64) error { + c := r.pool.Get() + defer c.Close() + if err := c.Err(); err != nil { + return err + } + + keys, err := r.getKeysConn(c, prefix) + if err != nil { + return err + } + + for _, key := range keys { + if err = r.updateTTLConn(c, key, newSecondsLifeTime); err != nil { // fail on first error. + return err + } + } + + return err +} + +// GetAll returns all redis entries using the "SCAN" command (2.8+). +func (r *Service) GetAll() (interface{}, error) { + c := r.pool.Get() + defer c.Close() + if err := c.Err(); err != nil { + return nil, err + } + + redisVal, err := c.Do("SCAN", 0) // 0 -> cursor + + if err != nil { + return nil, err + } + + if redisVal == nil { + return nil, err + } + + return redisVal, nil +} + +func (r *Service) getKeysConn(c redis.Conn, prefix string) ([]string, error) { + if err := c.Send("SCAN", 0, "MATCH", r.Config.Prefix+prefix+"*", "COUNT", 9999999999); err != nil { + return nil, err + } + + if err := c.Flush(); err != nil { + return nil, err + } + + reply, err := c.Receive() + if err != nil || reply == nil { + return nil, err + } + + // it returns []interface, with two entries, the first one is "0" and the second one is a slice of the keys as []interface{uint8....}. + + if keysInterface, ok := reply.([]interface{}); ok { + if len(keysInterface) == 2 { + // take the second, it must contain the slice of keys. + if keysSliceAsBytes, ok := keysInterface[1].([]interface{}); ok { + keys := make([]string, len(keysSliceAsBytes), len(keysSliceAsBytes)) + for i, k := range keysSliceAsBytes { + keys[i] = fmt.Sprintf("%s", k)[len(r.Config.Prefix):] + } + + return keys, nil + } + } + } + + return nil, nil +} + +// GetKeys returns all redis keys using the "SCAN" with MATCH command. +// Read more at: https://redis.io/commands/scan#the-match-option. +func (r *Service) GetKeys(prefix string) ([]string, error) { + c := r.pool.Get() + defer c.Close() + if err := c.Err(); err != nil { + return nil, err + } + + return r.getKeysConn(c, prefix) +} + +// GetBytes returns value, err by its key +// you can use utils.Deserialize((.GetBytes("yourkey"),&theobject{}) +//returns nil and a filled error if something wrong happens +func (r *Service) GetBytes(key string) ([]byte, error) { + c := r.pool.Get() + defer c.Close() + if err := c.Err(); err != nil { + return nil, err + } + + redisVal, err := c.Do("GET", r.Config.Prefix+key) + + if err != nil { + return nil, err + } + if redisVal == nil { + return nil, ErrKeyNotFound.Format(key) + } + + return redis.Bytes(redisVal, err) +} + +// Delete removes redis entry by specific key +func (r *Service) Delete(key string) error { + c := r.pool.Get() + defer c.Close() + + _, err := c.Do("DEL", r.Config.Prefix+key) + return err +} + +func dial(network string, addr string, pass string) (redis.Conn, error) { + if network == "" { + network = DefaultRedisNetwork + } + if addr == "" { + addr = DefaultRedisAddr + } + c, err := redis.Dial(network, addr) + 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 +func (r *Service) Connect() { + c := r.Config + + if c.IdleTimeout <= 0 { + c.IdleTimeout = DefaultRedisIdleTimeout + } + + if c.Network == "" { + c.Network = DefaultRedisNetwork + } + + if c.Addr == "" { + c.Addr = DefaultRedisAddr + } + + pool := &redis.Pool{IdleTimeout: c.IdleTimeout, MaxIdle: c.MaxIdle, 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) + 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) + } + } + r.Connected = true + r.pool = pool +} + +// New returns a Redis service filled by the passed config +// to connect call the .Connect(). +func New(cfg ...Config) *Service { + c := DefaultConfig() + if len(cfg) > 0 { + c = cfg[0] + } + r := &Service{pool: &redis.Pool{}, Config: &c} + return r +} diff --git a/sessions/sessions_test.go b/sessions/sessions_test.go index c0d52546..5041a809 100644 --- a/sessions/sessions_test.go +++ b/sessions/sessions_test.go @@ -91,7 +91,7 @@ func testSessions(t *testing.T, sess *sessions.Sessions, app *iris.Application) d := e.GET("/destroy").Expect().Status(iris.StatusOK) d.JSON().Object().Empty() // This removed: d.Cookies().Empty(). Reason: - // httpexpect counts the cookies setted or deleted at the response time, but cookie is not removed, to be really removed needs to SetExpire(now-1second) so, + // httpexpect counts the cookies set or deleted at the response time, but cookie is not removed, to be really removed needs to SetExpire(now-1second) so, // test if the cookies removed on the next request, like the browser's behavior. e.GET("/after_destroy").Expect().Status(iris.StatusOK).Cookies().Empty() // set and clear again diff --git a/typescript/config.go b/typescript/config.go index 44efe2a6..187972b4 100644 --- a/typescript/config.go +++ b/typescript/config.go @@ -78,7 +78,7 @@ type ( // 2. Dir: string, Dir set the root, where to search for typescript files/project. Default "./" // 3. Ignore: string, comma separated ignore typescript files/project from these directories. Default "" (node_modules are always ignored) // 4. Tsconfig: &typescript.Tsconfig{}, here you can set all compilerOptions if no tsconfig.json exists inside the 'Dir' - // 5. Editor: typescript.Editor("username","password"), if setted then alm-tools browser-based typescript IDE will be available. Defailt is nil + // 5. Editor: typescript.Editor("username","password"), if set then alm-tools browser-based typescript IDE will be available. Defailt is nil Config struct { // Bin the path of the tsc binary file // if empty then the plugin tries to find it diff --git a/view/README.md b/view/README.md index b5a5318b..5c9dd715 100644 --- a/view/README.md +++ b/view/README.md @@ -128,7 +128,7 @@ func hi(ctx iris.Context) { View engine supports bundled(https://github.com/shuLhan/go-bindata) template files too. `go-bindata` gives you two functions, `Assset` and `AssetNames`, -these can be setted to each of the template engines using the `.Binary` function. +these can be set to each of the template engines using the `.Binary` function. Example code: diff --git a/view/amber.go b/view/amber.go index 2888848a..9e040dc5 100644 --- a/view/amber.go +++ b/view/amber.go @@ -53,7 +53,7 @@ func (s *AmberEngine) Binary(assetFn func(name string) ([]byte, error), namesFn return s } -// Reload if setted to true the templates are reloading on each render, +// Reload if set to true the templates are reloading on each render, // use it when you're in development and you're boring of restarting // the whole app when you edit a template file. // @@ -91,7 +91,7 @@ func (s *AmberEngine) Load() error { if err != nil { return err } - // change the directory field configuration, load happens after directory has been setted, so we will not have any problems here. + // change the directory field configuration, load happens after directory has been set, so we will not have any problems here. s.directory = dir return s.loadDirectory() } diff --git a/view/django.go b/view/django.go index 0c62f93c..0455e4d7 100644 --- a/view/django.go +++ b/view/django.go @@ -135,7 +135,7 @@ func (s *DjangoEngine) Binary(assetFn func(name string) ([]byte, error), namesFn return s } -// Reload if setted to true the templates are reloading on each render, +// Reload if set to true the templates are reloading on each render, // use it when you're in development and you're boring of restarting // the whole app when you edit a template file. // @@ -210,7 +210,7 @@ func (s *DjangoEngine) Load() error { if err != nil { return err } - // change the directory field configuration, load happens after directory has been setted, so we will not have any problems here. + // change the directory field configuration, load happens after directory has been set, so we will not have any problems here. s.directory = dir return s.loadDirectory() } diff --git a/view/handlebars.go b/view/handlebars.go index 4736ae3d..14f15c18 100644 --- a/view/handlebars.go +++ b/view/handlebars.go @@ -64,7 +64,7 @@ func (s *HandlebarsEngine) Binary(assetFn func(name string) ([]byte, error), nam return s } -// Reload if setted to true the templates are reloading on each render, +// Reload if set to true the templates are reloading on each render, // use it when you're in development and you're boring of restarting // the whole app when you edit a template file. // @@ -111,7 +111,7 @@ func (s *HandlebarsEngine) Load() error { if err != nil { return err } - // change the directory field configuration, load happens after directory has been setted, so we will not have any problems here. + // change the directory field configuration, load happens after directory has been set, so we will not have any problems here. s.directory = dir return s.loadDirectory() } diff --git a/view/html.go b/view/html.go index 61d21af3..af01217c 100644 --- a/view/html.go +++ b/view/html.go @@ -92,7 +92,7 @@ func (s *HTMLEngine) Binary(assetFn func(name string) ([]byte, error), namesFn f return s } -// Reload if setted to true the templates are reloading on each render, +// Reload if set to true the templates are reloading on each render, // use it when you're in development and you're boring of restarting // the whole app when you edit a template file. // @@ -226,7 +226,7 @@ func (s *HTMLEngine) Load() error { if err != nil { return err } - // change the directory field configuration, load happens after directory has been setted, so we will not have any problems here. + // change the directory field configuration, load happens after directory has been set, so we will not have any problems here. s.directory = dir return s.loadDirectory() }