mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 10:41:03 +01:00
Minor Context changes
Former-commit-id: ff0a759895b322da8d42decd7374f58d3e02498c
This commit is contained in:
parent
221f026491
commit
3657aaf240
|
@ -372,7 +372,7 @@ Other Improvements:
|
||||||
![DBUG routes](https://iris-go.com/images/v12.2.0-dbug2.png?v=0)
|
![DBUG routes](https://iris-go.com/images/v12.2.0-dbug2.png?v=0)
|
||||||
|
|
||||||
- Enhanced cookie security and management through new `Context.AddCookieOptions` method and new cookie options (look on New Package-level functions section below), [securecookie](https://github.com/kataras/iris/tree/master/_examples/cookies/securecookie) example has been updated.
|
- Enhanced cookie security and management through new `Context.AddCookieOptions` method and new cookie options (look on New Package-level functions section below), [securecookie](https://github.com/kataras/iris/tree/master/_examples/cookies/securecookie) example has been updated.
|
||||||
- `Context.RemoveCookie` removes also the Request's cookies of the same request lifecycle when `iris.CookieAllowReclaim` is set to cookie options, [example](https://github.com/kataras/iris/tree/master/_examples/cookies/options).
|
- `Context.RemoveCookie` removes also the Request's specific cookie of the same request lifecycle when `iris.CookieAllowReclaim` is set to cookie options, [example](https://github.com/kataras/iris/tree/master/_examples/cookies/options).
|
||||||
|
|
||||||
- `iris.TLS` can now accept certificates as raw contents too.
|
- `iris.TLS` can now accept certificates as raw contents too.
|
||||||
- `iris.TLS` registers a secondary http server which redirects "http://" to their "https://" equivalent requests, unless the new `iris.TLSNoRedirect` host Configurator is provided on `iris.TLS` (or `iris.AutoTLS`), e.g. `app.Run(iris.TLS("127.0.0.1:443", "mycert.cert", "mykey.key", iris.TLSNoRedirect))`.
|
- `iris.TLS` registers a secondary http server which redirects "http://" to their "https://" equivalent requests, unless the new `iris.TLSNoRedirect` host Configurator is provided on `iris.TLS` (or `iris.AutoTLS`), e.g. `app.Run(iris.TLS("127.0.0.1:443", "mycert.cert", "mykey.key", iris.TLSNoRedirect))`.
|
||||||
|
@ -407,6 +407,7 @@ New Package-level Variables:
|
||||||
|
|
||||||
New Context Methods:
|
New Context Methods:
|
||||||
|
|
||||||
|
- `Context.SetID(id interface{})` and `Context.GetID() interface{}` added to register a custom unique indetifier to the Context, if necessary.
|
||||||
- `Context.GetDomain() string` returns the domain.
|
- `Context.GetDomain() string` returns the domain.
|
||||||
- `Context.AddCookieOptions(...CookieOption)` adds options for `SetCookie`, `SetCookieKV, UpsertCookie` and `RemoveCookie` methods for the current request.
|
- `Context.AddCookieOptions(...CookieOption)` adds options for `SetCookie`, `SetCookieKV, UpsertCookie` and `RemoveCookie` methods for the current request.
|
||||||
- `Context.ClearCookieOptions()` clears any cookie options registered through `AddCookieOptions`.
|
- `Context.ClearCookieOptions()` clears any cookie options registered through `AddCookieOptions`.
|
||||||
|
@ -432,6 +433,7 @@ New Context Methods:
|
||||||
|
|
||||||
Breaking Changes:
|
Breaking Changes:
|
||||||
|
|
||||||
|
- `Context.String()` (rarely used by end-developers) it does not return a unique string anymore, to achieve the old representation you must call the new `Context.SetID` method first.
|
||||||
- `iris.CookieEncode` and `CookieDecode` are replaced with the `iris.CookieEncoding`.
|
- `iris.CookieEncode` and `CookieDecode` are replaced with the `iris.CookieEncoding`.
|
||||||
- `sessions#Config.Encode` and `Decode` are removed in favor of (the existing) `Encoding` field.
|
- `sessions#Config.Encode` and `Decode` are removed in favor of (the existing) `Encoding` field.
|
||||||
- `versioning.GetVersion` now returns an empty string if version wasn't found.
|
- `versioning.GetVersion` now returns an empty string if version wasn't found.
|
||||||
|
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
@ -1136,13 +1135,19 @@ type Context interface {
|
||||||
// and methods are not available here for the developer's safety.
|
// and methods are not available here for the developer's safety.
|
||||||
Application() Application
|
Application() Application
|
||||||
|
|
||||||
// String returns the string representation of this request.
|
// SetID sets an ID, any value, to the Context.
|
||||||
// Each context has a unique string representation.
|
// If possible the "id" should implement a `String() string` method
|
||||||
// It can be used for simple debugging scenarios, i.e print context as string.
|
// so it can be rendered on `Context.String` method.
|
||||||
//
|
//
|
||||||
// What it returns? A number which declares the length of the
|
// See `GetID` too.
|
||||||
// total `String` calls per executable application, followed
|
SetID(id interface{})
|
||||||
// by the remote IP (the client) and finally the method:url.
|
// GetID returns the Context's ID.
|
||||||
|
// It returns nil if not given by a prior `SetID` call.
|
||||||
|
GetID() interface{}
|
||||||
|
// String returns the string representation of this request.
|
||||||
|
//
|
||||||
|
// It returns the Context's ID given by a `SetID`call,
|
||||||
|
// followed by the client's IP and the method:uri.
|
||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1185,10 +1190,6 @@ type Map = map[string]interface{}
|
||||||
// +------------------------------------------------------------+
|
// +------------------------------------------------------------+
|
||||||
|
|
||||||
type context struct {
|
type context struct {
|
||||||
// the unique id, it's zero until `String` function is called,
|
|
||||||
// it's here to cache the random, unique context's id, although `String`
|
|
||||||
// returns more than this.
|
|
||||||
id uint64
|
|
||||||
// the http.ResponseWriter wrapped by custom writer.
|
// the http.ResponseWriter wrapped by custom writer.
|
||||||
writer ResponseWriter
|
writer ResponseWriter
|
||||||
// the original http.Request
|
// the original http.Request
|
||||||
|
@ -2024,7 +2025,7 @@ func (ctx *context) GetReferrer() Referrer {
|
||||||
//
|
//
|
||||||
// See `i18n.ExtractFunc` for a more organised way of the same feature.
|
// See `i18n.ExtractFunc` for a more organised way of the same feature.
|
||||||
func (ctx *context) SetLanguage(langCode string) {
|
func (ctx *context) SetLanguage(langCode string) {
|
||||||
ctx.Values().Set(ctx.app.ConfigurationReadOnly().GetLanguageContextKey(), langCode)
|
ctx.values.Set(ctx.app.ConfigurationReadOnly().GetLanguageContextKey(), langCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLocale returns the current request's `Locale` found by i18n middleware.
|
// GetLocale returns the current request's `Locale` found by i18n middleware.
|
||||||
|
@ -2032,14 +2033,14 @@ func (ctx *context) SetLanguage(langCode string) {
|
||||||
func (ctx *context) GetLocale() Locale {
|
func (ctx *context) GetLocale() Locale {
|
||||||
// Cache the Locale itself for multiple calls of `Tr` method.
|
// Cache the Locale itself for multiple calls of `Tr` method.
|
||||||
contextKey := ctx.app.ConfigurationReadOnly().GetLocaleContextKey()
|
contextKey := ctx.app.ConfigurationReadOnly().GetLocaleContextKey()
|
||||||
if v := ctx.Values().Get(contextKey); v != nil {
|
if v := ctx.values.Get(contextKey); v != nil {
|
||||||
if locale, ok := v.(Locale); ok {
|
if locale, ok := v.(Locale); ok {
|
||||||
return locale
|
return locale
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if locale := ctx.Application().I18nReadOnly().GetLocale(ctx); locale != nil {
|
if locale := ctx.Application().I18nReadOnly().GetLocale(ctx); locale != nil {
|
||||||
ctx.Values().Set(contextKey, locale)
|
ctx.values.Set(contextKey, locale)
|
||||||
return locale
|
return locale
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2061,7 +2062,7 @@ func (ctx *context) Tr(format string, args ...interface{}) string { // other nam
|
||||||
// SetVersion force-sets the API Version integrated with the "iris/versioning" subpackage.
|
// SetVersion force-sets the API Version integrated with the "iris/versioning" subpackage.
|
||||||
// It can be used inside a middleare.
|
// It can be used inside a middleare.
|
||||||
func (ctx *context) SetVersion(constraint string) {
|
func (ctx *context) SetVersion(constraint string) {
|
||||||
ctx.Values().Set(ctx.Application().ConfigurationReadOnly().GetVersionContextKey(), constraint)
|
ctx.values.Set(ctx.Application().ConfigurationReadOnly().GetVersionContextKey(), constraint)
|
||||||
}
|
}
|
||||||
|
|
||||||
// +------------------------------------------------------------+
|
// +------------------------------------------------------------+
|
||||||
|
@ -2093,7 +2094,7 @@ func (ctx *context) contentTypeOnce(cType string, charset string) {
|
||||||
cType += "; charset=" + charset
|
cType += "; charset=" + charset
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Values().Set(contentTypeContextKey, cType)
|
ctx.values.Set(contentTypeContextKey, cType)
|
||||||
ctx.writer.Header().Set(ContentTypeHeaderKey, cType)
|
ctx.writer.Header().Set(ContentTypeHeaderKey, cType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2103,7 +2104,7 @@ func (ctx *context) ContentType(cType string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, wroteOnce := ctx.Values().GetEntry(contentTypeContextKey); wroteOnce {
|
if _, wroteOnce := ctx.values.GetEntry(contentTypeContextKey); wroteOnce {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3355,7 +3356,7 @@ func (ctx *context) ViewData(key string, value interface{}) {
|
||||||
// `viewData := ctx.Values().Get(ctx.Application().ConfigurationReadOnly().GetViewDataContextKey())`.
|
// `viewData := ctx.Values().Get(ctx.Application().ConfigurationReadOnly().GetViewDataContextKey())`.
|
||||||
func (ctx *context) GetViewData() map[string]interface{} {
|
func (ctx *context) GetViewData() map[string]interface{} {
|
||||||
viewDataContextKey := ctx.Application().ConfigurationReadOnly().GetViewDataContextKey()
|
viewDataContextKey := ctx.Application().ConfigurationReadOnly().GetViewDataContextKey()
|
||||||
v := ctx.Values().Get(viewDataContextKey)
|
v := ctx.values.Get(viewDataContextKey)
|
||||||
|
|
||||||
// if no values found, then return nil
|
// if no values found, then return nil
|
||||||
if v == nil {
|
if v == nil {
|
||||||
|
@ -4021,7 +4022,7 @@ const negotiationContextKey = "iris.negotiation_builder"
|
||||||
//
|
//
|
||||||
// See `Negotiate` method too.
|
// See `Negotiate` method too.
|
||||||
func (ctx *context) Negotiation() *NegotiationBuilder {
|
func (ctx *context) Negotiation() *NegotiationBuilder {
|
||||||
if n := ctx.Values().Get(negotiationContextKey); n != nil {
|
if n := ctx.values.Get(negotiationContextKey); n != nil {
|
||||||
return n.(*NegotiationBuilder)
|
return n.(*NegotiationBuilder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4031,7 +4032,7 @@ func (ctx *context) Negotiation() *NegotiationBuilder {
|
||||||
|
|
||||||
n := &NegotiationBuilder{Accept: acceptBuilder}
|
n := &NegotiationBuilder{Accept: acceptBuilder}
|
||||||
|
|
||||||
ctx.Values().Set(negotiationContextKey, n)
|
ctx.values.Set(negotiationContextKey, n)
|
||||||
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
@ -5029,17 +5030,17 @@ func (ctx *context) AddCookieOptions(options ...CookieOption) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if v := ctx.Values().Get(cookieOptionsContextKey); v != nil {
|
if v := ctx.values.Get(cookieOptionsContextKey); v != nil {
|
||||||
if opts, ok := v.([]CookieOption); ok {
|
if opts, ok := v.([]CookieOption); ok {
|
||||||
options = append(opts, options...)
|
options = append(opts, options...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Values().Set(cookieOptionsContextKey, options)
|
ctx.values.Set(cookieOptionsContextKey, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *context) applyCookieOptions(c *http.Cookie, op uint8, override []CookieOption) {
|
func (ctx *context) applyCookieOptions(c *http.Cookie, op uint8, override []CookieOption) {
|
||||||
if v := ctx.Values().Get(cookieOptionsContextKey); v != nil {
|
if v := ctx.values.Get(cookieOptionsContextKey); v != nil {
|
||||||
if options, ok := v.([]CookieOption); ok {
|
if options, ok := v.([]CookieOption); ok {
|
||||||
for _, opt := range options {
|
for _, opt := range options {
|
||||||
opt(ctx, c, op)
|
opt(ctx, c, op)
|
||||||
|
@ -5057,7 +5058,7 @@ func (ctx *context) applyCookieOptions(c *http.Cookie, op uint8, override []Cook
|
||||||
// ClearCookieOptions clears any previously registered cookie options.
|
// ClearCookieOptions clears any previously registered cookie options.
|
||||||
// See `AddCookieOptions` too.
|
// See `AddCookieOptions` too.
|
||||||
func (ctx *context) ClearCookieOptions() {
|
func (ctx *context) ClearCookieOptions() {
|
||||||
ctx.Values().Remove(cookieOptionsContextKey)
|
ctx.values.Remove(cookieOptionsContextKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCookie adds a cookie.
|
// SetCookie adds a cookie.
|
||||||
|
@ -5298,7 +5299,7 @@ func (ctx *context) BeginTransaction(pipe func(t *Transaction)) {
|
||||||
|
|
||||||
// skipTransactionsContextKey set this to any value to stop executing next transactions
|
// skipTransactionsContextKey set this to any value to stop executing next transactions
|
||||||
// it's a context-key in order to be used from anywhere, set it by calling the SkipTransactions()
|
// it's a context-key in order to be used from anywhere, set it by calling the SkipTransactions()
|
||||||
const skipTransactionsContextKey = "@transictions_skipped"
|
const skipTransactionsContextKey = "iris.transactions.skip"
|
||||||
|
|
||||||
// SkipTransactions if called then skip the rest of the transactions
|
// SkipTransactions if called then skip the rest of the transactions
|
||||||
// or all of them if called before the first transaction
|
// or all of them if called before the first transaction
|
||||||
|
@ -5395,12 +5396,12 @@ const (
|
||||||
// ReflectValue caches and returns a []reflect.Value{reflect.ValueOf(ctx)}.
|
// ReflectValue caches and returns a []reflect.Value{reflect.ValueOf(ctx)}.
|
||||||
// It's just a helper to maintain variable inside the context itself.
|
// It's just a helper to maintain variable inside the context itself.
|
||||||
func (ctx *context) ReflectValue() []reflect.Value {
|
func (ctx *context) ReflectValue() []reflect.Value {
|
||||||
if v := ctx.Values().Get(reflectValueContextKey); v != nil {
|
if v := ctx.values.Get(reflectValueContextKey); v != nil {
|
||||||
return v.([]reflect.Value)
|
return v.([]reflect.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
v := []reflect.Value{reflect.ValueOf(ctx)}
|
v := []reflect.Value{reflect.ValueOf(ctx)}
|
||||||
ctx.Values().Set(reflectValueContextKey, v)
|
ctx.values.Set(reflectValueContextKey, v)
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5409,7 +5410,7 @@ var emptyValue reflect.Value
|
||||||
// Controller returns a reflect Value of the custom Controller from which this handler executed.
|
// Controller returns a reflect Value of the custom Controller from which this handler executed.
|
||||||
// It will return a Kind() == reflect.Invalid if the handler was not executed from within a controller.
|
// It will return a Kind() == reflect.Invalid if the handler was not executed from within a controller.
|
||||||
func (ctx *context) Controller() reflect.Value {
|
func (ctx *context) Controller() reflect.Value {
|
||||||
if v := ctx.Values().Get(ControllerContextKey); v != nil {
|
if v := ctx.values.Get(ControllerContextKey); v != nil {
|
||||||
return v.(reflect.Value)
|
return v.(reflect.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5425,27 +5426,27 @@ func (ctx *context) Application() Application {
|
||||||
return ctx.app
|
return ctx.app
|
||||||
}
|
}
|
||||||
|
|
||||||
var lastCapturedContextID uint64
|
const idContextKey = "iris.context.id"
|
||||||
|
|
||||||
// LastCapturedContextID returns the total number of `context#String` calls.
|
// SetID sets an ID, any value, to the Context.
|
||||||
func LastCapturedContextID() uint64 {
|
// If possible the "id" should implement a `String() string` method
|
||||||
return atomic.LoadUint64(&lastCapturedContextID)
|
// so it can be rendered on `Context.String` method.
|
||||||
|
//
|
||||||
|
// See `GetID` too.
|
||||||
|
func (ctx *context) SetID(id interface{}) {
|
||||||
|
ctx.values.Set(idContextKey, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetID returns the Context's ID.
|
||||||
|
// It returns nil if not given by a prior `SetID` call.
|
||||||
|
func (ctx *context) GetID() interface{} {
|
||||||
|
return ctx.values.Get(idContextKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns the string representation of this request.
|
// String returns the string representation of this request.
|
||||||
// Each context has a unique string representation.
|
|
||||||
// It can be used for simple debugging scenarios, i.e print context as string.
|
|
||||||
//
|
//
|
||||||
// What it returns? A number which declares the length of the
|
// It returns the Context's ID given by a `SetID`call,
|
||||||
// total `String` calls per executable application, followed
|
// followed by the client's IP and the method:uri.
|
||||||
// by the remote IP (the client) and finally the method:url.
|
|
||||||
func (ctx *context) String() string {
|
func (ctx *context) String() string {
|
||||||
if ctx.id == 0 {
|
return fmt.Sprintf("[%s] %s ▶ %s:%s", ctx.GetID(), ctx.RemoteAddr(), ctx.Method(), ctx.Request().RequestURI)
|
||||||
// set the id here.
|
|
||||||
forward := atomic.AddUint64(&lastCapturedContextID, 1)
|
|
||||||
ctx.id = forward
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("[%d] %s ▶ %s:%s",
|
|
||||||
ctx.id, ctx.RemoteAddr(), ctx.Method(), ctx.Request().RequestURI)
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user