mirror of
https://github.com/kataras/iris.git
synced 2025-02-02 15:30:36 +01:00
ok almost finished. We're good at deadlines eventually. Tomorrow at 23:59 an article will be published same time with the dev branch merge to master
Former-commit-id: 42c1bf88cedbddf3cc01366ab769139546902e71
This commit is contained in:
parent
617258890e
commit
1b1661ed53
19
FAQ.md
19
FAQ.md
|
@ -60,17 +60,30 @@ Iris may have reached version 8, but we're not stopping there. We have many feat
|
||||||
Yes, not only because you will learn Golang in the same time, but there are some positions
|
Yes, not only because you will learn Golang in the same time, but there are some positions
|
||||||
open for Iris-specific developers the time we speak.
|
open for Iris-specific developers the time we speak.
|
||||||
|
|
||||||
- https://glints.id/opportunities/jobs/5553
|
Go to our facebook page, like it and receive notifications about new job offers, we already have couple of them stay at the top of the page: https://www.facebook.com/iris.framework
|
||||||
|
|
||||||
|
<!--
|
||||||
## Can Iris be used in production after Dubai purchase?
|
## Can Iris be used in production after Dubai purchase?
|
||||||
|
|
||||||
Yes, now more than ever.
|
Yes, now more than ever.
|
||||||
|
|
||||||
https://github.com/kataras/iris/issues/711
|
https://github.com/kataras/iris/issues/711
|
||||||
|
|
||||||
|
-------
|
||||||
|
|
||||||
|
UPDATE which I could mention by the beginning of the Decemember of 2017:
|
||||||
|
|
||||||
|
Nothing keeps for ever, and we should move on to greater things.
|
||||||
|
|
||||||
|
As you probably know, I was hired to develop an inside Iris version for a Dubai-based startup company's specific requirements in the same time I was developing the open-source Iris repository with your help this time as well!
|
||||||
|
|
||||||
|
As our first deal was to end this agreement via last-time negotiatations by the end of the current year (2017), the
|
||||||
|
agreement ended unofficially at 22 Novemember of 2017 (officially some weeks later, paper work), and after a week I came back to Greece as you may understood from the regularly commits and improvements to the public repository that I pushed.
|
||||||
|
-->
|
||||||
|
|
||||||
## Do we have a community Chat?
|
## Do we have a community Chat?
|
||||||
|
|
||||||
Yes, https://kataras.rocket.chat/channel/iris.
|
Yes, https://chat.iris-go.com
|
||||||
|
|
||||||
https://github.com/kataras/iris/issues/646
|
https://github.com/kataras/iris/issues/646
|
||||||
|
|
||||||
|
@ -78,4 +91,4 @@ https://github.com/kataras/iris/issues/646
|
||||||
|
|
||||||
By normal people like you, who help us by donating small or larger amounts of money.
|
By normal people like you, who help us by donating small or larger amounts of money.
|
||||||
|
|
||||||
Help this project to continue deliver awesome and unique features with the higher code quality as possible by donating any amount via [PayPal](https://www.paypal.me/kataras)!
|
Help this project to continue deliver awesome and unique features with the highest possible code quality as possible by donating any amount via [PayPal](https://www.paypal.me/kataras). Your name will be published [here](https://iris-go.com/donate) after your approval via e-mail.
|
160
HISTORY.md
160
HISTORY.md
|
@ -16,19 +16,161 @@ Developers are not forced to upgrade if they don't really need it. Upgrade whene
|
||||||
> Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes.
|
> Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes.
|
||||||
|
|
||||||
**How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris` or let the automatic updater do that for you.
|
**How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris` or let the automatic updater do that for you.
|
||||||
<!--
|
|
||||||
# Mo, 01 Jenuary 2018 | v10.0.0
|
# Mo, 01 Jenuary 2018 | v10.0.0
|
||||||
|
|
||||||
We must thanks [Mrs. Diana](https://www.instagram.com/merry.dii/) for our awesome new [logo](https://iris-go.com/images/logo.svg)!
|
We must thanks [Mrs. Diana](https://www.instagram.com/merry.dii/) for our awesome new [logo](https://iris-go.com/images/logo.svg)!
|
||||||
|
|
||||||
You can [contact](mailto:Kovalenkodiana8@gmail.com) her for any design-related enquiries or explore and send a direct message via [instagram](https://www.instagram.com/merry.dii/).
|
You can [contact](mailto:Kovalenkodiana8@gmail.com) her for any design-related enquiries or explore and send a direct message via [instagram](https://www.instagram.com/merry.dii/).
|
||||||
|
|
||||||
TODO:
|
<p align="center">
|
||||||
|
<img width="170px" src="https://iris-go.com/images/logo.svg" />
|
||||||
|
</p>
|
||||||
|
|
||||||
1. add one more feature, to 'get' auto-created *Route on the mvc by the function name, people need this to change the route's name
|
At this version we have many internal improvements but just two major changes and one big feature, called **hero**.
|
||||||
for reverse routing in the templates, I've already implemented the 'add custom routes' based on any mvc function by its name.
|
|
||||||
|
|
||||||
2. list of the changes, we have just one big change,
|
> The new version adds 75 plus new commits, read them if you are developing a web framework based on Iris. Why v10? 9 was skipped for undefined reasons.
|
||||||
on the mvc re-design but we have some improvements as well
|
|
||||||
I will not list all 70 commits ofc, just the actual changes
|
## Hero
|
||||||
the end-developer should know. -->
|
|
||||||
|
The new package [hero](hero) contains features for binding any object or function that `handlers` may use, these are called dependencies. Hero funcs can also return any type of values, these values will be dispatched to the client.
|
||||||
|
|
||||||
|
> You may saw binding before but you didn't have code editor's support, with Iris you get truly safe binding thanks to the new `hero` package. It's also fast, near to raw handlers performance because Iris calculates everything before server ran!
|
||||||
|
|
||||||
|
Below you will see some screenshots we prepared for you in order to be easier to understand:
|
||||||
|
|
||||||
|
### 1. Path Parameters - Built'n Dependencies
|
||||||
|
|
||||||
|
![](https://github.com/kataras/explore/raw/master/iris/hero/hero-1-monokai.png)
|
||||||
|
|
||||||
|
### 2. Services - Static Dependencies
|
||||||
|
|
||||||
|
![](https://github.com/kataras/explore/raw/master/iris/hero/hero-2-monokai.png)
|
||||||
|
|
||||||
|
### 3. Per-Request - Dynamic Dependencies
|
||||||
|
|
||||||
|
![](https://github.com/kataras/explore/raw/master/iris/hero/hero-3-monokai.png)
|
||||||
|
|
||||||
|
`hero funcs` are very easy to understand and when you start using them **you never go back**.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
- [Basic](_examples/hero/basic/main.go)
|
||||||
|
- [Overview](_examples/hero/overview)
|
||||||
|
|
||||||
|
## MVC
|
||||||
|
|
||||||
|
You have to understand the `hero` package in order to use the `mvc`, because `mvc` uses the `hero` internally for the controller's methods you use as routes, the same rules applied to those controller's methods of yours as well.
|
||||||
|
|
||||||
|
With this version you can register **any controller's methods as routes manually**, you can **get a route based on a method name and change its `Name` (useful for reverse routing inside templates)**, you can use any **dependencies** registered from `hero.Register` or `mvc.New(iris.Party).Register` per mvc application or per-controller, **you can still use `BeginRequest` and `EndRequest`**, you can catch **`BeforeActivation(b mvc.BeforeActivation)` to add dependencies per controller and `AfterActivation(a mvc.AfterActivation)` to make any post-validations**, **singleton controllers when no dynamic dependencies are used**, **Websocket controller, as simple as a `websocket.Connection` dependency** and more...
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
**If you used MVC before then read very carefully: MVC CONTAINS SOME BREAKING CHANGES BUT YOU CAN DO A LOT MORE AND EVEN FASTER THAN BEFORE**
|
||||||
|
|
||||||
|
**PLEASE READ THE EXAMPLES CAREFULLY, WE'VE MADE THEM FOR YOU**
|
||||||
|
|
||||||
|
Old examples are here as well. Compare the two different versions of each example to understand what you win if you upgrade now.
|
||||||
|
|
||||||
|
| NEW | OLD |
|
||||||
|
| -----------|-------------|
|
||||||
|
| [Hello world](_examples/mvc/hello-world/main.go) | [OLD Hello world](https://github.com/kataras/iris/blob/v8/_examples/mvc/hello-world/main.go) |
|
||||||
|
| [Session Controller](_examples/mvc/session-controller/main.go) | [OLD Session Controller](https://github.com/kataras/iris/blob/v8/_examples/mvc/session-controller/main.go) |
|
||||||
|
| [Overview - Plus Repository and Service layers](_examples/mvc/overview) | [OLD Overview - Plus Repository and Service layers](https://github.com/kataras/iris/tree/v8/_examples/mvc/overview) |
|
||||||
|
| [Login showcase - Plus Repository and Service layers](_examples/mvc/login) | [OLD Login showcase - Plus Repository and Service layers](https://github.com/kataras/iris/tree/v8/_examples/mvc/login) |
|
||||||
|
| [Singleton](_examples/mvc/singleton) | **NEW** |
|
||||||
|
| [Websocket Controller](_examples/mvc/websocket) | **NEW** |
|
||||||
|
| [Vue.js Todo MVC](_examples/tutorial/vuejs-todo-mvc) | **NEW** |
|
||||||
|
|
||||||
|
## context#PostMaxMemory
|
||||||
|
|
||||||
|
Remove the old static variable `context.DefaultMaxMemory` and replace it with the configuration `WithPostMaxMemory`.
|
||||||
|
|
||||||
|
```go
|
||||||
|
// WithPostMaxMemory sets the maximum post data size
|
||||||
|
// that a client can send to the server, this differs
|
||||||
|
// from the overral request body size which can be modified
|
||||||
|
// by the `context#SetMaxRequestBodySize` or `iris#LimitRequestBodySize`.
|
||||||
|
//
|
||||||
|
// Defaults to 32MB or 32 << 20 if you prefer.
|
||||||
|
func WithPostMaxMemory(limit int64) Configurator
|
||||||
|
```
|
||||||
|
|
||||||
|
If you used that old static field you will have to change that single line.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/kataras/iris"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := iris.New()
|
||||||
|
// [...]
|
||||||
|
|
||||||
|
app.Run(iris.Addr(":8080"), iris.WithPostMaxMemory(10 << 20))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## context#UploadFormFiles
|
||||||
|
|
||||||
|
New method to upload multiple files, should be used for common upload actions, it's just a helper function.
|
||||||
|
|
||||||
|
```go
|
||||||
|
// UploadFormFiles uploads any received file(s) from the client
|
||||||
|
// to the system physical location "destDirectory".
|
||||||
|
//
|
||||||
|
// The second optional argument "before" gives caller the chance to
|
||||||
|
// modify the *miltipart.FileHeader before saving to the disk,
|
||||||
|
// it can be used to change a file's name based on the current request,
|
||||||
|
// all FileHeader's options can be changed. You can ignore it if
|
||||||
|
// you don't need to use this capability before saving a file to the disk.
|
||||||
|
//
|
||||||
|
// Note that it doesn't check if request body streamed.
|
||||||
|
//
|
||||||
|
// Returns the copied length as int64 and
|
||||||
|
// a not nil error if at least one new file
|
||||||
|
// can't be created due to the operating system's permissions or
|
||||||
|
// http.ErrMissingFile if no file received.
|
||||||
|
//
|
||||||
|
// If you want to receive & accept files and manage them manually you can use the `context#FormFile`
|
||||||
|
// instead and create a copy function that suits your needs, the below is for generic usage.
|
||||||
|
//
|
||||||
|
// The default form's memory maximum size is 32MB, it can be changed by the
|
||||||
|
// `iris#WithPostMaxMemory` configurator at main configuration passed on `app.Run`'s second argument.
|
||||||
|
//
|
||||||
|
// See `FormFile` to a more controlled to receive a file.
|
||||||
|
func (ctx *context) UploadFormFiles(
|
||||||
|
destDirectory string,
|
||||||
|
before ...func(string, string),
|
||||||
|
) (int64, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Example can be found [here](_examples/http_request/upload-files/main.go).
|
||||||
|
|
||||||
|
## context#View
|
||||||
|
|
||||||
|
Just a minor addition, add a second optional variadic argument to the `context#view` method to accept a single value for template binding.
|
||||||
|
When you just want one value and not key-value pairs, you used to use an empty string on the `ViewData`, which is fine, especially if you preload these from a previous handler/middleware in the request handlers chain.
|
||||||
|
|
||||||
|
```go
|
||||||
|
func(ctx iris.Context) {
|
||||||
|
ctx.ViewData("", myItem{Name: "iris" })
|
||||||
|
ctx.View("item.html")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Same as:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func(ctx iris.Context) {
|
||||||
|
ctx.View("item.html", myItem{Name: "iris" })
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
Item's name: {{.Name}}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Session#GetString
|
||||||
|
|
||||||
|
`sessions/session#GetString` can now return a filled value even if the stored value is a type of integer, just like the memstore, the context's temp store, the context's path parameters and the context's url parameters.
|
22
README.md
22
README.md
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<img align="right" width="170px" src="https://iris-go.com/images/logo.svg" title="logo created by @merry.dii" />
|
<img align="right" width="170px" src="https://iris-go.com/images/logo.svg" title="logo created by @merry.dii" />
|
||||||
|
|
||||||
[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris) <!-- [![release](https://img.shields.io/github/release/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/releases)--> [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![github closed issues](https://img.shields.io/github/issues-closed-raw/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/issues?q=is%3Aissue+is%3Aclosed) [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/tree/master/_examples) [![release](https://img.shields.io/badge/release%20-v10.0-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
|
[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris)<!-- [![release](https://img.shields.io/github/release/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/releases)--> [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris)<!--[![github closed issues](https://img.shields.io/github/issues-closed-raw/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/issues?q=is%3Aissue+is%3Aclosed)--> [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/tree/master/_examples) [![release](https://img.shields.io/badge/release%20-v10.0-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
|
||||||
|
|
||||||
Iris is a fast, simple yet fully featured and very efficient web framework for Go.
|
Iris is a fast, simple yet fully featured and very efficient web framework for Go.
|
||||||
|
|
||||||
|
@ -41,9 +41,10 @@ _Updated at: [Tuesday, 21 November 2017](_benchmarks/README_UNIX.md)_
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
- [HISTORY](HISTORY.md) file is your best friend, it contains information about all the new features for the current release, you can even search for [older versions](https://github.com/kataras/iris/releases)
|
- [HISTORY](HISTORY.md#mo-01-jenuary-2018--v1000) file is your best friend, it contains information about the latest features and changes
|
||||||
- Did you happen to find a bug? Post it at [github issues](https://github.com/kataras/iris/issues)
|
- Did you happen to find a bug? Post it at [github issues](https://github.com/kataras/iris/issues)
|
||||||
- Do you have any questions or need to speak with someone experienced to solve a problem at real-time? Join us to the [community chat](https://chat.iris-go.com)
|
- Do you have any questions or need to speak with someone experienced to solve a problem at real-time? Join us to the [community chat](https://chat.iris-go.com)
|
||||||
|
- Complete our form-based user experience report by clicking [here](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
||||||
- Do you like the framework? Tweet something about it! The People have spoken:
|
- Do you like the framework? Tweet something about it! The People have spoken:
|
||||||
|
|
||||||
<a href="https://twitter.com/gelnior/status/769100480706379776">
|
<a href="https://twitter.com/gelnior/status/769100480706379776">
|
||||||
|
@ -81,15 +82,11 @@ _Updated at: [Tuesday, 21 November 2017](_benchmarks/README_UNIX.md)_
|
||||||
<img src="https://comments.iris-go.com/comment33_2_mini.png" width="350px">
|
<img src="https://comments.iris-go.com/comment33_2_mini.png" width="350px">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="https://twitter.com/sgryphon/status/912073318928232448">
|
|
||||||
<img src="https://comments.iris-go.com/comment40.png" width="350px">
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a href="https://twitter.com/ferarias/status/902468752364773376">
|
<a href="https://twitter.com/ferarias/status/902468752364773376">
|
||||||
<img src="https://comments.iris-go.com/comment41.png" width="350px">
|
<img src="https://comments.iris-go.com/comment41.png" width="350px">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
For more information about contributing to the Iris project please check the [CONTRIBUTING.md](CONTRIBUTING.md) file.
|
> For more information about contributing to the Iris project please check the [CONTRIBUTING.md](CONTRIBUTING.md) file.
|
||||||
|
|
||||||
[List of all Contributors](https://github.com/kataras/iris/graphs/contributors)
|
[List of all Contributors](https://github.com/kataras/iris/graphs/contributors)
|
||||||
|
|
||||||
|
@ -103,6 +100,7 @@ First of all, the most correct way to begin with a web framework is to learn the
|
||||||
|
|
||||||
### Iris starter kits
|
### Iris starter kits
|
||||||
|
|
||||||
|
<!-- table form
|
||||||
| Description | Link |
|
| Description | Link |
|
||||||
| -----------|-------------|
|
| -----------|-------------|
|
||||||
| Hasura hub starter project with a ready to deploy golang helloworld webapp with IRIS! | https://hasura.io/hub/project/hasura/hello-golang-iris |
|
| Hasura hub starter project with a ready to deploy golang helloworld webapp with IRIS! | https://hasura.io/hub/project/hasura/hello-golang-iris |
|
||||||
|
@ -113,6 +111,16 @@ First of all, the most correct way to begin with a web framework is to learn the
|
||||||
| Self-hosted Localization Management Platform built with Iris and Angular | https://github.com/iris-contrib/parrot |
|
| Self-hosted Localization Management Platform built with Iris and Angular | https://github.com/iris-contrib/parrot |
|
||||||
| Iris + Docker and Kubernetes | https://github.com/iris-contrib/cloud-native-go |
|
| Iris + Docker and Kubernetes | https://github.com/iris-contrib/cloud-native-go |
|
||||||
| Quickstart for Iris with Nanobox | https://guides.nanobox.io/golang/iris/from-scratch |
|
| Quickstart for Iris with Nanobox | https://guides.nanobox.io/golang/iris/from-scratch |
|
||||||
|
-->
|
||||||
|
|
||||||
|
1. [A basic web app built in Iris for Go](https://github.com/gauravtiwari/go_iris_app)
|
||||||
|
2. [A mini social-network created with the awesome Iris💖💖](https://github.com/iris-contrib/Iris-Mini-Social-Network)
|
||||||
|
3. [Iris isomorphic react/hot reloadable/redux/css-modules starter kit](https://github.com/iris-contrib/iris-starter-kit)
|
||||||
|
4. [Demo project with react using typescript and Iris](https://github.com/ionutvilie/react-ts)
|
||||||
|
5. [Self-hosted Localization Management Platform built with Iris and Angular](https://github.com/iris-contrib/parrot)
|
||||||
|
6. [Iris + Docker and Kubernetes](https://github.com/iris-contrib/cloud-native-go)
|
||||||
|
7. [Quickstart for Iris with Nanobox](https://guides.nanobox.io/golang/iris/from-scratch)
|
||||||
|
8. [A Hasura starter project with a ready to deploy Golang hello-world web app with IRIS](https://hasura.io/hub/project/hasura/hello-golang-iris)
|
||||||
|
|
||||||
> Did you build something similar? Let us [know](https://github.com/kataras/iris/pulls)!
|
> Did you build something similar? Let us [know](https://github.com/kataras/iris/pulls)!
|
||||||
|
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
8.5.8:https://github.com/kataras/iris/blob/master/HISTORY.md#th-09-november-2017--v858
|
10.0.0:https://github.com/kataras/iris/blob/master/HISTORY.md#mo-01-jenuary-2018--v1000
|
|
@ -112,6 +112,11 @@ Navigate through examples for a better understanding.
|
||||||
* [per-route](routing/writing-a-middleware/per-route/main.go)
|
* [per-route](routing/writing-a-middleware/per-route/main.go)
|
||||||
* [globally](routing/writing-a-middleware/globally/main.go)
|
* [globally](routing/writing-a-middleware/globally/main.go)
|
||||||
|
|
||||||
|
### hero
|
||||||
|
|
||||||
|
- [Basic](hero/basic/main.go)
|
||||||
|
- [Overview](hero/overview)
|
||||||
|
|
||||||
### MVC
|
### MVC
|
||||||
|
|
||||||
![](mvc/web_mvc_diagram.png)
|
![](mvc/web_mvc_diagram.png)
|
||||||
|
@ -313,7 +318,8 @@ You can serve [quicktemplate](https://github.com/valyala/quicktemplate) and [her
|
||||||
|
|
||||||
- [Bind JSON](http_request/read-json/main.go)
|
- [Bind JSON](http_request/read-json/main.go)
|
||||||
- [Bind Form](http_request/read-form/main.go)
|
- [Bind Form](http_request/read-form/main.go)
|
||||||
- [Upload/Read Files](http_request/upload-files/main.go)
|
- [Upload/Read File](http_request/upload-file/main.go)
|
||||||
|
- [Upload multiple files with an easy way](http_request/upload-files/main.go)
|
||||||
|
|
||||||
> The `context.Request()` returns the same *http.Request you already know, these examples show some places where the Context uses this object. Besides that you can use it as you did before iris.
|
> The `context.Request()` returns the same *http.Request you already know, these examples show some places where the Context uses this object. Besides that you can use it as you did before iris.
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,6 @@
|
||||||
|
|
||||||
![](https://github.com/kataras/explore/raw/master/iris/hero/hero-2-monokai.png)
|
![](https://github.com/kataras/explore/raw/master/iris/hero/hero-2-monokai.png)
|
||||||
|
|
||||||
## References
|
## 3. Per-Request - Dynamic Dependencies
|
||||||
|
|
||||||
- [explore](https://github.com/kataras/explore)
|
![](https://github.com/kataras/explore/raw/master/iris/hero/hero-3-monokai.png)
|
73
_examples/http_request/upload-file/main.go
Normal file
73
_examples/http_request/upload-file/main.go
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/kataras/iris"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := iris.New()
|
||||||
|
|
||||||
|
app.RegisterView(iris.HTML("./templates", ".html"))
|
||||||
|
|
||||||
|
// Serve the upload_form.html to the client.
|
||||||
|
app.Get("/upload", func(ctx iris.Context) {
|
||||||
|
// create a token (optionally).
|
||||||
|
|
||||||
|
now := time.Now().Unix()
|
||||||
|
h := md5.New()
|
||||||
|
io.WriteString(h, strconv.FormatInt(now, 10))
|
||||||
|
token := fmt.Sprintf("%x", h.Sum(nil))
|
||||||
|
|
||||||
|
// render the form with the token for any use you'd like.
|
||||||
|
// ctx.ViewData("", token)
|
||||||
|
// or add second argument to the `View` method.
|
||||||
|
// Token will be passed as {{.}} in the template.
|
||||||
|
ctx.View("upload_form.html", token)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Handle the post request from the upload_form.html to the server
|
||||||
|
app.Post("/upload", func(ctx iris.Context) {
|
||||||
|
// iris.LimitRequestBodySize(32 <<20) as middleware to a route
|
||||||
|
// or use ctx.SetMaxRequestBodySize(32 << 20)
|
||||||
|
// to limit the whole request body size,
|
||||||
|
//
|
||||||
|
// or let the configuration option at app.Run for global setting
|
||||||
|
// for POST/PUT methods, including uploads of course.
|
||||||
|
|
||||||
|
// Get the file from the request.
|
||||||
|
file, info, err := ctx.FormFile("uploadfile")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ctx.StatusCode(iris.StatusInternalServerError)
|
||||||
|
ctx.HTML("Error while uploading: <b>" + err.Error() + "</b>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer file.Close()
|
||||||
|
fname := info.Filename
|
||||||
|
|
||||||
|
// Create a file with the same name
|
||||||
|
// assuming that you have a folder named 'uploads'
|
||||||
|
out, err := os.OpenFile("./uploads/"+fname,
|
||||||
|
os.O_WRONLY|os.O_CREATE, 0666)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ctx.StatusCode(iris.StatusInternalServerError)
|
||||||
|
ctx.HTML("Error while uploading: <b>" + err.Error() + "</b>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer out.Close()
|
||||||
|
|
||||||
|
io.Copy(out, file)
|
||||||
|
})
|
||||||
|
|
||||||
|
// start the server at http://localhost:8080 with post limit at 32 MB.
|
||||||
|
app.Run(iris.Addr(":8080"), iris.WithPostMaxMemory(32<<20))
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Upload file</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form enctype="multipart/form-data"
|
||||||
|
action="http://127.0.0.1:8080/upload" method="POST">
|
||||||
|
<input type="file" name="uploadfile" /> <input type="hidden"
|
||||||
|
name="token" value="{{.}}" /> <input type="submit" value="upload" />
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
0
_examples/http_request/upload-file/uploads/.gitkeep
Normal file
0
_examples/http_request/upload-file/uploads/.gitkeep
Normal file
|
@ -4,8 +4,9 @@ import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"mime/multipart"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kataras/iris"
|
"github.com/kataras/iris"
|
||||||
|
@ -26,46 +27,39 @@ func main() {
|
||||||
token := fmt.Sprintf("%x", h.Sum(nil))
|
token := fmt.Sprintf("%x", h.Sum(nil))
|
||||||
|
|
||||||
// render the form with the token for any use you'd like.
|
// render the form with the token for any use you'd like.
|
||||||
ctx.ViewData("", token)
|
ctx.View("upload_form.html", token)
|
||||||
ctx.View("upload_form.html")
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Handle the post request from the upload_form.html to the server
|
// Handle the post request from the upload_form.html to the server.
|
||||||
app.Post("/upload", func(ctx iris.Context) {
|
app.Post("/upload", func(ctx iris.Context) {
|
||||||
// iris.LimitRequestBodySize(32 <<20) as middleware to a route
|
|
||||||
// or use ctx.SetMaxRequestBodySize(32 << 20)
|
|
||||||
// to limit the whole request body size,
|
|
||||||
//
|
//
|
||||||
// or let the configuration option at app.Run for global setting
|
// UploadFormFiles
|
||||||
// for POST/PUT methods, including uploads of course.
|
// uploads any number of incoming files (multiple property on the form input).
|
||||||
|
//
|
||||||
|
|
||||||
// Get the file from the request.
|
// second argument is totally optionally,
|
||||||
file, info, err := ctx.FormFile("uploadfile")
|
// it can be used to change a file's name based on the request,
|
||||||
|
// at this example we will showcase how to use it
|
||||||
if err != nil {
|
// by prefixing the uploaded file with the current user's ip.
|
||||||
ctx.StatusCode(iris.StatusInternalServerError)
|
ctx.UploadFormFiles("./uploads", beforeSave)
|
||||||
ctx.HTML("Error while uploading: <b>" + err.Error() + "</b>")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
defer file.Close()
|
|
||||||
fname := info.Filename
|
|
||||||
|
|
||||||
// Create a file with the same name
|
|
||||||
// assuming that you have a folder named 'uploads'
|
|
||||||
out, err := os.OpenFile("./uploads/"+fname,
|
|
||||||
os.O_WRONLY|os.O_CREATE, 0666)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
ctx.StatusCode(iris.StatusInternalServerError)
|
|
||||||
ctx.HTML("Error while uploading: <b>" + err.Error() + "</b>")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer out.Close()
|
|
||||||
|
|
||||||
io.Copy(out, file)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// start the server at http://localhost:8080 with post limit at 32 MB.
|
// start the server at http://localhost:8080 with post limit at 32 MB.
|
||||||
app.Run(iris.Addr(":8080"), iris.WithPostMaxMemory(32<<20))
|
app.Run(iris.Addr(":8080"), iris.WithPostMaxMemory(32<<20))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func beforeSave(ctx iris.Context, file *multipart.FileHeader) {
|
||||||
|
ip := ctx.RemoteAddr()
|
||||||
|
// make sure you format the ip in a way
|
||||||
|
// that can be used for a file name (simple case):
|
||||||
|
ip = strings.Replace(ip, ".", "_", -1)
|
||||||
|
ip = strings.Replace(ip, ":", "_", -1)
|
||||||
|
|
||||||
|
// you can use the time.Now, to prefix or suffix the files
|
||||||
|
// based on the current time as well, as an exercise.
|
||||||
|
// i.e unixTime := time.Now().Unix()
|
||||||
|
// prefix the Filename with the $IP-
|
||||||
|
// no need for more actions, internal uploader will use this
|
||||||
|
// name to save the file into the "./uploads" folder.
|
||||||
|
file.Filename = ip + "-" + file.Filename
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<body>
|
<body>
|
||||||
<form enctype="multipart/form-data"
|
<form enctype="multipart/form-data"
|
||||||
action="http://127.0.0.1:8080/upload" method="POST">
|
action="http://127.0.0.1:8080/upload" method="POST">
|
||||||
<input type="file" name="uploadfile" /> <input type="hidden"
|
<input type="file" name="uploadfile" multiple/> <input type="hidden"
|
||||||
name="token" value="{{.}}" /> <input type="submit" value="upload" />
|
name="token" value="{{.}}" /> <input type="submit" value="upload" />
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -5,9 +5,11 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
//line base.qtpl:3
|
//line base.qtpl:3
|
||||||
|
|
||||||
package templates
|
package templates
|
||||||
|
|
||||||
//line base.qtpl:3
|
//line base.qtpl:3
|
||||||
|
|
||||||
import (
|
import (
|
||||||
qtio422016 "io"
|
qtio422016 "io"
|
||||||
|
|
||||||
|
@ -15,12 +17,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
//line base.qtpl:3
|
//line base.qtpl:3
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_ = qtio422016.Copy
|
_ = qtio422016.Copy
|
||||||
_ = qt422016.AcquireByteBuffer
|
_ = qt422016.AcquireByteBuffer
|
||||||
)
|
)
|
||||||
|
|
||||||
//line base.qtpl:4
|
//line base.qtpl:4
|
||||||
|
|
||||||
type Partial interface {
|
type Partial interface {
|
||||||
//line base.qtpl:4
|
//line base.qtpl:4
|
||||||
Body() string
|
Body() string
|
||||||
|
@ -29,11 +33,13 @@ type Partial interface {
|
||||||
//line base.qtpl:4
|
//line base.qtpl:4
|
||||||
WriteBody(qq422016 qtio422016.Writer)
|
WriteBody(qq422016 qtio422016.Writer)
|
||||||
//line base.qtpl:4
|
//line base.qtpl:4
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Template writes a template implementing the Partial interface.
|
// Template writes a template implementing the Partial interface.
|
||||||
|
|
||||||
//line base.qtpl:11
|
//line base.qtpl:11
|
||||||
|
|
||||||
func StreamTemplate(qw422016 *qt422016.Writer, p Partial) {
|
func StreamTemplate(qw422016 *qt422016.Writer, p Partial) {
|
||||||
//line base.qtpl:11
|
//line base.qtpl:11
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
|
@ -61,9 +67,11 @@ func StreamTemplate(qw422016 *qt422016.Writer, p Partial) {
|
||||||
</html>
|
</html>
|
||||||
`)
|
`)
|
||||||
//line base.qtpl:30
|
//line base.qtpl:30
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//line base.qtpl:30
|
//line base.qtpl:30
|
||||||
|
|
||||||
func WriteTemplate(qq422016 qtio422016.Writer, p Partial) {
|
func WriteTemplate(qq422016 qtio422016.Writer, p Partial) {
|
||||||
//line base.qtpl:30
|
//line base.qtpl:30
|
||||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||||
|
@ -72,9 +80,11 @@ func WriteTemplate(qq422016 qtio422016.Writer, p Partial) {
|
||||||
//line base.qtpl:30
|
//line base.qtpl:30
|
||||||
qt422016.ReleaseWriter(qw422016)
|
qt422016.ReleaseWriter(qw422016)
|
||||||
//line base.qtpl:30
|
//line base.qtpl:30
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//line base.qtpl:30
|
//line base.qtpl:30
|
||||||
|
|
||||||
func Template(p Partial) string {
|
func Template(p Partial) string {
|
||||||
//line base.qtpl:30
|
//line base.qtpl:30
|
||||||
qb422016 := qt422016.AcquireByteBuffer()
|
qb422016 := qt422016.AcquireByteBuffer()
|
||||||
|
@ -87,21 +97,27 @@ func Template(p Partial) string {
|
||||||
//line base.qtpl:30
|
//line base.qtpl:30
|
||||||
return qs422016
|
return qs422016
|
||||||
//line base.qtpl:30
|
//line base.qtpl:30
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base template implementation. Other pages may inherit from it if they need
|
// Base template implementation. Other pages may inherit from it if they need
|
||||||
// overriding only certain Partial methods.
|
// overriding only certain Partial methods.
|
||||||
|
|
||||||
//line base.qtpl:35
|
//line base.qtpl:35
|
||||||
|
|
||||||
type Base struct{}
|
type Base struct{}
|
||||||
|
|
||||||
//line base.qtpl:36
|
//line base.qtpl:36
|
||||||
|
|
||||||
func (b *Base) StreamBody(qw422016 *qt422016.Writer) {
|
func (b *Base) StreamBody(qw422016 *qt422016.Writer) {
|
||||||
//line base.qtpl:36
|
//line base.qtpl:36
|
||||||
qw422016.N().S(`This is the base body`) }
|
|
||||||
|
qw422016.N().S(`This is the base body`)
|
||||||
|
}
|
||||||
|
|
||||||
//line base.qtpl:36
|
//line base.qtpl:36
|
||||||
//line base.qtpl:36
|
//line base.qtpl:36
|
||||||
|
|
||||||
func (b *Base) WriteBody(qq422016 qtio422016.Writer) {
|
func (b *Base) WriteBody(qq422016 qtio422016.Writer) {
|
||||||
//line base.qtpl:36
|
//line base.qtpl:36
|
||||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||||
|
@ -110,9 +126,11 @@ func (b *Base) WriteBody(qq422016 qtio422016.Writer) {
|
||||||
//line base.qtpl:36
|
//line base.qtpl:36
|
||||||
qt422016.ReleaseWriter(qw422016)
|
qt422016.ReleaseWriter(qw422016)
|
||||||
//line base.qtpl:36
|
//line base.qtpl:36
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//line base.qtpl:36
|
//line base.qtpl:36
|
||||||
|
|
||||||
func (b *Base) Body() string {
|
func (b *Base) Body() string {
|
||||||
//line base.qtpl:36
|
//line base.qtpl:36
|
||||||
qb422016 := qt422016.AcquireByteBuffer()
|
qb422016 := qt422016.AcquireByteBuffer()
|
||||||
|
@ -125,4 +143,5 @@ func (b *Base) Body() string {
|
||||||
//line base.qtpl:36
|
//line base.qtpl:36
|
||||||
return qs422016
|
return qs422016
|
||||||
//line base.qtpl:36
|
//line base.qtpl:36
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,11 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
//line hello.qtpl:3
|
//line hello.qtpl:3
|
||||||
|
|
||||||
package templates
|
package templates
|
||||||
|
|
||||||
//line hello.qtpl:3
|
//line hello.qtpl:3
|
||||||
|
|
||||||
import (
|
import (
|
||||||
qtio422016 "io"
|
qtio422016 "io"
|
||||||
|
|
||||||
|
@ -15,17 +17,20 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
//line hello.qtpl:3
|
//line hello.qtpl:3
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_ = qtio422016.Copy
|
_ = qtio422016.Copy
|
||||||
_ = qt422016.AcquireByteBuffer
|
_ = qt422016.AcquireByteBuffer
|
||||||
)
|
)
|
||||||
|
|
||||||
//line hello.qtpl:4
|
//line hello.qtpl:4
|
||||||
|
|
||||||
type Hello struct {
|
type Hello struct {
|
||||||
Vars map[string]interface{}
|
Vars map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//line hello.qtpl:9
|
//line hello.qtpl:9
|
||||||
|
|
||||||
func (h *Hello) StreamBody(qw422016 *qt422016.Writer) {
|
func (h *Hello) StreamBody(qw422016 *qt422016.Writer) {
|
||||||
//line hello.qtpl:9
|
//line hello.qtpl:9
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
|
@ -43,9 +48,11 @@ func (h *Hello) StreamBody(qw422016 *qt422016.Writer) {
|
||||||
</div>
|
</div>
|
||||||
`)
|
`)
|
||||||
//line hello.qtpl:14
|
//line hello.qtpl:14
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//line hello.qtpl:14
|
//line hello.qtpl:14
|
||||||
|
|
||||||
func (h *Hello) WriteBody(qq422016 qtio422016.Writer) {
|
func (h *Hello) WriteBody(qq422016 qtio422016.Writer) {
|
||||||
//line hello.qtpl:14
|
//line hello.qtpl:14
|
||||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||||
|
@ -54,9 +61,11 @@ func (h *Hello) WriteBody(qq422016 qtio422016.Writer) {
|
||||||
//line hello.qtpl:14
|
//line hello.qtpl:14
|
||||||
qt422016.ReleaseWriter(qw422016)
|
qt422016.ReleaseWriter(qw422016)
|
||||||
//line hello.qtpl:14
|
//line hello.qtpl:14
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//line hello.qtpl:14
|
//line hello.qtpl:14
|
||||||
|
|
||||||
func (h *Hello) Body() string {
|
func (h *Hello) Body() string {
|
||||||
//line hello.qtpl:14
|
//line hello.qtpl:14
|
||||||
qb422016 := qt422016.AcquireByteBuffer()
|
qb422016 := qt422016.AcquireByteBuffer()
|
||||||
|
@ -69,4 +78,5 @@ func (h *Hello) Body() string {
|
||||||
//line hello.qtpl:14
|
//line hello.qtpl:14
|
||||||
return qs422016
|
return qs422016
|
||||||
//line hello.qtpl:14
|
//line hello.qtpl:14
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,11 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
//line index.qtpl:3
|
//line index.qtpl:3
|
||||||
|
|
||||||
package templates
|
package templates
|
||||||
|
|
||||||
//line index.qtpl:3
|
//line index.qtpl:3
|
||||||
|
|
||||||
import (
|
import (
|
||||||
qtio422016 "io"
|
qtio422016 "io"
|
||||||
|
|
||||||
|
@ -15,15 +17,18 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
//line index.qtpl:3
|
//line index.qtpl:3
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_ = qtio422016.Copy
|
_ = qtio422016.Copy
|
||||||
_ = qt422016.AcquireByteBuffer
|
_ = qt422016.AcquireByteBuffer
|
||||||
)
|
)
|
||||||
|
|
||||||
//line index.qtpl:4
|
//line index.qtpl:4
|
||||||
|
|
||||||
type Index struct{}
|
type Index struct{}
|
||||||
|
|
||||||
//line index.qtpl:7
|
//line index.qtpl:7
|
||||||
|
|
||||||
func (i *Index) StreamBody(qw422016 *qt422016.Writer) {
|
func (i *Index) StreamBody(qw422016 *qt422016.Writer) {
|
||||||
//line index.qtpl:7
|
//line index.qtpl:7
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
|
@ -33,9 +38,11 @@ func (i *Index) StreamBody(qw422016 *qt422016.Writer) {
|
||||||
</div>
|
</div>
|
||||||
`)
|
`)
|
||||||
//line index.qtpl:12
|
//line index.qtpl:12
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//line index.qtpl:12
|
//line index.qtpl:12
|
||||||
|
|
||||||
func (i *Index) WriteBody(qq422016 qtio422016.Writer) {
|
func (i *Index) WriteBody(qq422016 qtio422016.Writer) {
|
||||||
//line index.qtpl:12
|
//line index.qtpl:12
|
||||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||||
|
@ -44,9 +51,11 @@ func (i *Index) WriteBody(qq422016 qtio422016.Writer) {
|
||||||
//line index.qtpl:12
|
//line index.qtpl:12
|
||||||
qt422016.ReleaseWriter(qw422016)
|
qt422016.ReleaseWriter(qw422016)
|
||||||
//line index.qtpl:12
|
//line index.qtpl:12
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//line index.qtpl:12
|
//line index.qtpl:12
|
||||||
|
|
||||||
func (i *Index) Body() string {
|
func (i *Index) Body() string {
|
||||||
//line index.qtpl:12
|
//line index.qtpl:12
|
||||||
qb422016 := qt422016.AcquireByteBuffer()
|
qb422016 := qt422016.AcquireByteBuffer()
|
||||||
|
@ -59,4 +68,5 @@ func (i *Index) Body() string {
|
||||||
//line index.qtpl:12
|
//line index.qtpl:12
|
||||||
return qs422016
|
return qs422016
|
||||||
//line index.qtpl:12
|
//line index.qtpl:12
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,12 @@ import (
|
||||||
func main() {
|
func main() {
|
||||||
app := iris.New()
|
app := iris.New()
|
||||||
app.Logger().SetLevel("debug")
|
app.Logger().SetLevel("debug")
|
||||||
mvc.Configure(app.Party("/todo"), TodoApp)
|
mvc.Configure(app.Party("/basic"), basicMVC)
|
||||||
|
|
||||||
app.Run(iris.Addr(":8080"))
|
app.Run(iris.Addr(":8080"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TodoApp(app *mvc.Application) {
|
func basicMVC(app *mvc.Application) {
|
||||||
// You can use normal middlewares at MVC apps of course.
|
// You can use normal middlewares at MVC apps of course.
|
||||||
app.Router.Use(func(ctx iris.Context) {
|
app.Router.Use(func(ctx iris.Context) {
|
||||||
ctx.Application().Logger().Infof("Path: %s", ctx.Path())
|
ctx.Application().Logger().Infof("Path: %s", ctx.Path())
|
||||||
|
@ -32,16 +32,16 @@ func TodoApp(app *mvc.Application) {
|
||||||
&prefixedLogger{prefix: "DEV"},
|
&prefixedLogger{prefix: "DEV"},
|
||||||
)
|
)
|
||||||
|
|
||||||
// GET: http://localhost:8080/todo
|
// GET: http://localhost:8080/basic
|
||||||
// GET: http://localhost:8080/todo/custom
|
// GET: http://localhost:8080/basic/custom
|
||||||
app.Handle(new(TodoController))
|
app.Handle(new(basicController))
|
||||||
|
|
||||||
// All dependencies of the parent *mvc.Application
|
// All dependencies of the parent *mvc.Application
|
||||||
// are cloned to this new child,
|
// are cloned to this new child,
|
||||||
// thefore it has access to the same session as well.
|
// thefore it has access to the same session as well.
|
||||||
// GET: http://localhost:8080/todo/sub
|
// GET: http://localhost:8080/basic/sub
|
||||||
app.Party("/sub").
|
app.Party("/sub").
|
||||||
Handle(new(TodoSubController))
|
Handle(new(basicSubController))
|
||||||
}
|
}
|
||||||
|
|
||||||
// If controller's fields (or even its functions) expecting an interface
|
// If controller's fields (or even its functions) expecting an interface
|
||||||
|
@ -64,39 +64,39 @@ func (s *prefixedLogger) Log(msg string) {
|
||||||
fmt.Printf("%s: %s\n", s.prefix, msg)
|
fmt.Printf("%s: %s\n", s.prefix, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
type TodoController struct {
|
type basicController struct {
|
||||||
Logger LoggerService
|
Logger LoggerService
|
||||||
|
|
||||||
Session *sessions.Session
|
Session *sessions.Session
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TodoController) BeforeActivation(b mvc.BeforeActivation) {
|
func (c *basicController) BeforeActivation(b mvc.BeforeActivation) {
|
||||||
b.Handle("GET", "/custom", "Custom")
|
b.Handle("GET", "/custom", "Custom")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TodoController) AfterActivation(a mvc.AfterActivation) {
|
func (c *basicController) AfterActivation(a mvc.AfterActivation) {
|
||||||
if a.Singleton() {
|
if a.Singleton() {
|
||||||
panic("TodoController should be stateless, a request-scoped, we have a 'Session' which depends on the context.")
|
panic("basicController should be stateless, a request-scoped, we have a 'Session' which depends on the context.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TodoController) Get() string {
|
func (c *basicController) Get() string {
|
||||||
count := c.Session.Increment("count", 1)
|
count := c.Session.Increment("count", 1)
|
||||||
|
|
||||||
body := fmt.Sprintf("Hello from TodoController\nTotal visits from you: %d", count)
|
body := fmt.Sprintf("Hello from basicController\nTotal visits from you: %d", count)
|
||||||
c.Logger.Log(body)
|
c.Logger.Log(body)
|
||||||
return body
|
return body
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TodoController) Custom() string {
|
func (c *basicController) Custom() string {
|
||||||
return "custom"
|
return "custom"
|
||||||
}
|
}
|
||||||
|
|
||||||
type TodoSubController struct {
|
type basicSubController struct {
|
||||||
Session *sessions.Session
|
Session *sessions.Session
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TodoSubController) Get() string {
|
func (c *basicSubController) Get() string {
|
||||||
count, _ := c.Session.GetIntDefault("count", 1)
|
count, _ := c.Session.GetIntDefault("count", 1)
|
||||||
return fmt.Sprintf("Hello from TodoSubController.\nRead-only visits count: %d", count)
|
return fmt.Sprintf("Hello from basicSubController.\nRead-only visits count: %d", count)
|
||||||
}
|
}
|
||||||
|
|
|
@ -318,7 +318,7 @@ func WithCharset(charset string) Configurator {
|
||||||
// WithPostMaxMemory sets the maximum post data size
|
// WithPostMaxMemory sets the maximum post data size
|
||||||
// that a client can send to the server, this differs
|
// that a client can send to the server, this differs
|
||||||
// from the overral request body size which can be modified
|
// from the overral request body size which can be modified
|
||||||
// by the `context#SetMaxRequestBodySize` or `iris#LimitRequestBodySize.
|
// by the `context#SetMaxRequestBodySize` or `iris#LimitRequestBodySize`.
|
||||||
//
|
//
|
||||||
// Defaults to 32MB or 32 << 20 if you prefer.
|
// Defaults to 32MB or 32 << 20 if you prefer.
|
||||||
func WithPostMaxMemory(limit int64) Configurator {
|
func WithPostMaxMemory(limit int64) Configurator {
|
||||||
|
@ -478,7 +478,7 @@ type Configuration struct {
|
||||||
// PostMaxMemory sets the maximum post data size
|
// PostMaxMemory sets the maximum post data size
|
||||||
// that a client can send to the server, this differs
|
// that a client can send to the server, this differs
|
||||||
// from the overral request body size which can be modified
|
// from the overral request body size which can be modified
|
||||||
// by the `context#SetMaxRequestBodySize` or `iris#LimitRequestBodySize.
|
// by the `context#SetMaxRequestBodySize` or `iris#LimitRequestBodySize`.
|
||||||
//
|
//
|
||||||
// Defaults to 32MB or 32 << 20 if you prefer.
|
// Defaults to 32MB or 32 << 20 if you prefer.
|
||||||
PostMaxMemory int64 `json:"postMaxMemory" yaml:"PostMaxMemory" toml:"PostMaxMemory"`
|
PostMaxMemory int64 `json:"postMaxMemory" yaml:"PostMaxMemory" toml:"PostMaxMemory"`
|
||||||
|
@ -601,7 +601,7 @@ func (c Configuration) GetCharset() string {
|
||||||
// GetPostMaxMemory returns the maximum configured post data size
|
// GetPostMaxMemory returns the maximum configured post data size
|
||||||
// that a client can send to the server, this differs
|
// that a client can send to the server, this differs
|
||||||
// from the overral request body size which can be modified
|
// from the overral request body size which can be modified
|
||||||
// by the `context#SetMaxRequestBodySize` or `iris#LimitRequestBodySize.
|
// by the `context#SetMaxRequestBodySize` or `iris#LimitRequestBodySize`.
|
||||||
//
|
//
|
||||||
// Defaults to 32MB or 32 << 20 if you prefer.
|
// Defaults to 32MB or 32 << 20 if you prefer.
|
||||||
func (c Configuration) GetPostMaxMemory() int64 {
|
func (c Configuration) GetPostMaxMemory() int64 {
|
||||||
|
|
|
@ -57,7 +57,7 @@ type ConfigurationReadOnly interface {
|
||||||
// GetPostMaxMemory returns the maximum configured post data size
|
// GetPostMaxMemory returns the maximum configured post data size
|
||||||
// that a client can send to the server, this differs
|
// that a client can send to the server, this differs
|
||||||
// from the overral request body size which can be modified
|
// from the overral request body size which can be modified
|
||||||
// by the `context#SetMaxRequestBodySize` or `iris#LimitRequestBodySize.
|
// by the `context#SetMaxRequestBodySize` or `iris#LimitRequestBodySize`.
|
||||||
//
|
//
|
||||||
// Defaults to 32MB or 32 << 20 if you prefer.
|
// Defaults to 32MB or 32 << 20 if you prefer.
|
||||||
GetPostMaxMemory() int64
|
GetPostMaxMemory() int64
|
||||||
|
|
|
@ -551,7 +551,13 @@ type Context interface {
|
||||||
FormFile(key string) (multipart.File, *multipart.FileHeader, error)
|
FormFile(key string) (multipart.File, *multipart.FileHeader, error)
|
||||||
// UploadFormFiles uploads any received file(s) from the client
|
// UploadFormFiles uploads any received file(s) from the client
|
||||||
// to the system physical location "destDirectory".
|
// to the system physical location "destDirectory".
|
||||||
// The root directory must already exists.
|
//
|
||||||
|
// The second optional argument "before" gives caller the chance to
|
||||||
|
// modify the *miltipart.FileHeader before saving to the disk,
|
||||||
|
// it can be used to change a file's name based on the current request,
|
||||||
|
// all FileHeader's options can be changed. You can ignore it if
|
||||||
|
// you don't need to use this capability before saving a file to the disk.
|
||||||
|
//
|
||||||
// Note that it doesn't check if request body streamed.
|
// Note that it doesn't check if request body streamed.
|
||||||
//
|
//
|
||||||
// Returns the copied length as int64 and
|
// Returns the copied length as int64 and
|
||||||
|
@ -564,7 +570,10 @@ type Context interface {
|
||||||
//
|
//
|
||||||
// The default form's memory maximum size is 32MB, it can be changed by the
|
// The default form's memory maximum size is 32MB, it can be changed by the
|
||||||
// `iris#WithPostMaxMemory` configurator at main configuration passed on `app.Run`'s second argument.
|
// `iris#WithPostMaxMemory` configurator at main configuration passed on `app.Run`'s second argument.
|
||||||
UploadFormFiles(destDirectory string) (int64, error)
|
//
|
||||||
|
// See `FormFile` to a more controlled to receive a file.
|
||||||
|
UploadFormFiles(destDirectory string, before ...func(Context, *multipart.FileHeader)) (n int64, err error)
|
||||||
|
|
||||||
// +------------------------------------------------------------+
|
// +------------------------------------------------------------+
|
||||||
// | Custom HTTP Errors |
|
// | Custom HTTP Errors |
|
||||||
// +------------------------------------------------------------+
|
// +------------------------------------------------------------+
|
||||||
|
@ -1780,7 +1789,12 @@ func (ctx *context) FormFile(key string) (multipart.File, *multipart.FileHeader,
|
||||||
|
|
||||||
// UploadFormFiles uploads any received file(s) from the client
|
// UploadFormFiles uploads any received file(s) from the client
|
||||||
// to the system physical location "destDirectory".
|
// to the system physical location "destDirectory".
|
||||||
// The root directory must already exists.
|
//
|
||||||
|
// The second optional argument "before" gives caller the chance to
|
||||||
|
// modify the *miltipart.FileHeader before saving to the disk,
|
||||||
|
// it can be used to change a file's name based on the current request,
|
||||||
|
// all FileHeader's options can be changed. You can ignore it if
|
||||||
|
// you don't need to use this capability before saving a file to the disk.
|
||||||
//
|
//
|
||||||
// Note that it doesn't check if request body streamed.
|
// Note that it doesn't check if request body streamed.
|
||||||
//
|
//
|
||||||
|
@ -1794,7 +1808,9 @@ func (ctx *context) FormFile(key string) (multipart.File, *multipart.FileHeader,
|
||||||
//
|
//
|
||||||
// The default form's memory maximum size is 32MB, it can be changed by the
|
// The default form's memory maximum size is 32MB, it can be changed by the
|
||||||
// `iris#WithPostMaxMemory` configurator at main configuration passed on `app.Run`'s second argument.
|
// `iris#WithPostMaxMemory` configurator at main configuration passed on `app.Run`'s second argument.
|
||||||
func (ctx *context) UploadFormFiles(destDirectory string) (n int64, err error) {
|
//
|
||||||
|
// See `FormFile` to a more controlled to receive a file.
|
||||||
|
func (ctx *context) UploadFormFiles(destDirectory string, before ...func(Context, *multipart.FileHeader)) (n int64, err error) {
|
||||||
err = ctx.request.ParseMultipartForm(ctx.Application().ConfigurationReadOnly().GetPostMaxMemory())
|
err = ctx.request.ParseMultipartForm(ctx.Application().ConfigurationReadOnly().GetPostMaxMemory())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -1804,6 +1820,11 @@ func (ctx *context) UploadFormFiles(destDirectory string) (n int64, err error) {
|
||||||
if fhs := ctx.request.MultipartForm.File; fhs != nil {
|
if fhs := ctx.request.MultipartForm.File; fhs != nil {
|
||||||
for _, files := range fhs {
|
for _, files := range fhs {
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
|
|
||||||
|
for _, b := range before {
|
||||||
|
b(ctx, file)
|
||||||
|
}
|
||||||
|
|
||||||
n0, err0 := uploadTo(file, destDirectory)
|
n0, err0 := uploadTo(file, destDirectory)
|
||||||
if err0 != nil {
|
if err0 != nil {
|
||||||
return 0, err0
|
return 0, err0
|
||||||
|
@ -1824,7 +1845,9 @@ func uploadTo(fh *multipart.FileHeader, destDirectory string) (int64, error) {
|
||||||
}
|
}
|
||||||
defer src.Close()
|
defer src.Close()
|
||||||
|
|
||||||
out, err := os.Create(filepath.Join(destDirectory, fh.Filename))
|
out, err := os.OpenFile(filepath.Join(destDirectory, fh.Filename),
|
||||||
|
os.O_WRONLY|os.O_CREATE, os.FileMode(0666))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Version is the string representation of the current local Iris Web Framework version.
|
// Version is the string representation of the current local Iris Web Framework version.
|
||||||
Version = "8.5.8"
|
Version = "10.0.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CheckForUpdates checks for any available updates
|
// CheckForUpdates checks for any available updates
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
// https://github.com/kataras/iris/blob/master/HISTORY.md#mo-01-jenuary-2018--v10
|
// https://github.com/kataras/iris/blob/master/HISTORY.md#mo-01-jenuary-2018--v10
|
||||||
func (app *Application) Controller(relPath string, c interface{}, _ ...interface{}) []*router.Route {
|
func (app *Application) Controller(relPath string, c interface{}, _ ...interface{}) []*router.Route {
|
||||||
name := mvc.NameOf(c)
|
name := mvc.NameOf(c)
|
||||||
|
|
||||||
panic(fmt.Errorf(`"Controller" method is DEPRECATED, use the "mvc" subpackage instead.
|
panic(fmt.Errorf(`"Controller" method is DEPRECATED, use the "mvc" subpackage instead.
|
||||||
|
|
||||||
PREVIOUSLY YOU USED TO CODE IT LIKE THIS:
|
PREVIOUSLY YOU USED TO CODE IT LIKE THIS:
|
||||||
|
|
4
doc.go
4
doc.go
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2017 The Iris Authors. All rights reserved.
|
// Copyright (c) 2017-2018 The Iris Authors. All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -35,7 +35,7 @@ Source code and other details for the project are available at GitHub:
|
||||||
|
|
||||||
Current Version
|
Current Version
|
||||||
|
|
||||||
8.5.8
|
10.0.0
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user