mirror of
https://github.com/kataras/iris.git
synced 2025-03-14 08:26:26 +01:00
This commit is contained in:
parent
5e7975d97f
commit
716b5001da
259
README.md
259
README.md
|
@ -1,93 +1,56 @@
|
|||
<p align="center">
|
||||
# iris: sometimes the simplicity is the best solution
|
||||
[![Travis Widget]][Travis]
|
||||
[![Report Widget]][Report]
|
||||
[![Awesome Widget]][Awesome]
|
||||
[![License Widget]][License]
|
||||
[![Release Widget]][Release]
|
||||
[![Examples Widget]][Examples]
|
||||
[![Documentation Widget]][Documentation]
|
||||
[![Chat Widget]][Chat]
|
||||
[](http://iris-go.com)
|
||||
|
||||
|
||||
<a href="https://www.gitbook.com/book/kataras/iris/details"><img width="600" src="https://raw.githubusercontent.com/iris-contrib/website/gh-pages/assets/book/cover_6_flat_alpha.png"></a>
|
||||
|
||||
<br/>
|
||||
|
||||
<a href="https://travis-ci.org/kataras/iris"><img src="https://img.shields.io/travis/kataras/iris.svg?style=flat-square" alt="Build Status"></a>
|
||||
|
||||
<a href="https://github.com/avelino/awesome-go"><img src="https://img.shields.io/badge/awesome-%E2%9C%93-ff69b4.svg?style=flat-square" alt="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg"></a>
|
||||
|
||||
<a href="#"><img src="https://img.shields.io/badge/platform-Any-ec2eb4.svg?style=flat-square" alt="Platforms"></a>
|
||||
|
||||
<a href="https://github.com/kataras/iris/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-MIT%20%20-E91E63.svg?style=flat-square" alt="License"></a>
|
||||
|
||||
|
||||
<a href="https://golang.org"><img src="https://img.shields.io/badge/powered_by-Go-3362c2.svg?style=flat-square" alt="Built with GoLang"></a>
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
<a href="https://github.com/kataras/iris/releases"><img src="https://img.shields.io/badge/%20version%20-%204.4.1%20-blue.svg?style=flat-square" alt="Releases"></a>
|
||||
|
||||
<a href="https://github.com/iris-contrib/examples"><img src="https://img.shields.io/badge/%20examples-repository-3362c2.svg?style=flat-square" alt="Examples"></a>
|
||||
|
||||
<a href="https://www.gitbook.com/book/kataras/iris/details"><img src="https://img.shields.io/badge/%20docs-reference-5272B4.svg?style=flat-square" alt="Practical Guide/Docs"></a>
|
||||
|
||||
<a href="https://kataras.rocket.chat/channel/iris"><img src="https://img.shields.io/badge/%20community-chat-00BCD4.svg?style=flat-square" alt="Chat"></a><br/><br/>
|
||||
|
||||
|
||||
The <a href="https://github.com/kataras/iris#benchmarks">fastest</a> backend web framework for Go.
|
||||
<br/>
|
||||
Easy to <a href="https://www.gitbook.com/book/kataras/iris/details">learn</a>, while it's highly customizable. <br/>
|
||||
Ideally suited for both experienced and novice <b>Developers</b>.
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<img src="https://raw.githubusercontent.com/smallnest/go-web-framework-benchmark/4db507a22c964c9bc9774c5b31afdc199a0fe8b7/benchmark.png" href="#benchmarks" alt="Benchmark Wizzard July 21, 2016- Processing Time Horizontal Graph" />
|
||||
|
||||
</p>
|
||||
The fastest web framework for Go. Easy to learn, while it's highly customizable.
|
||||
Ideally suited for both experienced and novice Developers.
|
||||
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
Quick Look
|
||||
- Focus on high performance
|
||||
- Automatically install TLS certificates from https://letsencrypt.org
|
||||
- Proxy HTTP and WebSocket requests
|
||||
- Robust routing and middleware ecosystem
|
||||
- Define virtual hosts and (wildcard) subdomains with path level routing
|
||||
- Graceful shutdown
|
||||
- Limit request body
|
||||
- I18N
|
||||
- Serve static files
|
||||
- Log requests
|
||||
- Gzip response
|
||||
- Authentication
|
||||
- OAuth, OAuth2 supporting 27+ popular websites
|
||||
- JWT
|
||||
- Basic Authentication
|
||||
- HTTP Sessions
|
||||
- Add / Remove trailing slash from the URL with option to redirect
|
||||
- Redirect requests
|
||||
- HTTP to HTTPS
|
||||
- HTTP to HTTPS WWW
|
||||
- HTTP to HTTPS non WWW
|
||||
- Non WWW to WWW
|
||||
- WWW to non WWW
|
||||
- View system supporting more than six template engines
|
||||
- Highly scalable rich render (Markdown, JSON, JSONP, XML...)
|
||||
- Websocket API similar to socket.io
|
||||
- Hot Reload
|
||||
- Typescript integration + Web IDE
|
||||
- Checks for updates at startup
|
||||
|
||||
Getting Started
|
||||
------------
|
||||
|
||||
```go
|
||||
package main
|
||||
### Installation
|
||||
|
||||
import "github.com/kataras/iris"
|
||||
|
||||
func main() {
|
||||
// serve static files, just a fav here
|
||||
iris.Favicon("./favicon.ico")
|
||||
|
||||
// handle "/" - HTTP METHOD: "GET"
|
||||
iris.Get("/", func(ctx *iris.Context) {
|
||||
ctx.Render("index.html", nil)
|
||||
})
|
||||
|
||||
iris.Get("/login", func(ctx *iris.Context) {
|
||||
ctx.Render("login.html", iris.Map{"Title": "Login Page"})
|
||||
})
|
||||
|
||||
// handle "/login" - HTTP METHOD: "POST"
|
||||
iris.Post("/login", func(ctx *iris.Context) {
|
||||
secret := ctx.PostValue("secret")
|
||||
ctx.Session().Set("secret", secret)
|
||||
|
||||
ctx.Redirect("/user")
|
||||
})
|
||||
|
||||
// handle websocket connections
|
||||
iris.Config.Websocket.Endpoint = "/mychat"
|
||||
iris.Websocket.OnConnection(func(c iris.WebsocketConnection) {
|
||||
c.Join("myroom")
|
||||
|
||||
c.On("chat", func(message string){
|
||||
c.To("myroom").Emit("chat", "From "+c.ID()+": "+message)
|
||||
})
|
||||
})
|
||||
|
||||
// serve requests at http://localhost:8080
|
||||
iris.Listen(":8080")
|
||||
}
|
||||
```
|
||||
|
||||
Installation
|
||||
------------
|
||||
The only requirement is the [Go Programming Language](https://golang.org/dl), at least v1.7.
|
||||
|
||||
```bash
|
||||
|
@ -96,12 +59,9 @@ $ go get -u github.com/kataras/iris/iris
|
|||
|
||||
> If you have installation issues or you are connected to the Internet through China please, [click here](https://kataras.gitbooks.io/iris/content/install.html).
|
||||
|
||||
### Need help?
|
||||
|
||||
|
||||
Docs & Community
|
||||
------------
|
||||
|
||||
<a href="https://www.gitbook.com/book/kataras/iris/details"><img align="right" width="185" src="https://raw.githubusercontent.com/iris-contrib/website/gh-pages/assets/book/cover_4.jpg"></a>
|
||||
<a href="https://www.gitbook.com/book/kataras/iris/details"><img align="right" width="125" src="https://raw.githubusercontent.com/iris-contrib/website/gh-pages/assets/book/cover_4.jpg"></a>
|
||||
|
||||
|
||||
- The most important is to read [the practical guide](https://www.gitbook.com/book/kataras/iris/details).
|
||||
|
@ -110,77 +70,40 @@ Docs & Community
|
|||
|
||||
- [HISTORY.md](https://github.com//kataras/iris/tree/master/HISTORY.md) file is your best friend.
|
||||
|
||||
#### FAQ
|
||||
|
||||
If you'd like to discuss this package, or ask questions about it, feel free to
|
||||
|
||||
* Post an issue or idea [here](https://github.com/kataras/iris/issues).
|
||||
* [Chat][Chat].
|
||||
|
||||
|
||||
New logo have been designed by the community member, [@OneebMalik](https://github.com/OneebMalik).
|
||||
|
||||
|
||||
Features
|
||||
------------
|
||||
- Focus on high performance
|
||||
- Robust routing, static, wildcard subdomains and routes.
|
||||
- Internal version checker & updater[.*](https://github.com/kataras/iris/issues/401).
|
||||
- [Websocket API](https://github.com/kataras/go-websocket), [Sessions](https://github.com/kataras/go-sessions) support out of the box
|
||||
- Remote control through [SSH](https://github.com/iris-contrib/examples/blob/master/ssh/main.go)
|
||||
- View system supporting [6+](https://github.com/kataras/go-template) template engines.[*](https://kataras.gitbooks.io/iris/content/template-engines.html)
|
||||
- Highly scalable response engines with pre-defined [serializers](https://github.com/kataras/go-serializer)
|
||||
- Live reload
|
||||
- Typescript integration + Online editor
|
||||
- OAuth, OAuth2 supporting 27+ API providers, JWT, BasicAuth
|
||||
- and many other surprises
|
||||
|
||||
<img src="https://raw.githubusercontent.com/iris-contrib/website/gh-pages/assets/arrowdown.png" width="72"/>
|
||||
|
||||
|
||||
| Name | Description | Usage |
|
||||
| ------------------|:---------------------:|-------:|
|
||||
| [JSON ](https://github.com/kataras/go-serializer/tree/master/json) | JSON Serializer (Default) |[example 1](https://github.com/iris-contrib/examples/blob/master/serialize_engines/json_1/main.go),[example 2](https://github.com/iris-contrib/examples/blob/master/serialize_engines/json_2/main.go), [book section](https://kataras.gitbooks.io/iris/content/serialize-engines.html)
|
||||
| [JSONP ](https://github.com/kataras/go-serializer/tree/master/jsonp) | JSONP Serializer (Default) |[example 1](https://github.com/iris-contrib/examples/blob/master/serialize_engines/jsonp_1/main.go),[example 2](https://github.com/iris-contrib/examples/blob/master/serialize_engines/jsonp_2/main.go), [book section](https://kataras.gitbooks.io/iris/content/serialize-engines.html)
|
||||
| [XML ](https://github.com/kataras/go-serializer/tree/master/xml) | XML Serializer (Default) |[example 1](https://github.com/iris-contrib/examples/blob/master/serialize_engines/xml_1/main.go),[example 2](https://github.com/iris-contrib/examples/blob/master/serialize_engines/xml_2/main.go), [book section](https://kataras.gitbooks.io/iris/content/serialize-engines.html)
|
||||
| [Markdown ](https://github.com/kataras/go-serializer/tree/master/markdown) | Markdown Serializer (Default) |[example 1](https://github.com/iris-contrib/examples/blob/master/serialize_engines/markdown_1/main.go),[example 2](https://github.com/iris-contrib/examples/blob/master/serialize_engines/markdown_2/main.go), [book section](https://kataras.gitbooks.io/iris/content/serialize-engines.html)
|
||||
| [Text](https://github.com/kataras/go-serializer/tree/master/text) | Text Serializer (Default) |[example 1](https://github.com/iris-contrib/examples/blob/master/serialize_engines/text_1/main.go), [book section](https://kataras.gitbooks.io/iris/content/serialize-engines.html)
|
||||
| [Binary Data ](https://github.com/kataras/go-serializer/tree/master/data) | Binary Data Serializer (Default) |[example 1](https://github.com/iris-contrib/examples/blob/master/serialize_engines/data_1/main.go), [book section](https://kataras.gitbooks.io/iris/content/serialize-engines.html)
|
||||
| [HTML/Default Engine ](https://github.com/kataras/go-template/tree/master/html) | HTML Template Engine (Default) |[example ](https://github.com/iris-contrib/examples/blob/master/template_engines/template_html_0/main.go), [book section](https://kataras.gitbooks.io/iris/content/template-engines.html)
|
||||
| [Django Engine ](https://github.com/kataras/go-template/tree/master/django) | Django Template Engine |[example ](https://github.com/iris-contrib/examples/blob/master/template_engines/template_django_1/main.go), [book section](https://kataras.gitbooks.io/iris/content/template-engines.html)
|
||||
| [Pug/Jade Engine ](https://github.com/kataras/go-template/tree/master/pug) | Pug Template Engine |[example ](https://github.com/iris-contrib/examples/blob/master/template_engines/template_pug_1/main.go), [book section](https://kataras.gitbooks.io/iris/content/template-engines.html)
|
||||
| [Handlebars Engine ](https://github.com/kataras/go-template/tree/master/handlebars) | Handlebars Template Engine |[example ](https://github.com/iris-contrib/examples/blob/master/template_engines/template_handlebars_1/main.go), [book section](https://kataras.gitbooks.io/iris/content/template-engines.html)
|
||||
| [Amber Engine ](https://github.com/kataras/go-template/tree/master/amber) | Amber Template Engine |[example ](https://github.com/iris-contrib/examples/blob/master/template_engines/template_amber_1/main.go), [book section](https://kataras.gitbooks.io/iris/content/template-engines.html)
|
||||
| [Markdown Engine ](https://github.com/kataras/go-template/tree/master/markdown) | Markdown Template Engine |[example ](https://github.com/iris-contrib/examples/blob/master/template_engines/template_markdown_1/main.go), [book section](https://kataras.gitbooks.io/iris/content/template-engines.html)
|
||||
| [Basicauth Middleware ](https://github.com/iris-contrib/middleware/tree/master/basicauth) | HTTP Basic authentication |[example 1](https://github.com/iris-contrib/examples/blob/master/middleware_basicauth_1/main.go), [example 2](https://github.com/iris-contrib/examples/blob/master/middleware_basicauth_2/main.go), [book section](https://kataras.gitbooks.io/iris/content/basic-authentication.html) |
|
||||
| [JWT Middleware ](https://github.com/iris-contrib/middleware/tree/master/jwt) | JSON Web Tokens |[example ](https://github.com/iris-contrib/examples/blob/master/middleware_jwt/main.go), [book section](https://kataras.gitbooks.io/iris/content/jwt.html) |
|
||||
| [Cors Middleware ](https://github.com/iris-contrib/middleware/tree/master/cors) | Cross Origin Resource Sharing W3 specification | [how to use ](https://github.com/iris-contrib/middleware/tree/master/cors#how-to-use) |
|
||||
| [Secure Middleware ](https://github.com/iris-contrib/middleware/tree/master/secure) | Facilitates some quick security wins | [example](https://github.com/iris-contrib/examples/blob/master/middleware_secure/main.go) |
|
||||
| [I18n Middleware ](https://github.com/iris-contrib/middleware/tree/master/i18n) | Simple internationalization | [example](https://github.com/iris-contrib/examples/tree/master/middleware_internationalization_i18n), [book section](https://kataras.gitbooks.io/iris/content/middleware-internationalization-and-localization.html) |
|
||||
| [Recovery Middleware ](https://github.com/iris-contrib/middleware/tree/master/recovery) | Safety recover the station from panic | [example](https://github.com/iris-contrib/examples/blob/master/middleware_recovery/main.go) |
|
||||
| [Logger Middleware ](https://github.com/iris-contrib/middleware/tree/master/logger) | Logs every request | [example](https://github.com/iris-contrib/examples/blob/master/middleware_logger/main.go), [book section](https://kataras.gitbooks.io/iris/content/logger.html) |
|
||||
| [Profile Middleware ](https://github.com/iris-contrib/middleware/tree/master/pprof) | Http profiling for debugging | [example](https://github.com/iris-contrib/examples/blob/master/middleware_pprof/main.go) |
|
||||
| [Editor Plugin](https://github.com/iris-contrib/plugin/tree/master/editor) | Alm-tools, a typescript online IDE/Editor | [book section](https://kataras.gitbooks.io/iris/content/plugin-editor.html) |
|
||||
| [Typescript Plugin](https://github.com/iris-contrib/plugin/tree/master/typescript) | Auto-compile client-side typescript files | [book section](https://kataras.gitbooks.io/iris/content/plugin-typescript.html) |
|
||||
| [OAuth,OAuth2 Plugin](https://github.com/iris-contrib/plugin/tree/master/oauth) | User Authentication was never be easier, supports >27 providers | [example](https://github.com/iris-contrib/examples/tree/master/plugin_oauth_oauth2), [book section](https://kataras.gitbooks.io/iris/content/plugin-oauth.html) |
|
||||
| [Iris control Plugin](https://github.com/iris-contrib/plugin/tree/master/iriscontrol) | Basic (browser-based) control over your Iris station | [example](https://github.com/iris-contrib/examples/blob/master/plugin_iriscontrol/main.go), [book section](https://kataras.gitbooks.io/iris/content/plugin-iriscontrol.html) |
|
||||
|
||||
|
||||
FAQ
|
||||
------------
|
||||
Explore [these questions](https://github.com/kataras/iris/issues?q=label%3Aquestion) or navigate to the [community chat][Chat].
|
||||
|
||||
|
||||
Support
|
||||
------------
|
||||
|
||||
Hi, my name is Gerasimos Maropoulos and I'm the author of this project, let me put a few words about me.
|
||||
|
||||
I started to design iris the night of the 13 March 2016, some weeks later, iris started to became famous and I have to fix many issues and implement new features, but I didn't have time to work on Iris because I had a part time job and the (software engineering) colleague which I studied.
|
||||
|
||||
I wanted to make iris' users proud of the framework they're using, so I decided to interupt my studies and colleague, two days later I left from my part time job also.
|
||||
|
||||
Today I spend all my days and nights coding for Iris, and I'm happy about this, therefore I have zero incoming value.
|
||||
|
||||
- :star: the project
|
||||
- [Donate](https://github.com/kataras/iris/blob/master/DONATIONS.md)
|
||||
- :earth_americas: spread the word
|
||||
- [Contribute](#contributing) to the project
|
||||
|
||||
|
||||
|
||||
Philosophy
|
||||
------------
|
||||
|
||||
The Iris philosophy is to provide robust tooling for HTTP, making it a great solution for single page applications, web sites, hybrids, or public HTTP APIs.
|
||||
The Iris philosophy is to provide robust tooling for HTTP, making it a great solution for single page applications, web sites, hybrids, or public HTTP APIs. Keep note that, today, iris has the clostest performance to the nginx.
|
||||
|
||||
Iris does not force you to use any specific ORM or template engine. With support for the most used template engines, you can quickly craft the perfect application.
|
||||
|
||||
Iris is built on top of fasthttp (http basic layer), net/http middleware will not work by default on Iris, but you can convert any net/http middleware to Iris, see [middleware](https://github.com/iris-contrib/middleware) repository to see how.
|
||||
|
||||
If for any personal reasons you think that Iris+fasthttp is not suitable for you, but you don't want to miss the unique features that Iris provides, you can take a look at the HTTP2 [Q web framework](https://github.com/kataras/q).
|
||||
|
||||
## Benchmarks
|
||||
Benchmarks
|
||||
------------
|
||||
|
||||
This Benchmark test aims to compare the whole HTTP request processing between Go web frameworks.
|
||||
|
||||
|
@ -197,7 +120,7 @@ I recommend writing your API tests using this new library, [httpexpect](https://
|
|||
Versioning
|
||||
------------
|
||||
|
||||
Current: **v4.4.1**
|
||||
Current: **v4.4.2**
|
||||
|
||||
> Iris is an active project
|
||||
|
||||
|
@ -207,15 +130,13 @@ Read more about Semantic Versioning 2.0.0
|
|||
- https://en.wikipedia.org/wiki/Software_versioning
|
||||
- https://wiki.debian.org/UpstreamGuide#Releases_and_Versions
|
||||
|
||||
Todo
|
||||
------------
|
||||
- [x] Use of the standard `log.Logger` instead of the `iris-contrib/logger`(colorful logger), make these changes to all middleware, examples and plugins.
|
||||
- [x] Implement, even, a better way to manage configuration/options, devs will be able to set their own custom options inside there. ` I'm thinking of something the last days, but it will have breaking changes. `
|
||||
- [x] Implement an internal updater, as requested [here](https://github.com/kataras/iris/issues/401).
|
||||
- [x] Support of using native servers and net.Listener instead of Iris' defined.[*](https://github.com/kataras/iris/issues/438)
|
||||
- [x] Add context processors(PreRenders).[*](https://github.com/kataras/iris/issues/412)
|
||||
|
||||
Iris is a **Community-Driven** Project, waiting for your suggestions and [feature requests](https://github.com/kataras/iris/issues?utf8=%E2%9C%93&q=label%3A%22feature%20request%22)!
|
||||
Contributing
|
||||
------------
|
||||
If you are interested in contributing to the Iris project, please make sure that you read the document [CONTRIBUTING](https://github.com/kataras/iris/blob/master/CONTRIBUTING.md) first.
|
||||
|
||||
- Report issues
|
||||
- Suggest new features or enhancements
|
||||
|
||||
People
|
||||
------------
|
||||
|
@ -224,15 +145,33 @@ The big thanks goes to [all people](https://github.com/kataras/iris/issues?utf8=
|
|||
The author of Iris is [@kataras](https://github.com/kataras). If **you**'re willing to donate, feel **free** to navigate to the [DONATIONS PAGE](https://github.com/kataras/iris/blob/master/DONATIONS.md).
|
||||
|
||||
|
||||
Contributing
|
||||
------------
|
||||
If you are interested in contributing to the Iris project, please see the document [CONTRIBUTING](https://github.com/kataras/iris/blob/master/CONTRIBUTING.md).
|
||||
|
||||
|
||||
|
||||
License
|
||||
------------
|
||||
|
||||
This project is licensed under the MIT License, Copyright (c) 2016 Gerasimos Maropoulos.
|
||||
This project is licensed under the [MIT License](LICENSE), Copyright (c) 2016 Gerasimos Maropoulos.
|
||||
|
||||
|
||||
[Travis Widget]: https://img.shields.io/travis/kataras/iris.svg?style=flat-square
|
||||
[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-4.4.2%20-blue.svg?style=flat-square
|
||||
[Release]: https://github.com/kataras/iris/releases
|
||||
[Chat Widget]: https://img.shields.io/badge/community-chat%20-00BCD4.svg?style=flat-square
|
||||
[Chat]: https://kataras.rocket.chat/channel/iris
|
||||
[ChatMain]: https://kataras.rocket.chat/channel/iris
|
||||
[ChatAlternative]: https://gitter.im/kataras/iris
|
||||
[Report Widget]: https://img.shields.io/badge/report%20card%20-A%2B-F44336.svg?style=flat-square
|
||||
[Report]: http://goreportcard.com/report/kataras/iris
|
||||
[Documentation Widget]: https://img.shields.io/badge/docs-reference%20-5272B4.svg?style=flat-square
|
||||
[Documentation]: https://www.gitbook.com/book/kataras/iris/details
|
||||
[Examples Widget]: https://img.shields.io/badge/examples-repository%20-3362c2.svg?style=flat-square
|
||||
[Examples]: https://github.com/iris-contrib/examples
|
||||
[Language Widget]: https://img.shields.io/badge/powered_by-Go-3362c2.svg?style=flat-square
|
||||
[Language]: http://golang.org
|
||||
[Platform Widget]: https://img.shields.io/badge/platform-Any--OS-gray.svg?style=flat-square
|
||||
[Awesome]: https://github.com/avelino/awesome-go
|
||||
[Awesome Widget]: https://img.shields.io/badge/awesome%20go-%E2%9C%93-ff69b4.svg?style=flat-square
|
||||
|
|
|
@ -38,7 +38,7 @@ func (o OptionSet) Set(c *Configuration) {
|
|||
// Configuration the whole configuration for an iris instance ($instance.Config) or global iris instance (iris.Config)
|
||||
// these can be passed via options also, look at the top of this file(configuration.go)
|
||||
//
|
||||
// Configuration is also implements the OptionSet so it's a valid option itself, this is briliant enough
|
||||
// Configuration is also implements the OptionSet so it's a valid option itself, this is brilliant enough
|
||||
type Configuration struct {
|
||||
// VHost is the addr or the domain that server listens to, which it's optional
|
||||
// When to set VHost manually:
|
||||
|
|
|
@ -463,7 +463,7 @@ func (ctx *Context) SetHeader(k string, v string) {
|
|||
// first parameter is the url to redirect
|
||||
// second parameter is the http status should send, default is 302 (StatusFound), you can set it to 301 (Permant redirect), if that's nessecery
|
||||
func (ctx *Context) Redirect(urlToRedirect string, statusHeader ...int) {
|
||||
httpStatus := StatusFound // a 'temporary-redirect-like' wich works better than for our purpose
|
||||
httpStatus := StatusFound // a 'temporary-redirect-like' which works better than for our purpose
|
||||
if statusHeader != nil && len(statusHeader) > 0 && statusHeader[0] > 0 {
|
||||
httpStatus = statusHeader[0]
|
||||
}
|
||||
|
@ -833,7 +833,7 @@ func (ctx *Context) Set(key string, value interface{}) {
|
|||
// Note: the method ctx.Request.Header.VisitAllCookie by fasthttp, has a strange bug which I cannot solve at the moment.
|
||||
// This is the reason which this function exists and should be used instead of fasthttp's built'n.
|
||||
func (ctx *Context) VisitAllCookies(visitor func(key string, value string)) {
|
||||
// strange bug, this doesnt works also: cookieHeaderContent := ctx.Request.Header.Peek("Cookie")/User-Agent tested also
|
||||
// strange bug, this doesn't works also: cookieHeaderContent := ctx.Request.Header.Peek("Cookie")/User-Agent tested also
|
||||
headerbody := string(ctx.Request.Header.Header())
|
||||
headerlines := strings.Split(headerbody, "\n")
|
||||
for _, s := range headerlines {
|
||||
|
|
|
@ -402,7 +402,7 @@ func TestContextFlashMessages(t *testing.T) {
|
|||
}
|
||||
})
|
||||
|
||||
// get the first flash, the next should be avaiable to the next requess
|
||||
// get the first flash, the next should be available to the next requess
|
||||
Get("/get_first_flash", func(ctx *Context) {
|
||||
for _, v := range values {
|
||||
val, err := ctx.GetFlash(v.Key)
|
||||
|
@ -421,7 +421,7 @@ func TestContextFlashMessages(t *testing.T) {
|
|||
Get("/get_no_getflash", func(ctx *Context) {
|
||||
})
|
||||
|
||||
// get the last flash, the next should be avaiable to the next requess
|
||||
// get the last flash, the next should be available to the next requess
|
||||
Get("/get_last_flash", func(ctx *Context) {
|
||||
for i, v := range values {
|
||||
if i == len(values)-1 {
|
||||
|
@ -572,7 +572,7 @@ func TestContextSessions(t *testing.T) {
|
|||
es.Request("GET", "/get").Expect().Status(StatusOK).JSON().Object().Equal(values)
|
||||
}
|
||||
|
||||
// test destory which also clears first
|
||||
// test destroy which also clears first
|
||||
d := e.GET("/destroy").Expect().Status(StatusOK)
|
||||
d.JSON().Null()
|
||||
// This removed: d.Cookies().Empty(). Reason:
|
||||
|
|
89
http.go
89
http.go
|
@ -824,7 +824,7 @@ func (s bySubdomain) Less(i, j int) bool {
|
|||
var _ Route = &route{}
|
||||
|
||||
func newRoute(method []byte, subdomain string, path string, middleware Middleware) *route {
|
||||
r := &route{name: path + subdomain, method: method, subdomain: subdomain, path: path, middleware: middleware}
|
||||
r := &route{name: path + subdomain, method: method, methodStr: string(method), subdomain: subdomain, path: path, middleware: middleware}
|
||||
r.formatPath()
|
||||
return r
|
||||
}
|
||||
|
@ -926,11 +926,10 @@ type (
|
|||
// ex: mysubdomain.
|
||||
subdomain string
|
||||
entry *muxEntry
|
||||
next *muxTree
|
||||
}
|
||||
|
||||
serveMux struct {
|
||||
tree *muxTree
|
||||
garden []*muxTree
|
||||
lookups []*route
|
||||
maxParameters uint8
|
||||
|
||||
|
@ -1008,16 +1007,14 @@ func (mux *serveMux) fireError(statusCode int, ctx *Context) {
|
|||
errHandler.Serve(ctx)
|
||||
}
|
||||
|
||||
func (mux *serveMux) getTree(method []byte, subdomain string) (tree *muxTree) {
|
||||
tree = mux.tree
|
||||
for tree != nil {
|
||||
if bytes.Equal(tree.method, method) && tree.subdomain == subdomain {
|
||||
return
|
||||
func (mux *serveMux) getTree(method []byte, subdomain string) *muxTree {
|
||||
for i := range mux.garden {
|
||||
t := mux.garden[i]
|
||||
if bytes.Equal(t.method, method) && t.subdomain == subdomain {
|
||||
return t
|
||||
}
|
||||
tree = tree.next
|
||||
}
|
||||
// tree is nil here, return that.
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mux *serveMux) register(method []byte, subdomain string, path string, middleware Middleware) *route {
|
||||
|
@ -1041,30 +1038,30 @@ func (mux *serveMux) register(method []byte, subdomain string, path string, midd
|
|||
|
||||
// build collects all routes info and adds them to the registry in order to be served from the request handler
|
||||
// this happens once when server is setting the mux's handler.
|
||||
func (mux *serveMux) build() (func(reqCtx *fasthttp.RequestCtx) string, func([]byte, []byte) bool) {
|
||||
mux.tree = nil
|
||||
func (mux *serveMux) build() func(reqCtx *fasthttp.RequestCtx) string {
|
||||
|
||||
// check for cors conflicts FIRST in order to put them in OPTIONS tree also
|
||||
for i := range mux.lookups {
|
||||
r := mux.lookups[i]
|
||||
if r.hasCors() {
|
||||
if exists := mux.lookup(r.path + r.subdomain); exists == nil || exists.Method() != MethodOptions {
|
||||
// skip any already registed to OPTIONS, some users maybe do that manually, so we should be careful here, we do not catch custom names but that's fairly enough
|
||||
mux.register(MethodOptionsBytes, r.subdomain, r.path, r.middleware)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sort.Sort(bySubdomain(mux.lookups))
|
||||
for _, r := range mux.lookups {
|
||||
|
||||
for i := range mux.lookups {
|
||||
r := mux.lookups[i]
|
||||
// add to the registry tree
|
||||
tree := mux.getTree(r.method, r.subdomain)
|
||||
if tree == nil {
|
||||
//first time we register a route to this method with this domain
|
||||
tree = &muxTree{method: r.method, subdomain: r.subdomain, entry: &muxEntry{}, next: nil}
|
||||
|
||||
if mux.tree == nil {
|
||||
// it's the first entry
|
||||
mux.tree = tree
|
||||
} else {
|
||||
// find the last tree and make the .next to the tree we created before
|
||||
lastTree := mux.tree
|
||||
for lastTree != nil {
|
||||
if lastTree.next == nil {
|
||||
lastTree.next = tree
|
||||
break
|
||||
}
|
||||
lastTree = lastTree.next
|
||||
}
|
||||
}
|
||||
tree = &muxTree{method: r.method, subdomain: r.subdomain, entry: &muxEntry{}}
|
||||
mux.garden = append(mux.garden, tree)
|
||||
}
|
||||
// I decide that it's better to explicit give subdomain and a path to it than registedPath(mysubdomain./something) now its: subdomain: mysubdomain., path: /something
|
||||
// we have different tree for each of subdomains, now you can use everything you can use with the normal paths ( before you couldn't set /any/*path)
|
||||
|
@ -1086,20 +1083,7 @@ func (mux *serveMux) build() (func(reqCtx *fasthttp.RequestCtx) string, func([]b
|
|||
getRequestPath = func(reqCtx *fasthttp.RequestCtx) string { return utils.BytesToString(reqCtx.RequestURI()) }
|
||||
}
|
||||
|
||||
methodEqual := func(treeMethod []byte, reqMethod []byte) bool {
|
||||
return bytes.Equal(treeMethod, reqMethod)
|
||||
}
|
||||
// check for cors conflicts
|
||||
for _, r := range mux.lookups {
|
||||
if r.hasCors() {
|
||||
methodEqual = func(treeMethod []byte, reqMethod []byte) bool {
|
||||
return bytes.Equal(treeMethod, reqMethod) || bytes.Equal(reqMethod, MethodOptionsBytes)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return getRequestPath, methodEqual
|
||||
return getRequestPath
|
||||
|
||||
}
|
||||
|
||||
|
@ -1116,20 +1100,15 @@ func (mux *serveMux) lookup(routeName string) *route {
|
|||
func (mux *serveMux) BuildHandler() HandlerFunc {
|
||||
|
||||
// initialize the router once
|
||||
getRequestPath, methodEqual := mux.build()
|
||||
getRequestPath := mux.build()
|
||||
|
||||
return func(context *Context) {
|
||||
routePath := getRequestPath(context.RequestCtx)
|
||||
tree := mux.tree
|
||||
for tree != nil {
|
||||
if !methodEqual(tree.method, context.Method()) {
|
||||
// we break any CORS OPTIONS method
|
||||
// but for performance reasons if user wants http method OPTIONS to be served
|
||||
// then must register it with .Options(...)
|
||||
tree = tree.next
|
||||
for i := range mux.garden {
|
||||
tree := mux.garden[i]
|
||||
if !bytes.Equal(tree.method, context.Method()) {
|
||||
continue
|
||||
}
|
||||
// we have at least one subdomain on the root
|
||||
if mux.hosts && tree.subdomain != "" {
|
||||
// context.VirtualHost() is a slow method because it makes string.Replaces but user can understand that if subdomain then server will have some nano/or/milleseconds performance cost
|
||||
requestHost := context.VirtualHostname()
|
||||
|
@ -1143,17 +1122,17 @@ func (mux *serveMux) BuildHandler() HandlerFunc {
|
|||
// so the host must be api.iris-go.com:8080
|
||||
if tree.subdomain+mux.hostname != requestHost {
|
||||
// go to the next tree, we have a subdomain but it is not the correct
|
||||
tree = tree.next
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
//("it's subdomain but the request is the same as the listening addr mux.host == requestHost =>" + mux.host + "=" + requestHost + " ____ and tree's subdomain was: " + tree.subdomain)
|
||||
tree = tree.next
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
middleware, params, mustRedirect := tree.entry.get(routePath, context.Params) // pass the parameters here for 0 allocation
|
||||
if middleware != nil {
|
||||
// ok we found the correct route, serve it and exit entirely from here
|
||||
|
|
|
@ -152,6 +152,8 @@ func TestMultiRunningServers_v1_PROXY(t *testing.T) {
|
|||
defer Close()
|
||||
host := "localhost" // you have to add it to your hosts file( for windows, as 127.0.0.1 mydomain.com)
|
||||
hostTLS := "localhost:9999"
|
||||
Close()
|
||||
defer Close()
|
||||
initDefault()
|
||||
Default.Config.DisableBanner = true
|
||||
// create the key and cert files on the fly, and delete them when this test finished
|
||||
|
@ -406,9 +408,12 @@ func TestMuxSimpleParty(t *testing.T) {
|
|||
}
|
||||
|
||||
Default.Config.VHost = "0.0.0.0:8080"
|
||||
//Default.Config.Tester.Debug = true
|
||||
//Default.Config.Tester.ExplicitURL = true
|
||||
e := Tester(t)
|
||||
|
||||
request := func(reqPath string) {
|
||||
|
||||
e.Request("GET", reqPath).
|
||||
Expect().
|
||||
Status(StatusOK).Body().Equal(Default.Config.VHost + reqPath)
|
||||
|
|
2
iris.go
2
iris.go
|
@ -79,7 +79,7 @@ import (
|
|||
|
||||
const (
|
||||
// Version is the current version of the Iris web framework
|
||||
Version = "4.4.1"
|
||||
Version = "4.4.2"
|
||||
|
||||
banner = ` _____ _
|
||||
|_ _| (_)
|
||||
|
|
|
@ -176,13 +176,13 @@ func TestPluginEvents(t *testing.T) {
|
|||
plugins.DoPreClose(nil)
|
||||
|
||||
if !prelistenran {
|
||||
t.Fatalf("Expected to run PreListen Func but it doesnt!")
|
||||
t.Fatalf("Expected to run PreListen Func but it doesn't!")
|
||||
}
|
||||
if !postlistenran {
|
||||
t.Fatalf("Expected to run PostListen Func but it doesnt!")
|
||||
t.Fatalf("Expected to run PostListen Func but it doesn't!")
|
||||
}
|
||||
if !precloseran {
|
||||
t.Fatalf("Expected to run PostListen Func but it doesnt!")
|
||||
t.Fatalf("Expected to run PostListen Func but it doesn't!")
|
||||
}
|
||||
|
||||
if !myplugin.named {
|
||||
|
@ -192,13 +192,13 @@ func TestPluginEvents(t *testing.T) {
|
|||
t.Fatalf("Plugin should be activated but it's not!")
|
||||
}
|
||||
if !myplugin.prelistenran {
|
||||
t.Fatalf("Expected to run PreListen Struct but it doesnt!")
|
||||
t.Fatalf("Expected to run PreListen Struct but it doesn't!")
|
||||
}
|
||||
if !myplugin.postlistenran {
|
||||
t.Fatalf("Expected to run PostListen Struct but it doesnt!")
|
||||
t.Fatalf("Expected to run PostListen Struct but it doesn't!")
|
||||
}
|
||||
if !myplugin.precloseran {
|
||||
t.Fatalf("Expected to run PostListen Struct but it doesnt!")
|
||||
t.Fatalf("Expected to run PostListen Struct but it doesn't!")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user