mirror of
https://github.com/kataras/iris.git
synced 2025-12-23 21:07:03 +00:00
Add notes for the new lead maintainer of the open-source iris project and align with @get-ion/ion by @hiveminded
Former-commit-id: da4f38eb9034daa49446df3ee529423b98f9b331
This commit is contained in:
@@ -1,7 +1,3 @@
|
||||
// Copyright 2017 Gerasimos Maropoulos, ΓΜ. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
@@ -32,7 +28,6 @@ import (
|
||||
|
||||
"github.com/kataras/iris/core/errors"
|
||||
"github.com/kataras/iris/core/memstore"
|
||||
"github.com/kataras/iris/sessions"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -142,7 +137,7 @@ func (r RequestParams) Len() int {
|
||||
// Context is the midle-man server's "object" for the clients.
|
||||
//
|
||||
// A New context is being acquired from a sync.Pool on each connection.
|
||||
// The Context is the most important thing on the Iris' http flow.
|
||||
// The Context is the most important thing on the iris's http flow.
|
||||
//
|
||||
// Developers send responses to the client's request through a Context.
|
||||
// Developers get request information from the client's request a Context.
|
||||
@@ -155,7 +150,7 @@ type Context interface {
|
||||
// BeginRequest is executing once for each request
|
||||
// it should prepare the (new or acquired from pool) context's fields for the new request.
|
||||
//
|
||||
// To follow the Iris' flow, developer should:
|
||||
// To follow the iris' flow, developer should:
|
||||
// 1. reset handlers to nil
|
||||
// 2. reset values to empty
|
||||
// 3. reset sessions to nil
|
||||
@@ -165,7 +160,7 @@ type Context interface {
|
||||
BeginRequest(http.ResponseWriter, *http.Request)
|
||||
// EndRequest is executing once after a response to the request was sent and this context is useless or released.
|
||||
//
|
||||
// To follow the Iris' flow, developer should:
|
||||
// To follow the iris' flow, developer should:
|
||||
// 1. flush the response writer's result
|
||||
// 2. release the response writer
|
||||
// and any other optional steps, depends on dev's application type.
|
||||
@@ -249,7 +244,7 @@ type Context interface {
|
||||
// Translate is the i18n (localization) middleware's function,
|
||||
// it calls the Get("translate") to return the translated value.
|
||||
//
|
||||
// Example: https://github.com/kataras/iris/tree/master/_examples/intermediate/i18n
|
||||
// Example: https://github.com/kataras/iris/tree/master/_examples/miscellaneous/i18n
|
||||
Translate(format string, args ...interface{}) string
|
||||
|
||||
// +------------------------------------------------------------+
|
||||
@@ -270,7 +265,16 @@ type Context interface {
|
||||
// Subdomain returns the subdomain of this request, if any.
|
||||
// Note that this is a fast method which does not cover all cases.
|
||||
Subdomain() (subdomain string)
|
||||
// RemoteAddr tries to return the real client's request IP.
|
||||
// RemoteAddr tries to parse and return the real client's request IP.
|
||||
//
|
||||
// Based on allowed headers names that can be modified from Configuration.RemoteAddrHeaders.
|
||||
//
|
||||
// If parse based on these headers fail then it will return the Request's `RemoteAddr` field
|
||||
// which is filled by the server before the HTTP handler.
|
||||
//
|
||||
// Look `Configuration.RemoteAddrHeaders`,
|
||||
// `Configuration.WithRemoteAddrHeader(...)`,
|
||||
// `Configuration.WithoutRemoteAddrHeader(...)` for more.
|
||||
RemoteAddr() string
|
||||
// GetHeader returns the request header's value based on its name.
|
||||
GetHeader(name string) string
|
||||
@@ -344,7 +348,7 @@ type Context interface {
|
||||
|
||||
// NotFound emits an error 404 to the client, using the specific custom error error handler.
|
||||
// Note that you may need to call ctx.StopExecution() if you don't want the next handlers
|
||||
// to be executed. Next handlers are being executed on Iris because you can alt the
|
||||
// to be executed. Next handlers are being executed on iris because you can alt the
|
||||
// error code and change it to a more specific one, i.e
|
||||
// users := app.Party("/users")
|
||||
// users.Done(func(ctx context.Context){ if ctx.StatusCode() == 400 { /* custom error code for /users */ }})
|
||||
@@ -401,9 +405,9 @@ type Context interface {
|
||||
//
|
||||
// Returns the number of bytes written and any write error encountered.
|
||||
WriteString(body string) (int, error)
|
||||
// WriteWithExpiration like SetBody but it sends with an expiration datetime
|
||||
// which is managed by the client-side (all major web browsers supports this)
|
||||
WriteWithExpiration(bodyContent []byte, cType string, modtime time.Time) error
|
||||
// WriteWithExpiration like Write but it sends with an expiration datetime
|
||||
// which is refreshed every package-level `StaticCacheDuration` field.
|
||||
WriteWithExpiration(body []byte, modtime time.Time) (int, error)
|
||||
// StreamWriter registers the given stream writer for populating
|
||||
// response body.
|
||||
//
|
||||
@@ -459,7 +463,7 @@ type Context interface {
|
||||
//
|
||||
// Look .ViewData and .View too.
|
||||
//
|
||||
// Example: https://github.com/kataras/iris/tree/master/_examples/intermediate/view/context-view-data/
|
||||
// Example: https://github.com/kataras/iris/tree/master/_examples/view/context-view-data/
|
||||
ViewLayout(layoutTmplFile string)
|
||||
|
||||
// ViewData saves one or more key-value pair in order to be passed if and when .View
|
||||
@@ -479,7 +483,7 @@ type Context interface {
|
||||
//
|
||||
// Look .ViewLayout and .View too.
|
||||
//
|
||||
// Example: https://github.com/kataras/iris/tree/master/_examples/intermediate/view/context-view-data/
|
||||
// Example: https://github.com/kataras/iris/tree/master/_examples/view/context-view-data/
|
||||
ViewData(key string, value interface{})
|
||||
|
||||
// View renders templates based on the adapted view engines.
|
||||
@@ -489,7 +493,7 @@ type Context interface {
|
||||
//
|
||||
// Look: .ViewData and .ViewLayout too.
|
||||
//
|
||||
// Examples: https://github.com/kataras/iris/tree/master/_examples/intermediate/view/
|
||||
// Examples: https://github.com/kataras/iris/tree/master/_examples/view/
|
||||
View(filename string) error
|
||||
|
||||
// Binary writes out the raw bytes as binary data.
|
||||
@@ -533,7 +537,7 @@ type Context interface {
|
||||
SendFile(filename string, destinationName string) error
|
||||
|
||||
// +------------------------------------------------------------+
|
||||
// | Cookies, Session and Flashes |
|
||||
// | Cookies |
|
||||
// +------------------------------------------------------------+
|
||||
|
||||
// SetCookie adds a cookie
|
||||
@@ -552,11 +556,6 @@ type Context interface {
|
||||
// on each (request's) cookies' name and value.
|
||||
VisitAllCookies(visitor func(name string, value string))
|
||||
|
||||
// Session returns the current user's Session.
|
||||
Session() sessions.Session
|
||||
// SessionDestroy destroys the whole session and removes the session id cookie.
|
||||
SessionDestroy()
|
||||
|
||||
// MaxAge returns the "cache-control" request header's value
|
||||
// seconds as int64
|
||||
// if header not found or parse failed then it returns -1.
|
||||
@@ -589,7 +588,7 @@ type Context interface {
|
||||
// this transaction scope is only for context's response.
|
||||
// Transactions have their own middleware ecosystem also, look iris.go:UseTransaction.
|
||||
//
|
||||
// See https://github.com/kataras/iris/tree/master/_examples/advanced/transactions for more
|
||||
// See https://github.com/kataras/iris/tree/master/_examples/ for more
|
||||
BeginTransaction(pipe func(t *Transaction))
|
||||
// SkipTransactions if called then skip the rest of the transactions
|
||||
// or all of them if called before the first transaction
|
||||
@@ -613,7 +612,7 @@ type Context interface {
|
||||
//
|
||||
// app.None(...) and app.Routes().Offline(route)/.Online(route, method)
|
||||
//
|
||||
// Example: https://github.com/kataras/iris/tree/master/_examples/intermediate/route-state
|
||||
// Example: https://github.com/kataras/iris/tree/master/_examples/routing/route-state
|
||||
//
|
||||
// User can get the response by simple using rec := ctx.Recorder(); rec.Body()/rec.StatusCode()/rec.Header().
|
||||
//
|
||||
@@ -622,10 +621,10 @@ type Context interface {
|
||||
// It's for extreme use cases, 99% of the times will never be useful for you.
|
||||
Exec(method string, path string)
|
||||
|
||||
// Application returns the Iris framework instance which belongs to this context.
|
||||
// Application returns the iris app instance which belongs to this context.
|
||||
// Worth to notice that this function returns an interface
|
||||
// of the Application, which contains methods that are safe
|
||||
// to be executed at serve-time. The full framework's fields
|
||||
// to be executed at serve-time. The full app's fields
|
||||
// and methods are not available here for the developer's safety.
|
||||
Application() Application
|
||||
|
||||
@@ -735,8 +734,8 @@ func Next(ctx Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// LimitRequestBodySize is a middleware which sets a request body size limit for all next handlers
|
||||
// should be registered before all other handlers
|
||||
// LimitRequestBodySize is a middleware which sets a request body size limit
|
||||
// for all next handlers in the chain.
|
||||
var LimitRequestBodySize = func(maxRequestBodySizeBytes int64) Handler {
|
||||
return func(ctx Context) {
|
||||
ctx.SetMaxRequestBodySize(maxRequestBodySizeBytes)
|
||||
@@ -760,12 +759,10 @@ type context struct {
|
||||
params RequestParams // url named parameters
|
||||
values memstore.Store // generic storage, middleware communication
|
||||
|
||||
// the underline application framework
|
||||
framework Application
|
||||
// the underline application app
|
||||
app Application
|
||||
// the route's handlers
|
||||
handlers Handlers
|
||||
// the session, can be nil if never acquired
|
||||
session sessions.Session
|
||||
// the current position of the handler's chain
|
||||
currentHandlerIndex int
|
||||
}
|
||||
@@ -775,14 +772,14 @@ type context struct {
|
||||
// to a custom one.
|
||||
//
|
||||
// This context is received by the context pool.
|
||||
func NewContext(framework Application) Context {
|
||||
return &context{framework: framework}
|
||||
func NewContext(app Application) Context {
|
||||
return &context{app: app}
|
||||
}
|
||||
|
||||
// BeginRequest is executing once for each request
|
||||
// it should prepare the (new or acquired from pool) context's fields for the new request.
|
||||
//
|
||||
// To follow the Iris' flow, developer should:
|
||||
// To follow the iris' flow, developer should:
|
||||
// 1. reset handlers to nil
|
||||
// 2. reset store to empty
|
||||
// 3. reset sessions to nil
|
||||
@@ -791,7 +788,6 @@ func NewContext(framework Application) Context {
|
||||
// and any other optional steps, depends on dev's application type.
|
||||
func (ctx *context) BeginRequest(w http.ResponseWriter, r *http.Request) {
|
||||
ctx.handlers = nil // will be filled by router.Serve/HTTP
|
||||
ctx.session = nil // >> >> by sessions.Session()
|
||||
ctx.values = ctx.values[0:0] // >> >> by context.Values().Set
|
||||
ctx.params.store = ctx.params.store[0:0]
|
||||
ctx.request = r
|
||||
@@ -802,7 +798,7 @@ func (ctx *context) BeginRequest(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// EndRequest is executing once after a response to the request was sent and this context is useless or released.
|
||||
//
|
||||
// To follow the Iris' flow, developer should:
|
||||
// To follow the iris' flow, developer should:
|
||||
// 1. flush the response writer's result
|
||||
// 2. release the response writer
|
||||
// and any other optional steps, depends on dev's application type.
|
||||
@@ -961,7 +957,7 @@ func (ctx *context) Values() *memstore.Store {
|
||||
// Translate is the i18n (localization) middleware's function,
|
||||
// it calls the Get("translate") to return the translated value.
|
||||
//
|
||||
// Example: https://github.com/kataras/iris/tree/master/_examples/intermediate/i18n
|
||||
// Example: https://github.com/kataras/iris/tree/master/_examples/miscellaneous/i18n
|
||||
func (ctx *context) Translate(format string, args ...interface{}) string {
|
||||
if cb, ok := ctx.values.Get(ctx.Application().ConfigurationReadOnly().GetTranslateFunctionContextKey()).(func(format string, args ...interface{}) string); ok {
|
||||
return cb(format, args...)
|
||||
@@ -1056,8 +1052,8 @@ func (ctx *context) Subdomain() (subdomain string) {
|
||||
subdomain = host[0:index]
|
||||
}
|
||||
|
||||
// listening on iris-go.com:80
|
||||
// subdomain = iris-go, but it's wrong, it should return ""
|
||||
// listening on mydomain.com:80
|
||||
// subdomain = mydomain, but it's wrong, it should return ""
|
||||
vhost := ctx.Application().ConfigurationReadOnly().GetVHost()
|
||||
if strings.Contains(vhost, subdomain) { // then it's not subdomain
|
||||
return ""
|
||||
@@ -1066,30 +1062,46 @@ func (ctx *context) Subdomain() (subdomain string) {
|
||||
return
|
||||
}
|
||||
|
||||
// RemoteAddr tries to return the real client's request IP.
|
||||
// RemoteAddr tries to parse and return the real client's request IP.
|
||||
//
|
||||
// Based on allowed headers names that can be modified from Configuration.RemoteAddrHeaders.
|
||||
//
|
||||
// If parse based on these headers fail then it will return the Request's `RemoteAddr` field
|
||||
// which is filled by the server before the HTTP handler.
|
||||
//
|
||||
// Look `Configuration.RemoteAddrHeaders`,
|
||||
// `Configuration.WithRemoteAddrHeader(...)`,
|
||||
// `Configuration.WithoutRemoteAddrHeader(...)` for more.
|
||||
func (ctx *context) RemoteAddr() string {
|
||||
header := ctx.GetHeader("X-Real-Ip")
|
||||
realIP := strings.TrimSpace(header)
|
||||
if realIP != "" {
|
||||
return realIP
|
||||
}
|
||||
realIP = ctx.GetHeader("X-Forwarded-For")
|
||||
idx := strings.IndexByte(realIP, ',')
|
||||
if idx >= 0 {
|
||||
realIP = realIP[0:idx]
|
||||
}
|
||||
realIP = strings.TrimSpace(realIP)
|
||||
if realIP != "" {
|
||||
return realIP
|
||||
|
||||
remoteHeaders := ctx.Application().ConfigurationReadOnly().GetRemoteAddrHeaders()
|
||||
|
||||
for headerName, enabled := range remoteHeaders {
|
||||
if enabled {
|
||||
headerValue := ctx.GetHeader(headerName)
|
||||
// exception needed for 'X-Forwarded-For' only , if enabled.
|
||||
if headerName == "X-Forwarded-For" {
|
||||
idx := strings.IndexByte(headerValue, ',')
|
||||
if idx >= 0 {
|
||||
headerValue = headerValue[0:idx]
|
||||
}
|
||||
}
|
||||
|
||||
realIP := strings.TrimSpace(headerValue)
|
||||
if realIP != "" {
|
||||
return realIP
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addr := strings.TrimSpace(ctx.request.RemoteAddr)
|
||||
if len(addr) == 0 {
|
||||
return ""
|
||||
}
|
||||
// if addr has port use the net.SplitHostPort otherwise(error occurs) take as it is
|
||||
if ip, _, err := net.SplitHostPort(addr); err == nil {
|
||||
return ip
|
||||
if addr != "" {
|
||||
// if addr has port use the net.SplitHostPort otherwise(error occurs) take as it is
|
||||
if ip, _, err := net.SplitHostPort(addr); err == nil {
|
||||
return ip
|
||||
}
|
||||
}
|
||||
|
||||
return addr
|
||||
}
|
||||
|
||||
@@ -1160,7 +1172,7 @@ func (ctx *context) StatusCode(statusCode int) {
|
||||
|
||||
// NotFound emits an error 404 to the client, using the specific custom error error handler.
|
||||
// Note that you may need to call ctx.StopExecution() if you don't want the next handlers
|
||||
// to be executed. Next handlers are being executed on Iris because you can alt the
|
||||
// to be executed. Next handlers are being executed on iris because you can alt the
|
||||
// error code and change it to a more specific one, i.e
|
||||
// users := app.Party("/users")
|
||||
// users.Done(func(ctx context.Context){ if ctx.StatusCode() == 400 { /* custom error code for /users */ }})
|
||||
@@ -1264,24 +1276,6 @@ func (ctx *context) Redirect(urlToRedirect string, statusHeader ...int) {
|
||||
httpStatus = statusHeader[0]
|
||||
}
|
||||
|
||||
// comment these because in some cases the the ctx.Request().URL.Path is already updated
|
||||
// to the new one, so it shows a wrong warning message.
|
||||
//
|
||||
// // we don't know the Method of the url to redirect,
|
||||
// // sure we can find it by reverse routing as we already implemented
|
||||
// // but it will take too much time for a simple redirect, it doesn't worth it.
|
||||
// // So we are checking the CURRENT Method for GET, HEAD, CONNECT and TRACE.
|
||||
// // the
|
||||
// // Fixes: http: //support.iris-go.com/d/21-wrong-warning-message-while-redirecting
|
||||
// shouldCheckForCycle := urlToRedirect == ctx.Path() && ctx.Method() == http.MethodGet
|
||||
// // from POST to GET on the same path will give a warning message but developers don't use the iris.DevLogger
|
||||
// // for production, so I assume it's OK to let it logs it
|
||||
// // (it can solve issues when developer redirects to the same handler over and over again)
|
||||
// // Note: it doesn't stops the redirect, the developer gets what he/she expected.
|
||||
// if shouldCheckForCycle {
|
||||
// ctx.Application().Log("warning: redirect from: '%s' to: '%s',\ncurrent method: '%s'", ctx.Path(), urlToRedirect, ctx.Method())
|
||||
// }
|
||||
|
||||
http.Redirect(ctx.writer, ctx.request, urlToRedirect, httpStatus)
|
||||
}
|
||||
|
||||
@@ -1356,7 +1350,7 @@ func (ctx *context) ReadForm(formObject interface{}) error {
|
||||
}
|
||||
|
||||
// or dec := formam.NewDecoder(&formam.DecoderOptions{TagName: "form"})
|
||||
// somewhere at the framework level. I did change the tagName to "form"
|
||||
// somewhere at the app level. I did change the tagName to "form"
|
||||
// inside its source code, so it's not needed for now.
|
||||
return errReadBody.With(formam.Decode(values, formObject))
|
||||
}
|
||||
@@ -1429,19 +1423,17 @@ func (ctx *context) staticCachePassed(modtime time.Time) bool {
|
||||
}
|
||||
|
||||
// WriteWithExpiration like Write but it sends with an expiration datetime
|
||||
// which is managed by the client-side (all major web browsers supports this)
|
||||
func (ctx *context) WriteWithExpiration(bodyContent []byte, cType string, modtime time.Time) error {
|
||||
// which is refreshed every package-level `StaticCacheDuration` field.
|
||||
func (ctx *context) WriteWithExpiration(body []byte, modtime time.Time) (int, error) {
|
||||
|
||||
if ctx.staticCachePassed(modtime) {
|
||||
return nil
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
modtimeFormatted := modtime.UTC().Format(ctx.Application().ConfigurationReadOnly().GetTimeFormat())
|
||||
ctx.Header(lastModifiedHeaderKey, modtimeFormatted)
|
||||
|
||||
ctx.writer.Header().Set(contentTypeHeaderKey, cType)
|
||||
ctx.writer.Header().Set(lastModifiedHeaderKey, modtimeFormatted)
|
||||
|
||||
_, err := ctx.writer.Write(bodyContent)
|
||||
return err
|
||||
return ctx.writer.Write(body)
|
||||
}
|
||||
|
||||
// StreamWriter registers the given stream writer for populating
|
||||
@@ -1584,7 +1576,7 @@ const (
|
||||
//
|
||||
// Look .ViewData and .View too.
|
||||
//
|
||||
// Example: https://github.com/kataras/iris/tree/master/_examples/intermediate/view/context-view-data/
|
||||
// Example: https://github.com/kataras/iris/tree/master/_examples/view/context-view-data/
|
||||
func (ctx *context) ViewLayout(layoutTmplFile string) {
|
||||
ctx.values.Set(ctx.Application().ConfigurationReadOnly().GetViewLayoutContextKey(), layoutTmplFile)
|
||||
}
|
||||
@@ -1606,7 +1598,7 @@ func (ctx *context) ViewLayout(layoutTmplFile string) {
|
||||
//
|
||||
// Look .ViewLayout and .View too.
|
||||
//
|
||||
// Example: https://github.com/kataras/iris/tree/master/_examples/intermediate/view/context-view-data/
|
||||
// Example: https://github.com/kataras/iris/tree/master/_examples/view/context-view-data/
|
||||
func (ctx *context) ViewData(key string, value interface{}) {
|
||||
viewDataContextKey := ctx.Application().ConfigurationReadOnly().GetViewDataContextKey()
|
||||
if key == "" {
|
||||
@@ -1620,7 +1612,9 @@ func (ctx *context) ViewData(key string, value interface{}) {
|
||||
return
|
||||
}
|
||||
|
||||
if data, ok := v.(Map); ok {
|
||||
if data, ok := v.(map[string]interface{}); ok {
|
||||
data[key] = value
|
||||
} else if data, ok := v.(Map); ok {
|
||||
data[key] = value
|
||||
}
|
||||
}
|
||||
@@ -1632,15 +1626,18 @@ func (ctx *context) ViewData(key string, value interface{}) {
|
||||
//
|
||||
// Look: .ViewData and .ViewLayout too.
|
||||
//
|
||||
// Examples: https://github.com/kataras/iris/tree/master/_examples/intermediate/view/
|
||||
// Examples: https://github.com/kataras/iris/tree/master/_examples/view/
|
||||
func (ctx *context) View(filename string) error {
|
||||
ctx.ContentType(contentHTMLHeaderValue)
|
||||
layout := ctx.values.GetString(ctx.Application().ConfigurationReadOnly().GetViewLayoutContextKey())
|
||||
bindingData := ctx.values.Get(ctx.Application().ConfigurationReadOnly().GetViewDataContextKey())
|
||||
cfg := ctx.Application().ConfigurationReadOnly()
|
||||
|
||||
layout := ctx.values.GetString(cfg.GetViewLayoutContextKey())
|
||||
bindingData := ctx.values.Get(cfg.GetViewDataContextKey())
|
||||
|
||||
err := ctx.Application().View(ctx.writer, filename, layout, bindingData)
|
||||
if err != nil {
|
||||
ctx.StatusCode(http.StatusInternalServerError)
|
||||
ctx.StopExecution()
|
||||
}
|
||||
|
||||
return err
|
||||
@@ -1682,6 +1679,36 @@ func (ctx *context) HTML(htmlContents string) (int, error) {
|
||||
return ctx.writer.WriteString(htmlContents)
|
||||
}
|
||||
|
||||
// JSON contains the options for the JSON (Context's) Renderer.
|
||||
type JSON struct {
|
||||
// http-specific
|
||||
StreamingJSON bool
|
||||
// content-specific
|
||||
UnescapeHTML bool
|
||||
Indent string
|
||||
Prefix string
|
||||
}
|
||||
|
||||
// JSONP contains the options for the JSONP (Context's) Renderer.
|
||||
type JSONP struct {
|
||||
// content-specific
|
||||
Indent string
|
||||
Callback string
|
||||
}
|
||||
|
||||
// XML contains the options for the XML (Context's) Renderer.
|
||||
type XML struct {
|
||||
// content-specific
|
||||
Indent string
|
||||
Prefix string
|
||||
}
|
||||
|
||||
// Markdown contains the options for the Markdown (Context's) Renderer.
|
||||
type Markdown struct {
|
||||
// content-specific
|
||||
Sanitize bool
|
||||
}
|
||||
|
||||
var (
|
||||
newLineB = []byte("\n")
|
||||
// the html codes for unescaping
|
||||
@@ -2022,31 +2049,6 @@ func (ctx *context) VisitAllCookies(visitor func(name string, value string)) {
|
||||
}
|
||||
}
|
||||
|
||||
// Session returns the current user's Session.
|
||||
func (ctx *context) Session() sessions.Session {
|
||||
sessmanager, err := ctx.Application().SessionManager()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if ctx.session == nil {
|
||||
ctx.session = sessmanager.Start(ctx.writer, ctx.request)
|
||||
}
|
||||
|
||||
return ctx.session
|
||||
}
|
||||
|
||||
// SessionDestroy destroys the whole session and removes the session id cookie.
|
||||
func (ctx *context) SessionDestroy() {
|
||||
if sess := ctx.Session(); sess != nil {
|
||||
sessmanager, err := ctx.Application().SessionManager()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sessmanager.Destroy(ctx.writer, ctx.request)
|
||||
}
|
||||
}
|
||||
|
||||
var maxAgeExp = regexp.MustCompile(`maxage=(\d+)`)
|
||||
|
||||
// MaxAge returns the "cache-control" request header's value
|
||||
@@ -2115,7 +2117,7 @@ var errTransactionInterrupted = errors.New("transaction interrupted, recovery fr
|
||||
// this transaction scope is only for context's response.
|
||||
// Transactions have their own middleware ecosystem also, look iris.go:UseTransaction.
|
||||
//
|
||||
// See https://github.com/kataras/iris/tree/master/_examples/advanced/transactions for more
|
||||
// See https://github.com/kataras/iris/tree/master/_examples/ for more
|
||||
func (ctx *context) BeginTransaction(pipe func(t *Transaction)) {
|
||||
// do NOT begin a transaction when the previous transaction has been failed
|
||||
// and it was requested scoped or SkipTransactions called manually.
|
||||
@@ -2129,7 +2131,7 @@ func (ctx *context) BeginTransaction(pipe func(t *Transaction)) {
|
||||
t := newTransaction(ctx) // it calls this *context, so the overriding with a new pool's New of context.Context wil not work here.
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
ctx.Application().Log(errTransactionInterrupted.Format(err).Error())
|
||||
ctx.Application().Logger().Warnln(errTransactionInterrupted.Format(err).Error())
|
||||
// complete (again or not , doesn't matters) the scope without loud
|
||||
t.Complete(nil)
|
||||
// we continue as normal, no need to return here*
|
||||
@@ -2181,7 +2183,7 @@ func (ctx *context) TransactionsSkipped() bool {
|
||||
//
|
||||
// app.None(...) and app.Routes().Offline(route)/.Online(route, method)
|
||||
//
|
||||
// Example: https://github.com/kataras/iris/tree/master/_examples/intermediate/route-state
|
||||
// Example: https://github.com/kataras/iris/tree/master/_examples/routing/route-state
|
||||
//
|
||||
// User can get the response by simple using rec := ctx.Recorder(); rec.Body()/rec.StatusCode()/rec.Header().
|
||||
//
|
||||
@@ -2233,13 +2235,13 @@ func (ctx *context) Exec(method string, path string) {
|
||||
}
|
||||
}
|
||||
|
||||
// Application returns the Iris framework instance which belongs to this context.
|
||||
// Application returns the iris app instance which belongs to this context.
|
||||
// Worth to notice that this function returns an interface
|
||||
// of the Application, which contains methods that are safe
|
||||
// to be executed at serve-time. The full framework's fields
|
||||
// to be executed at serve-time. The full app's fields
|
||||
// and methods are not available here for the developer's safety.
|
||||
func (ctx *context) Application() Application {
|
||||
return ctx.framework
|
||||
return ctx.app
|
||||
}
|
||||
|
||||
// +--------------------------------------------------------------+
|
||||
|
||||
Reference in New Issue
Block a user