mirror of
https://github.com/kataras/iris.git
synced 2025-02-02 15:30:36 +01:00
Iris 4.0.0-alpha.4. Book is finally updated https://kataras.gitbooks.io/iris/content/ also
This commit is contained in:
parent
566a194836
commit
7ed5ed4519
22
HISTORY.md
22
HISTORY.md
|
@ -2,6 +2,25 @@
|
|||
|
||||
**How to upgrade**: remove your `$GOPATH/src/github.com/kataras/iris` folder, open your command-line and execute this command: `go get -u github.com/kataras/iris/iris`.
|
||||
|
||||
|
||||
## 4.0.0-alpha.4 -> 4.0.0-alpha.4
|
||||
|
||||
|
||||
** The important** , is that the [book](https://kataras.gitbooks.io/iris/content/) is finally updated!
|
||||
|
||||
If you're **willing to donate** click [here](DONATIONS.md)!
|
||||
|
||||
|
||||
- `iris.Config.Gzip`, enables gzip compression on your Render actions, this includes any type of render, templates and pure/raw content. If you don't want to enable it globaly, you could just use the third parameter on context.Render("myfileOrResponse", structBinding{}, iris.RenderOptions{"gzip": true}). It defaults to false
|
||||
|
||||
|
||||
**Fix**
|
||||
- https://github.com/kataras/iris/issues/301
|
||||
|
||||
**Sessions changes **
|
||||
|
||||
- `iris.Config.Sessions.Expires` it was time.Time, changed to time.Duration, which defaults to 0, means unlimited session life duration, if you change it then the correct date is setted on client's cookie but also server destroys the session automatically when the duration passed, this is better approach, see [here](https://github.com/kataras/iris/issues/301)
|
||||
|
||||
## 4.0.0-alpha.2 -> 4.0.0-alpha.3
|
||||
|
||||
**New**
|
||||
|
@ -21,7 +40,6 @@ A **Response Engine** gives you the freedom to create/change the render/response
|
|||
|
||||
**Fix**
|
||||
- https://github.com/kataras/iris/issues/294
|
||||
- https://github.com/kataras/iris/issues/301
|
||||
- https://github.com/kataras/iris/issues/303
|
||||
|
||||
|
||||
|
@ -29,7 +47,7 @@ A **Response Engine** gives you the freedom to create/change the render/response
|
|||
|
||||
- `iris.Config.Charset`, before alpha.3 was `iris.Config.Rest.Charset` & `iris.Config.Render.Template.Charset`, but you can override it at runtime by passinth a map `iris.RenderOptions` on the `context.Render` call .
|
||||
- `iris.Config.IsDevelopment`, before alpha.1 was `iris.Config.Render.Template.IsDevelopment`
|
||||
- `iris.Config.Gzip`, enables gzip compression on your Render actions, this includes any type of render, templates and pure/raw content. If you don't want to enable it globaly, you could just use the third parameter on context.Render("myfileOrResponse", structBinding{}, iris.RenderOptions{"gzip": true}). It defaults to false
|
||||
|
||||
|
||||
**Websockets changes**
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ I recommend writing your API tests using this new library, [httpexpect](https://
|
|||
Versioning
|
||||
------------
|
||||
|
||||
Current: **v4.0.0-alpha.3**
|
||||
Current: **v4.0.0-alpha.4**
|
||||
|
||||
> Iris is an active project
|
||||
|
||||
|
@ -186,7 +186,7 @@ License can be found [here](LICENSE).
|
|||
[Travis]: http://travis-ci.org/kataras/iris
|
||||
[License Widget]: https://img.shields.io/badge/license-MIT%20%20License%20-E91E63.svg?style=flat-square
|
||||
[License]: https://github.com/kataras/iris/blob/master/LICENSE
|
||||
[Release Widget]: https://img.shields.io/badge/release-v4.0.0--alpha.3-blue.svg?style=flat-square
|
||||
[Release Widget]: https://img.shields.io/badge/release-v4.0.0--alpha.4-blue.svg?style=flat-square
|
||||
[Release]: https://github.com/kataras/iris/releases
|
||||
[Chat Widget]: https://img.shields.io/badge/community-chat-00BCD4.svg?style=flat-square
|
||||
[Chat]: https://kataras.rocket.chat/channel/iris
|
||||
|
|
|
@ -13,17 +13,6 @@ const (
|
|||
|
||||
type (
|
||||
// Iris configs for the station
|
||||
// All fields can be changed before server's listen except the DisablePathCorrection field
|
||||
//
|
||||
// MaxRequestBodySize is the only options that can be changed after server listen -
|
||||
// using Config.MaxRequestBodySize = ...
|
||||
// Render's rest config can be changed after declaration but before server's listen -
|
||||
// using Config.Render.Rest...
|
||||
// Render's Template config can be changed after declaration but before server's listen -
|
||||
// using Config.Render.Template...
|
||||
// Sessions config can be changed after declaration but before server's listen -
|
||||
// using Config.Sessions...
|
||||
// and so on...
|
||||
Iris struct {
|
||||
|
||||
// DisablePathCorrection corrects and redirects the requested path to the registed path
|
||||
|
@ -106,6 +95,7 @@ type (
|
|||
Websocket *Websocket
|
||||
|
||||
// Tester contains the configs for the test framework, so far we have only one because all test framework's configs are setted by the iris itself
|
||||
// You can find example on the https://github.com/kataras/iris/glob/master/context_test.go
|
||||
Tester Tester
|
||||
}
|
||||
)
|
||||
|
|
|
@ -9,8 +9,8 @@ import (
|
|||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// Default values for base Server conf, can be changed for global use
|
||||
var (
|
||||
// Default values for base Server conf
|
||||
const (
|
||||
// DefaultServerHostname returns the default hostname which is 127.0.0.1
|
||||
DefaultServerHostname = "127.0.0.1"
|
||||
// DefaultServerPort returns the default port which is 8080
|
||||
|
@ -31,6 +31,9 @@ var (
|
|||
//
|
||||
// Default buffer size is 8MB
|
||||
DefaultWriteBufferSize = 8096
|
||||
|
||||
// DefaultServerName the response header of the 'Server' value when writes to the client
|
||||
DefaultServerName = "iris"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -38,9 +41,6 @@ var (
|
|||
DefaultServerAddr = DefaultServerHostname + ":" + strconv.Itoa(DefaultServerPort)
|
||||
)
|
||||
|
||||
// ServerName the response header of the 'Server' value when writes to the client
|
||||
const ServerName = "iris"
|
||||
|
||||
// Server used inside server for listening
|
||||
type Server struct {
|
||||
// ListenningAddr the addr that server listens to
|
||||
|
@ -79,6 +79,9 @@ type Server struct {
|
|||
RedirectTo string
|
||||
// Virtual If this server is not really listens to a real host, it mostly used in order to achieve testing without system modifications
|
||||
Virtual bool
|
||||
// Name the server's name, defaults to "iris".
|
||||
// You're free to change it, but I will trust you to don't, this is the only setting whose somebody, like me, can see if iris web framework is used
|
||||
Name string
|
||||
}
|
||||
|
||||
// ServerParseAddr parses the listening addr and returns this
|
||||
|
@ -114,7 +117,7 @@ func ServerParseAddr(listeningAddr string) string {
|
|||
|
||||
// DefaultServer returns the default configs for the server
|
||||
func DefaultServer() Server {
|
||||
return Server{ListeningAddr: DefaultServerAddr,
|
||||
return Server{ListeningAddr: DefaultServerAddr, Name: DefaultServerName,
|
||||
MaxRequestBodySize: DefaultMaxRequestBodySize,
|
||||
ReadBufferSize: DefaultReadBufferSize,
|
||||
WriteBufferSize: DefaultWriteBufferSize,
|
||||
|
|
|
@ -34,11 +34,12 @@ type (
|
|||
// DecodeCookie set it to true to decode the cookie key with base64 URLEncoding
|
||||
// Defaults to false
|
||||
DecodeCookie bool
|
||||
//Expires the date which the cookie must expires. Default infinitive/unlimited life
|
||||
Expires time.Time
|
||||
// Expires the duration of which the cookie must expires (created_time.Add(Expires)).
|
||||
// Default infinitive/unlimited life duration(0)
|
||||
Expires time.Duration
|
||||
// GcDuration every how much duration(GcDuration) the memory should be clear for unused cookies (GcDuration)
|
||||
// for example: time.Duration(2)*time.Hour. it will check every 2 hours if cookie hasn't be used for 2 hours,
|
||||
// deletes it from memory until the user comes back, then the session continue to work as it was
|
||||
// deletes it from backend memory until the user comes back, then the session continue to work as it was
|
||||
//
|
||||
// Default 2 hours
|
||||
GcDuration time.Duration
|
||||
|
@ -54,7 +55,7 @@ func DefaultSessions() Sessions {
|
|||
return Sessions{
|
||||
Cookie: DefaultCookieName,
|
||||
DecodeCookie: false,
|
||||
Expires: CookieExpireNever,
|
||||
Expires: 0,
|
||||
GcDuration: DefaultSessionGcDuration,
|
||||
DisableSubdomainPersistence: false,
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"github.com/imdario/mergo"
|
||||
)
|
||||
|
||||
// Currently only these 5 values are used for real
|
||||
const (
|
||||
// DefaultWriteTimeout 15 * time.Second
|
||||
DefaultWriteTimeout = 15 * time.Second
|
||||
|
@ -20,7 +19,7 @@ const (
|
|||
|
||||
//
|
||||
|
||||
// Websocket the config contains options for 'websocket' package
|
||||
// Websocket the config contains options for the ../websocket.go
|
||||
type Websocket struct {
|
||||
// WriteTimeout time allowed to write a message to the connection.
|
||||
// Default value is 15 * time.Second
|
||||
|
|
5
http.go
5
http.go
|
@ -254,7 +254,10 @@ type (
|
|||
|
||||
// newServer returns a pointer to a Server object, and set it's options if any, nothing more
|
||||
func newServer(cfg config.Server) *Server {
|
||||
s := &Server{Server: &fasthttp.Server{Name: config.ServerName}, Config: cfg}
|
||||
if cfg.Name == "" {
|
||||
cfg.Name = config.DefaultServerName
|
||||
}
|
||||
s := &Server{Server: &fasthttp.Server{Name: cfg.Name}, Config: cfg}
|
||||
s.prepare()
|
||||
return s
|
||||
}
|
||||
|
|
26
iris.go
26
iris.go
|
@ -84,7 +84,7 @@ import (
|
|||
|
||||
const (
|
||||
// Version of the iris
|
||||
Version = "4.0.0-alpha.3"
|
||||
Version = "4.0.0-alpha.4"
|
||||
|
||||
banner = ` _____ _
|
||||
|_ _| (_)
|
||||
|
@ -219,8 +219,6 @@ func New(cfg ...config.Iris) *Framework {
|
|||
},
|
||||
engines: make([]*templateEngineWrapper, 0),
|
||||
}
|
||||
//set the session manager
|
||||
s.sessions = newSessionsManager(&c.Sessions)
|
||||
// set the websocket server
|
||||
s.Websocket = NewWebsocketServer(s.Config.Websocket)
|
||||
// set the servemux, which will provide us the public API also, with its context pool
|
||||
|
@ -236,6 +234,11 @@ func New(cfg ...config.Iris) *Framework {
|
|||
}
|
||||
|
||||
func (s *Framework) initialize() {
|
||||
if s.Config.Sessions.Cookie != "" {
|
||||
//set the session manager
|
||||
s.sessions = newSessionsManager(s.Config.Sessions)
|
||||
}
|
||||
|
||||
// prepare the response engines, if no response engines setted for the default content-types
|
||||
// then add them
|
||||
|
||||
|
@ -335,9 +338,9 @@ func (s *Framework) Must(err error) {
|
|||
}
|
||||
}
|
||||
|
||||
// AddServer same as .Servers.Add(config.Server) instead
|
||||
// AddServer same as .Servers.Add(config.Server)
|
||||
//
|
||||
// AddServers starts a server which listens to this station
|
||||
// AddServer starts a server which listens to this station
|
||||
// Note that the view engine's functions {{ url }} and {{ urlpath }} will return the first's registered server's scheme (http/https)
|
||||
//
|
||||
// this is useful mostly when you want to have two or more listening ports ( two or more servers ) for the same station
|
||||
|
@ -352,10 +355,10 @@ func AddServer(cfg config.Server) *Server {
|
|||
return Default.AddServer(cfg)
|
||||
}
|
||||
|
||||
// AddServer same as .Servers.Add(config.Server) instead
|
||||
// AddServer same as .Servers.Add(config.Server)
|
||||
//
|
||||
// AddServers starts a server which listens to this station
|
||||
// Note that the view engine's functions {{ url }} and {{ urlpath }} will return the first's registered server's scheme (http/https)
|
||||
// AddServer starts a server which listens to this station
|
||||
// Note that the view engine's functions {{ url }} and {{ urlpath }} will return the last registered server's scheme (http/https)
|
||||
//
|
||||
// this is useful mostly when you want to have two or more listening ports ( two or more servers ) for the same station
|
||||
//
|
||||
|
@ -369,7 +372,7 @@ func (s *Framework) AddServer(cfg config.Server) *Server {
|
|||
return s.Servers.Add(cfg)
|
||||
}
|
||||
|
||||
// ListenTo listens to a server but receives the full server's configuration
|
||||
// ListenTo listens to a server but accepts the full server's configuration
|
||||
// returns an error, you're responsible to handle that
|
||||
// or use the iris.Must(iris.ListenTo(config.Server{}))
|
||||
//
|
||||
|
@ -378,7 +381,10 @@ func ListenTo(cfg config.Server) error {
|
|||
return Default.ListenTo(cfg)
|
||||
}
|
||||
|
||||
// ListenTo listens to a server but receives the full server's configuration
|
||||
// ListenTo listens to a server but acceots the full server's configuration
|
||||
// returns an error, you're responsible to handle that
|
||||
// or use the iris.Must(iris.ListenTo(config.Server{}))
|
||||
//
|
||||
// it's a blocking func
|
||||
func (s *Framework) ListenTo(cfg config.Server) (err error) {
|
||||
if cfg.ReadBufferSize == 0 {
|
||||
|
|
37
sessions.go
37
sessions.go
|
@ -42,6 +42,7 @@ type session struct {
|
|||
values map[string]interface{} // here is the real values
|
||||
mu sync.Mutex
|
||||
lastAccessedTime time.Time
|
||||
createdAt time.Time
|
||||
provider *sessionProvider
|
||||
}
|
||||
|
||||
|
@ -135,6 +136,7 @@ type (
|
|||
sessions map[string]*list.Element // underline TEMPORARY memory store used to give advantage on sessions used more times than others
|
||||
list *list.List // for GC
|
||||
databases []SessionDatabase
|
||||
expires time.Duration
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -145,12 +147,25 @@ func (p *sessionProvider) registerDatabase(db SessionDatabase) {
|
|||
}
|
||||
|
||||
func (p *sessionProvider) newSession(sid string) *session {
|
||||
return &session{
|
||||
|
||||
sess := &session{
|
||||
sid: sid,
|
||||
provider: p,
|
||||
lastAccessedTime: time.Now(),
|
||||
values: p.loadSessionValues(sid),
|
||||
}
|
||||
if p.expires > 0 { // if not unlimited life duration
|
||||
time.AfterFunc(p.expires, func() {
|
||||
// the destroy makes the check if this session is exists then or not,
|
||||
// this is used to destroy the session from the server-side also
|
||||
// it's good to have here for security reasons, I didn't add it on the gc function to separate its action
|
||||
p.destroy(sid)
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
return sess
|
||||
|
||||
}
|
||||
|
||||
func (p *sessionProvider) loadSessionValues(sid string) map[string]interface{} {
|
||||
|
@ -203,7 +218,6 @@ func (p *sessionProvider) destroy(sid string) {
|
|||
p.updateDatabases(sid, nil)
|
||||
delete(p.sessions, sid)
|
||||
p.list.Remove(elem)
|
||||
|
||||
}
|
||||
p.mu.Unlock()
|
||||
}
|
||||
|
@ -234,10 +248,9 @@ func (p *sessionProvider) gc(duration time.Duration) {
|
|||
|
||||
// if the time has passed. session was expired, then delete the session and its memory place
|
||||
// we are not destroy the session completely for the case this is re-used after
|
||||
|
||||
if time.Now().After(elem.Value.(*session).lastAccessedTime.Add(duration)) {
|
||||
sess := elem.Value.(*session)
|
||||
if time.Now().After(sess.lastAccessedTime.Add(duration)) {
|
||||
p.list.Remove(elem)
|
||||
delete(p.sessions, elem.Value.(*session).sid)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
|
@ -254,19 +267,19 @@ type (
|
|||
// sessionsManager implements the ISessionsManager interface
|
||||
// contains the cookie's name, the provider and a duration for GC and cookie life expire
|
||||
sessionsManager struct {
|
||||
config *config.Sessions
|
||||
config config.Sessions
|
||||
provider *sessionProvider
|
||||
}
|
||||
)
|
||||
|
||||
// newSessionsManager creates & returns a new SessionsManager and start its GC
|
||||
func newSessionsManager(c *config.Sessions) *sessionsManager {
|
||||
func newSessionsManager(c config.Sessions) *sessionsManager {
|
||||
if c.DecodeCookie {
|
||||
c.Cookie = base64.URLEncoding.EncodeToString([]byte(c.Cookie)) // change the cookie's name/key to a more safe(?)
|
||||
// get the real value for your tests by:
|
||||
//sessIdKey := url.QueryEscape(base64.URLEncoding.EncodeToString([]byte(iris.Config.Sessions.Cookie)))
|
||||
}
|
||||
manager := &sessionsManager{config: c, provider: &sessionProvider{list: list.New(), sessions: make(map[string]*list.Element, 0), databases: make([]SessionDatabase, 0)}}
|
||||
manager := &sessionsManager{config: c, provider: &sessionProvider{list: list.New(), sessions: make(map[string]*list.Element, 0), databases: make([]SessionDatabase, 0), expires: c.Expires}}
|
||||
//run the GC here
|
||||
go manager.gc()
|
||||
return manager
|
||||
|
@ -327,7 +340,13 @@ func (m *sessionsManager) start(ctx *Context) *session {
|
|||
|
||||
}
|
||||
cookie.SetHTTPOnly(true)
|
||||
cookie.SetExpire(m.config.Expires)
|
||||
if m.config.Expires == 0 {
|
||||
// unlimited life
|
||||
cookie.SetExpire(config.CookieExpireNever)
|
||||
} else {
|
||||
cookie.SetExpire(time.Now().Add(m.config.Expires))
|
||||
}
|
||||
|
||||
ctx.SetCookie(cookie)
|
||||
fasthttp.ReleaseCookie(cookie)
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue
Block a user