Update to version 8.5.5 | Read HISTORY.md

Former-commit-id: dced7d472edabbab4f80c76051f13261928a8dea
This commit is contained in:
kataras 2017-11-02 05:54:33 +02:00
parent 666bcacf20
commit 15feaf0237
100 changed files with 13338 additions and 13155 deletions

6
.gitattributes vendored
View File

@ -1,4 +1,4 @@
*.go linguist-language=Go *.go linguist-language=Go
vendor/* linguist-vendored vendor/* linguist-vendored
_examples/* linguist-documentation _examples/* linguist-documentation
_benchmarks/* linguist-documentation _benchmarks/* linguist-documentation

4
.github/CODEOWNERS vendored
View File

@ -1,2 +1,2 @@
# These owners will be the default owners for everything in the repo. # These owners will be the default owners for everything in the repo.
* @kataras * @kataras

View File

@ -1,5 +1,5 @@
Documentation for the Iris project can be found at Documentation for the Iris project can be found at
<https://github.com/kataras/iris#learn>. <https://github.com/kataras/iris#learn>.
Want to contribute to the Iris project? Want to contribute to the Iris project?
<https://github.com/kataras/blob/master/CONTRIBUTING.md> <https://github.com/kataras/blob/master/CONTRIBUTING.md>

View File

@ -1,5 +1,5 @@
# We'd love to see more contributions # We'd love to see more contributions
Read how you can [contribute to the project](https://github.com/kataras/blob/master/CONTRIBUTING.md). Read how you can [contribute to the project](https://github.com/kataras/blob/master/CONTRIBUTING.md).
> Please attach an [issue](https://github.com/kataras/iris/issues) link which your PR solves otherwise your work may be rejected. > Please attach an [issue](https://github.com/kataras/iris/issues) link which your PR solves otherwise your work may be rejected.

View File

@ -1,25 +1,25 @@
language: go language: go
os: os:
- linux - linux
- osx - osx
go: go:
# - go1.8 works of course but # - go1.8 works of course but
# we must encourage users to update to the latest go version, # we must encourage users to update to the latest go version,
# so examples are running on go 1.9 mode. # so examples are running on go 1.9 mode.
- go1.9 - go1.9
# - tip # - tip
go_import_path: github.com/kataras/iris go_import_path: github.com/kataras/iris
install: install:
- go get ./... # for iris-contrib/httpexpect, kataras/golog, boltdb/bolt(sessiondb, optional) - go get ./... # for iris-contrib/httpexpect, kataras/golog, kataras/signal
script: script:
- go test -v -cover ./... - go test -v -cover ./...
after_script: after_script:
# examples # examples
- cd ./_examples - cd ./_examples
- go get ./... - go get ./...
- go test -v -cover ./... - go test -v -cover ./...
- cd ../ - cd ../
# typescript examples # typescript examples
- cd ./typescript/_examples - cd ./typescript/_examples
- go get ./... - go get ./...
- go test -v -cover ./... - go test -v -cover ./...

View File

@ -1,4 +1,4 @@
# This is the official list of Iris authors for copyright # This is the official list of Iris authors for copyright
# purposes. # purposes.
Gerasimos Maropoulos <kataras2006@hotmail.com> Gerasimos Maropoulos <kataras2006@hotmail.com>

View File

@ -1,74 +1,74 @@
# Contributor Covenant Code of Conduct # Contributor Covenant Code of Conduct
## Our Pledge ## Our Pledge
In the interest of fostering an open and welcoming environment, we as In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience, size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and nationality, personal appearance, race, religion, or sexual identity and
orientation. orientation.
## Our Standards ## Our Standards
Examples of behavior that contributes to creating a positive environment Examples of behavior that contributes to creating a positive environment
include: include:
* Using welcoming and inclusive language * Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences * Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism * Gracefully accepting constructive criticism
* Focusing on what is best for the community * Focusing on what is best for the community
* Showing empathy towards other community members * Showing empathy towards other community members
Examples of unacceptable behavior by participants include: Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or * The use of sexualized language or imagery and unwelcome sexual attention or
advances advances
* Trolling, insulting/derogatory comments, and personal or political attacks * Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment * Public or private harassment
* Publishing others' private information, such as a physical or electronic * Publishing others' private information, such as a physical or electronic
address, without explicit permission address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a * Other conduct which could reasonably be considered inappropriate in a
professional setting professional setting
## Our Responsibilities ## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior. response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate, permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful. threatening, offensive, or harmful.
## Scope ## Scope
This Code of Conduct applies both within project spaces and in public spaces This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers. further defined and clarified by project maintainers.
## Enforcement ## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at kataras2006@hotmail.com. All reported by contacting the project team at kataras2006@hotmail.com. All
complaints will be reviewed and investigated and will result in a response that complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident. obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other faith may face temporary or permanent repercussions as determined by other
members of the project's leadership. members of the project's leadership.
## Attribution ## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version] available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org [homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/ [version]: http://contributor-covenant.org/version/1/4/

View File

@ -1,74 +1,74 @@
# Contributing # Contributing
First of all read our [Code of Conduct](https://github.com/kataras/iris/tree/master/CODE_OF_CONDUCT.md). First of all read our [Code of Conduct](https://github.com/kataras/iris/tree/master/CODE_OF_CONDUCT.md).
## PR ## PR
1. Open a new [issue](https://github.com/kataras/iris/issues/new) 1. Open a new [issue](https://github.com/kataras/iris/issues/new)
* Write version of your local Iris. * Write version of your local Iris.
* Write version of your local Go programming language. * Write version of your local Go programming language.
* Describe your problem, what did you expect to see and what you see instead. * Describe your problem, what did you expect to see and what you see instead.
* If it's a feature request, describe your idea as better as you can * If it's a feature request, describe your idea as better as you can
* optionally, navigate to the [chat](https://kataras.rocket.chat/channel/iris) to push other members to participate and share their thoughts about your brilliant idea. * optionally, navigate to the [chat](https://kataras.rocket.chat/channel/iris) to push other members to participate and share their thoughts about your brilliant idea.
2. Fork the [repository](https://github.com/kataras/iris). 2. Fork the [repository](https://github.com/kataras/iris).
3. Make your changes. 3. Make your changes.
4. Compare & Push the PR from [here](https://github.com/kataras/iris/compare). 4. Compare & Push the PR from [here](https://github.com/kataras/iris/compare).
## Donate ## Donate
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) or [BTC](https://iris-go.com/v8/donate)! 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) or [BTC](https://iris-go.com/v8/donate)!
| Name | Amount | Membership | | Name | Amount | Membership |
| -----------|--------|--------| | -----------|--------|--------|
| [Juan Sebastián Suárez Valencia](https://github.com/Juanses) | 20 EUR | Bronze | | [Juan Sebastián Suárez Valencia](https://github.com/Juanses) | 20 EUR | Bronze |
| [Bob Lee](https://github.com/li3p) | 20 EUR | Bronze | | [Bob Lee](https://github.com/li3p) | 20 EUR | Bronze |
| [Celso Luiz](https://github.com/celsosz) | 50 EUR | **Silver** | | [Celso Luiz](https://github.com/celsosz) | 50 EUR | **Silver** |
| [Ankur Srivastava](https://github.com/ansrivas) | 20 EUR | Bronze | | [Ankur Srivastava](https://github.com/ansrivas) | 20 EUR | Bronze |
| [Damon Zhao](https://github.com/se77en) | 20 EUR | Bronze | | [Damon Zhao](https://github.com/se77en) | 20 EUR | Bronze |
| [Exponity - Tech Company](https://github.com/exponity) | 30 EUR | Bronze | | [Exponity - Tech Company](https://github.com/exponity) | 30 EUR | Bronze |
| [Thomas Fritz](https://github.com/thomasfr) | 25 EUR | Bronze | | [Thomas Fritz](https://github.com/thomasfr) | 25 EUR | Bronze |
| [Thanos V.](http://mykonosbiennale.com/) | 20 EUR | Bronze | | [Thanos V.](http://mykonosbiennale.com/) | 20 EUR | Bronze |
| [George Opritescu](https://github.com/International) | 20 EUR | Bronze | | [George Opritescu](https://github.com/International) | 20 EUR | Bronze |
| [Lex Tang](https://github.com/lexrus) | 20 EUR | Bronze | | [Lex Tang](https://github.com/lexrus) | 20 EUR | Bronze |
| [Bill Q.](https://github.com/hiveminded) | 600 EUR | **Gold** | | [Bill Q.](https://github.com/hiveminded) | 600 EUR | **Gold** |
| [Conrad Steenberg](https://github.com/hengestone) | 25 EUR | Bronze | | [Conrad Steenberg](https://github.com/hengestone) | 25 EUR | Bronze |
## Translate ## Translate
We need your help with translations into your native language. We need your help with translations into your native language.
Iris needs your help, please think about contributing to the translation of the [README](README.md) and https://iris-go.com, you will be rewarded. Iris needs your help, please think about contributing to the translation of the [README](README.md) and https://iris-go.com, you will be rewarded.
Instructions can be found at: https://github.com/kataras/iris/issues/796 Instructions can be found at: https://github.com/kataras/iris/issues/796
## Share ## Share
### Writing ### Writing
Write an article about Iris in https://medium.com , https://dev.to or if you're being a hackathon at https://hackernoon.com, some examples: Write an article about Iris in https://medium.com , https://dev.to or if you're being a hackathon at https://hackernoon.com, some examples:
* [How to build a file upload form using DropzoneJS and Go](https://hackernoon.com/how-to-build-a-file-upload-form-using-dropzonejs-and-go-8fb9f258a991) * [How to build a file upload form using DropzoneJS and Go](https://hackernoon.com/how-to-build-a-file-upload-form-using-dropzonejs-and-go-8fb9f258a991)
* [How to display existing files on server using DropzoneJS and Go](https://hackernoon.com/how-to-display-existing-files-on-server-using-dropzonejs-and-go-53e24b57ba19) * [How to display existing files on server using DropzoneJS and Go](https://hackernoon.com/how-to-display-existing-files-on-server-using-dropzonejs-and-go-53e24b57ba19)
* [Iris Go vs .NET Core Kestrel in terms of HTTP performance](https://hackernoon.com/iris-go-vs-net-core-kestrel-in-terms-of-http-performance-806195dc93d5) * [Iris Go vs .NET Core Kestrel in terms of HTTP performance](https://hackernoon.com/iris-go-vs-net-core-kestrel-in-terms-of-http-performance-806195dc93d5)
* [Go vs .NET Core in terms of HTTP performance](https://medium.com/@kataras/go-vs-net-core-in-terms-of-http-performance-7535a61b67b8) * [Go vs .NET Core in terms of HTTP performance](https://medium.com/@kataras/go-vs-net-core-in-terms-of-http-performance-7535a61b67b8)
* [Iris, a modular web framework](https://medium.com/@corebreaker/iris-web-cd684b4685c7) * [Iris, a modular web framework](https://medium.com/@corebreaker/iris-web-cd684b4685c7)
* [How to Turn an Android Device into a Web Server](https://twitter.com/ThePracticalDev/status/892022594031017988) * [How to Turn an Android Device into a Web Server](https://twitter.com/ThePracticalDev/status/892022594031017988)
* [A URL Shortener Service using Go, Iris and Bolt](https://medium.com/@kataras/a-url-shortener-service-using-go-iris-and-bolt-4182f0b00ae7) * [A URL Shortener Service using Go, Iris and Bolt](https://medium.com/@kataras/a-url-shortener-service-using-go-iris-and-bolt-4182f0b00ae7)
### Social networks ### Social networks
If you're part of any social network, do a post(or tweet if twitter) about Iris and what you love about it, many examples can be found, the most recent one is [that](https://www.facebook.com/eliaswalyba/posts/1462004807202379). If you're part of any social network, do a post(or tweet if twitter) about Iris and what you love about it, many examples can be found, the most recent one is [that](https://www.facebook.com/eliaswalyba/posts/1462004807202379).
### Work ### Work
Convince your colleagues to try the Iris web framework at dev environment and if they choose to proceed on production, contact with [us](mailto:kataras2006@hotmail.com?subject=Iris%20Production) for further instructions, if you need any help. Convince your colleagues to try the Iris web framework at dev environment and if they choose to proceed on production, contact with [us](mailto:kataras2006@hotmail.com?subject=Iris%20Production) for further instructions, if you need any help.
Many young people are choosing Iris for their postgraduate studies as well. Many young people are choosing Iris for their postgraduate studies as well.
## Documentation ## Documentation
We're preparing the new version of the [Build A Better Web, Together](https://github.com/kataras/build-a-better-web-together) Go book, which is a type of documentation of Iris web framework as well. We're preparing the new version of the [Build A Better Web, Together](https://github.com/kataras/build-a-better-web-together) Go book, which is a type of documentation of Iris web framework as well.
If you want to be part of this and you've time for collaboration, please open a new [issue](https://github.com/kataras/build-a-better-web-together/issues/new) and write some words about yourself and your overall experience at tech. At the end of the day you will be granded with `write access` in order to push your sections without our approval at all. If you want to be part of this and you've time for collaboration, please open a new [issue](https://github.com/kataras/build-a-better-web-together/issues/new) and write some words about yourself and your overall experience at tech. At the end of the day you will be granded with `write access` in order to push your sections without our approval at all.
All new contributors of that book will receive prizes! All new contributors of that book will receive prizes!

View File

@ -1,5 +1,5 @@
FROM irisgo/cloud-native-go:latest FROM irisgo/cloud-native-go:latest
ENV APPSOURCES /go/src/github.com/iris-contrib/cloud-native-go ENV APPSOURCES /go/src/github.com/iris-contrib/cloud-native-go
RUN ${APPSOURCES}/cloud-native-go RUN ${APPSOURCES}/cloud-native-go

View File

@ -1,12 +1,12 @@
FROM golang:1.9-alpine FROM golang:1.9-alpine
RUN apk update && apk upgrade && apk add --no-cache bash git RUN apk update && apk upgrade && apk add --no-cache bash git
RUN go get github.com/iris-contrib/cloud-native-go RUN go get github.com/iris-contrib/cloud-native-go
ENV SOURCES /go/src/github.com/iris-contrib/cloud-native-go ENV SOURCES /go/src/github.com/iris-contrib/cloud-native-go
# COPY . ${SOURCES} # COPY . ${SOURCES}
RUN cd ${SOURCES} $$ CGO_ENABLED=0 go build RUN cd ${SOURCES} $$ CGO_ENABLED=0 go build
ENTRYPOINT cloud-native-go ENTRYPOINT cloud-native-go
EXPOSE 8080 EXPOSE 8080

630
Gopkg.lock generated
View File

@ -1,315 +1,315 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]] [[projects]]
name = "github.com/BurntSushi/toml" name = "github.com/BurntSushi/toml"
packages = ["."] packages = ["."]
revision = "b26d9c308763d68093482582cea63d69be07a0f0" revision = "b26d9c308763d68093482582cea63d69be07a0f0"
version = "v0.3.0" version = "v0.3.0"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/Joker/jade" name = "github.com/Joker/jade"
packages = ["."] packages = ["."]
revision = "35b3f5bdbcc920cd31f4870536dbc63be8530541" revision = "35b3f5bdbcc920cd31f4870536dbc63be8530541"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/iris-contrib/i18n" name = "github.com/iris-contrib/i18n"
packages = ["."] packages = ["."]
revision = "976ad7f3463c8f0b8fd949cf5e78a73a1828c96d" revision = "976ad7f3463c8f0b8fd949cf5e78a73a1828c96d"
[[projects]] [[projects]]
name = "github.com/ajg/form" name = "github.com/ajg/form"
packages = ["."] packages = ["."]
revision = "cc2954064ec9ea8d93917f0f87456e11d7b881ad" revision = "cc2954064ec9ea8d93917f0f87456e11d7b881ad"
version = "v1.5" version = "v1.5"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/aymerick/raymond" name = "github.com/aymerick/raymond"
packages = [".","ast","lexer","parser"] packages = [".","ast","lexer","parser"]
revision = "72acac2207479d21dd45898c2a4264246c818148" revision = "72acac2207479d21dd45898c2a4264246c818148"
[[projects]] [[projects]]
name = "github.com/boltdb/bolt" name = "github.com/boltdb/bolt"
packages = ["."] packages = ["."]
revision = "2f1ce7a837dcb8da3ec595b1dac9d0632f0f99e8" revision = "2f1ce7a837dcb8da3ec595b1dac9d0632f0f99e8"
version = "v1.3.1" version = "v1.3.1"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/dgraph-io/badger" name = "github.com/dgraph-io/badger"
packages = ["."] packages = ["."]
revision = "d8b951787ebe5c42286475df8a3dea25045bda1a" revision = "d8b951787ebe5c42286475df8a3dea25045bda1a"
[[projects]] [[projects]]
name = "github.com/davecgh/go-spew" name = "github.com/davecgh/go-spew"
packages = ["spew"] packages = ["spew"]
revision = "346938d642f2ec3594ed81d874461961cd0faa76" revision = "346938d642f2ec3594ed81d874461961cd0faa76"
version = "v1.1.0" version = "v1.1.0"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/eknkc/amber" name = "github.com/eknkc/amber"
packages = [".","parser"] packages = [".","parser"]
revision = "b8bd8b03e4f747e33f092617225e9fa8076c0448" revision = "b8bd8b03e4f747e33f092617225e9fa8076c0448"
[[projects]] [[projects]]
name = "github.com/fatih/structs" name = "github.com/fatih/structs"
packages = ["."] packages = ["."]
revision = "a720dfa8df582c51dee1b36feabb906bde1588bd" revision = "a720dfa8df582c51dee1b36feabb906bde1588bd"
version = "v1.0" version = "v1.0"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/flosch/pongo2" name = "github.com/flosch/pongo2"
packages = ["."] packages = ["."]
revision = "58f1f3387f7c57843ff829d92a759d08abe5a63f" revision = "58f1f3387f7c57843ff829d92a759d08abe5a63f"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/garyburd/redigo" name = "github.com/garyburd/redigo"
packages = ["internal","redis"] packages = ["internal","redis"]
revision = "b925df3cc15d8646e9b5b333ebaf3011385aba11" revision = "b925df3cc15d8646e9b5b333ebaf3011385aba11"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/gavv/monotime" name = "github.com/gavv/monotime"
packages = ["."] packages = ["."]
revision = "47d58efa69556a936a3c15eb2ed42706d968ab01" revision = "47d58efa69556a936a3c15eb2ed42706d968ab01"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/golang/snappy" name = "github.com/golang/snappy"
packages = ["."] packages = ["."]
revision = "553a641470496b2327abcac10b36396bd98e45c9" revision = "553a641470496b2327abcac10b36396bd98e45c9"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/google/go-querystring" name = "github.com/google/go-querystring"
packages = ["query"] packages = ["query"]
revision = "53e6ce116135b80d037921a7fdd5138cf32d7a8a" revision = "53e6ce116135b80d037921a7fdd5138cf32d7a8a"
[[projects]] [[projects]]
name = "github.com/gorilla/websocket" name = "github.com/gorilla/websocket"
packages = ["."] packages = ["."]
revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b" revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b"
version = "v1.2.0" version = "v1.2.0"
[[projects]] [[projects]]
name = "github.com/imkira/go-interpol" name = "github.com/imkira/go-interpol"
packages = ["."] packages = ["."]
revision = "5accad8134979a6ac504d456a6c7f1c53da237ca" revision = "5accad8134979a6ac504d456a6c7f1c53da237ca"
version = "v1.1.0" version = "v1.1.0"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/iris-contrib/formBinder" name = "github.com/iris-contrib/formBinder"
packages = ["."] packages = ["."]
revision = "ad9fb86c356f971f30319c40ddbdcf72129a2791" revision = "ad9fb86c356f971f30319c40ddbdcf72129a2791"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/iris-contrib/httpexpect" name = "github.com/iris-contrib/httpexpect"
packages = ["."] packages = ["."]
revision = "65e93247e7071782e760f82086e8b677cca0c78a" revision = "65e93247e7071782e760f82086e8b677cca0c78a"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/json-iterator/go" name = "github.com/json-iterator/go"
packages = ["."] packages = ["."]
revision = "2dc0031b26575ddf5dab09ab7795105a05575473" revision = "2dc0031b26575ddf5dab09ab7795105a05575473"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/juju/errors" name = "github.com/juju/errors"
packages = ["."] packages = ["."]
revision = "c7d06af17c68cd34c835053720b21f6549d9b0ee" revision = "c7d06af17c68cd34c835053720b21f6549d9b0ee"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/kataras/golog" name = "github.com/kataras/golog"
packages = ["."] packages = ["."]
revision = "2ed680e7b1f34147164fa8073373e14fce02ac30" revision = "2ed680e7b1f34147164fa8073373e14fce02ac30"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/kataras/pio" name = "github.com/kataras/pio"
packages = [".","terminal"] packages = [".","terminal"]
revision = "825e39f34365e7db2c9fbc3692c16220e3bd7418" revision = "825e39f34365e7db2c9fbc3692c16220e3bd7418"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/kataras/survey" name = "github.com/kataras/survey"
packages = ["."] packages = ["."]
revision = "20e139a6d2469769ae88e0a3579ba5df71839ca7" revision = "20e139a6d2469769ae88e0a3579ba5df71839ca7"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/skratchdot/open-golang" name = "github.com/skratchdot/open-golang"
packages = ["."] packages = ["."]
revision = "75fb7ed4208cf72d323d7d02fd1a5964a7a9073c" revision = "75fb7ed4208cf72d323d7d02fd1a5964a7a9073c"
[[projects]] [[projects]]
name = "github.com/klauspost/compress" name = "github.com/klauspost/compress"
packages = ["flate","gzip"] packages = ["flate","gzip"]
revision = "6c8db69c4b49dd4df1fff66996cf556176d0b9bf" revision = "6c8db69c4b49dd4df1fff66996cf556176d0b9bf"
version = "v1.2.1" version = "v1.2.1"
[[projects]] [[projects]]
name = "github.com/klauspost/cpuid" name = "github.com/klauspost/cpuid"
packages = ["."] packages = ["."]
revision = "ae7887de9fa5d2db4eaa8174a7eff2c1ac00f2da" revision = "ae7887de9fa5d2db4eaa8174a7eff2c1ac00f2da"
version = "v1.1" version = "v1.1"
[[projects]] [[projects]]
name = "github.com/klauspost/crc32" name = "github.com/klauspost/crc32"
packages = ["."] packages = ["."]
revision = "cb6bfca970f6908083f26f39a79009d608efd5cd" revision = "cb6bfca970f6908083f26f39a79009d608efd5cd"
version = "v1.1" version = "v1.1"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/microcosm-cc/bluemonday" name = "github.com/microcosm-cc/bluemonday"
packages = ["."] packages = ["."]
revision = "1c44c0b45a213b21569d6dbf440c47191652566f" revision = "1c44c0b45a213b21569d6dbf440c47191652566f"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/moul/http2curl" name = "github.com/moul/http2curl"
packages = ["."] packages = ["."]
revision = "4e24498b31dba4683efb9d35c1c8a91e2eda28c8" revision = "4e24498b31dba4683efb9d35c1c8a91e2eda28c8"
[[projects]] [[projects]]
name = "github.com/pmezard/go-difflib" name = "github.com/pmezard/go-difflib"
packages = ["difflib"] packages = ["difflib"]
revision = "792786c7400a136282c1664665ae0a8db921c6c2" revision = "792786c7400a136282c1664665ae0a8db921c6c2"
version = "v1.0.0" version = "v1.0.0"
[[projects]] [[projects]]
name = "github.com/russross/blackfriday" name = "github.com/russross/blackfriday"
packages = ["."] packages = ["."]
revision = "cadec560ec52d93835bf2f15bd794700d3a2473b" revision = "cadec560ec52d93835bf2f15bd794700d3a2473b"
version = "v2.0.0" version = "v2.0.0"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/ryanuber/columnize" name = "github.com/ryanuber/columnize"
packages = ["."] packages = ["."]
revision = "abc90934186a77966e2beeac62ed966aac0561d5" revision = "abc90934186a77966e2beeac62ed966aac0561d5"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/satori/go.uuid" name = "github.com/satori/go.uuid"
packages = ["."] packages = ["."]
revision = "5bf94b69c6b68ee1b541973bb8e1144db23a194b" revision = "5bf94b69c6b68ee1b541973bb8e1144db23a194b"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/sergi/go-diff" name = "github.com/sergi/go-diff"
packages = ["diffmatchpatch"] packages = ["diffmatchpatch"]
revision = "feef008d51ad2b3778f85d387ccf91735543008d" revision = "feef008d51ad2b3778f85d387ccf91735543008d"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/shurcooL/sanitized_anchor_name" name = "github.com/shurcooL/sanitized_anchor_name"
packages = ["."] packages = ["."]
revision = "541ff5ee47f1dddf6a5281af78307d921524bcb5" revision = "541ff5ee47f1dddf6a5281af78307d921524bcb5"
[[projects]] [[projects]]
name = "github.com/stretchr/testify" name = "github.com/stretchr/testify"
packages = ["assert","require"] packages = ["assert","require"]
revision = "69483b4bd14f5845b5a1e55bca19e954e827f1d0" revision = "69483b4bd14f5845b5a1e55bca19e954e827f1d0"
version = "v1.1.4" version = "v1.1.4"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/syndtr/goleveldb" name = "github.com/syndtr/goleveldb"
packages = ["leveldb","leveldb/cache","leveldb/comparer","leveldb/errors","leveldb/filter","leveldb/iterator","leveldb/journal","leveldb/memdb","leveldb/opt","leveldb/storage","leveldb/table","leveldb/util"] packages = ["leveldb","leveldb/cache","leveldb/comparer","leveldb/errors","leveldb/filter","leveldb/iterator","leveldb/journal","leveldb/memdb","leveldb/opt","leveldb/storage","leveldb/table","leveldb/util"]
revision = "b89cc31ef7977104127d34c1bd31ebd1a9db2199" revision = "b89cc31ef7977104127d34c1bd31ebd1a9db2199"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/valyala/bytebufferpool" name = "github.com/valyala/bytebufferpool"
packages = ["."] packages = ["."]
revision = "e746df99fe4a3986f4d4f79e13c1e0117ce9c2f7" revision = "e746df99fe4a3986f4d4f79e13c1e0117ce9c2f7"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/xeipuuv/gojsonpointer" name = "github.com/xeipuuv/gojsonpointer"
packages = ["."] packages = ["."]
revision = "6fe8760cad3569743d51ddbb243b26f8456742dc" revision = "6fe8760cad3569743d51ddbb243b26f8456742dc"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/xeipuuv/gojsonreference" name = "github.com/xeipuuv/gojsonreference"
packages = ["."] packages = ["."]
revision = "e02fc20de94c78484cd5ffb007f8af96be030a45" revision = "e02fc20de94c78484cd5ffb007f8af96be030a45"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/xeipuuv/gojsonschema" name = "github.com/xeipuuv/gojsonschema"
packages = ["."] packages = ["."]
revision = "0c8571ac0ce161a5feb57375a9cdf148c98c0f70" revision = "0c8571ac0ce161a5feb57375a9cdf148c98c0f70"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/yalp/jsonpath" name = "github.com/yalp/jsonpath"
packages = ["."] packages = ["."]
revision = "31a79c7593bb93eb10b163650d4a3e6ca190e4dc" revision = "31a79c7593bb93eb10b163650d4a3e6ca190e4dc"
[[projects]] [[projects]]
name = "github.com/yudai/gojsondiff" name = "github.com/yudai/gojsondiff"
packages = [".","formatter"] packages = [".","formatter"]
revision = "7b1b7adf999dab73a6eb02669c3d82dbb27a3dd6" revision = "7b1b7adf999dab73a6eb02669c3d82dbb27a3dd6"
version = "1.0.0" version = "1.0.0"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/yudai/golcs" name = "github.com/yudai/golcs"
packages = ["."] packages = ["."]
revision = "ecda9a501e8220fae3b4b600c3db4b0ba22cfc68" revision = "ecda9a501e8220fae3b4b600c3db4b0ba22cfc68"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "golang.org/x/crypto" name = "golang.org/x/crypto"
packages = ["acme","acme/autocert"] packages = ["acme","acme/autocert"]
revision = "81e90905daefcd6fd217b62423c0908922eadb30" revision = "81e90905daefcd6fd217b62423c0908922eadb30"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "golang.org/x/net" name = "golang.org/x/net"
packages = ["html","html/atom","idna","publicsuffix"] packages = ["html","html/atom","idna","publicsuffix"]
revision = "66aacef3dd8a676686c7ae3716979581e8b03c47" revision = "66aacef3dd8a676686c7ae3716979581e8b03c47"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "golang.org/x/sys" name = "golang.org/x/sys"
packages = ["unix"] packages = ["unix"]
revision = "2d6f6f883a06fc0d5f4b14a81e4c28705ea64c15" revision = "2d6f6f883a06fc0d5f4b14a81e4c28705ea64c15"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "golang.org/x/text" name = "golang.org/x/text"
packages = ["internal/gen","internal/triegen","internal/ucd","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable"] packages = ["internal/gen","internal/triegen","internal/ucd","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable"]
revision = "de984aaade05b6b868d6ad3a063e045ed3609f20" revision = "de984aaade05b6b868d6ad3a063e045ed3609f20"
[[projects]] [[projects]]
name = "gopkg.in/ini.v1" name = "gopkg.in/ini.v1"
packages = ["."] packages = ["."]
revision = "20b96f641a5ea98f2f8619ff4f3e061cff4833bd" revision = "20b96f641a5ea98f2f8619ff4f3e061cff4833bd"
version = "v1.28.2" version = "v1.28.2"
[[projects]] [[projects]]
branch = "v2" branch = "v2"
name = "gopkg.in/yaml.v2" name = "gopkg.in/yaml.v2"
packages = ["."] packages = ["."]
revision = "eb3733d160e74a9c7e442f435eb3bea458e1d19f" revision = "eb3733d160e74a9c7e442f435eb3bea458e1d19f"
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "9669ba685c3ec1b0c93329b8457e8567e67cd9c11fd5ca1ecc1cc6e145775f60" inputs-digest = "9669ba685c3ec1b0c93329b8457e8567e67cd9c11fd5ca1ecc1cc6e145775f60"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View File

@ -1,103 +1,103 @@
[[constraint]] [[constraint]]
name = "github.com/BurntSushi/toml" name = "github.com/BurntSushi/toml"
version = "0.3.0" version = "0.3.0"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/Joker/jade" name = "github.com/Joker/jade"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/iris-contrib/i18n" name = "github.com/iris-contrib/i18n"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/aymerick/raymond" name = "github.com/aymerick/raymond"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/boltdb/bolt" name = "github.com/boltdb/bolt"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/dgraph-io/badger" name = "github.com/dgraph-io/badger"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/eknkc/amber" name = "github.com/eknkc/amber"
[[constraint]] [[constraint]]
name = "github.com/fatih/structs" name = "github.com/fatih/structs"
version = "1.0.0" version = "1.0.0"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/flosch/pongo2" name = "github.com/flosch/pongo2"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/garyburd/redigo" name = "github.com/garyburd/redigo"
[[constraint]] [[constraint]]
name = "github.com/gorilla/websocket" name = "github.com/gorilla/websocket"
version = "1.2.0" version = "1.2.0"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/iris-contrib/formBinder" name = "github.com/iris-contrib/formBinder"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/iris-contrib/httpexpect" name = "github.com/iris-contrib/httpexpect"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/json-iterator/go" name = "github.com/json-iterator/go"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/kataras/golog" name = "github.com/kataras/golog"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/kataras/survey" name = "github.com/kataras/survey"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/skratchdot/open-golang" name = "github.com/skratchdot/open-golang"
[[constraint]] [[constraint]]
name = "github.com/klauspost/compress" name = "github.com/klauspost/compress"
version = "1.2.1" version = "1.2.1"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/microcosm-cc/bluemonday" name = "github.com/microcosm-cc/bluemonday"
[[constraint]] [[constraint]]
name = "github.com/russross/blackfriday" name = "github.com/russross/blackfriday"
version = "2.0.0" version = "2.0.0"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/ryanuber/columnize" name = "github.com/ryanuber/columnize"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/satori/go.uuid" name = "github.com/satori/go.uuid"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/syndtr/goleveldb" name = "github.com/syndtr/goleveldb"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/valyala/bytebufferpool" name = "github.com/valyala/bytebufferpool"
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "golang.org/x/crypto" name = "golang.org/x/crypto"
[[constraint]] [[constraint]]
branch = "v2" branch = "v2"
name = "gopkg.in/yaml.v2" name = "gopkg.in/yaml.v2"

3571
HISTORY.md

File diff suppressed because it is too large Load Diff

52
LICENSE
View File

@ -1,27 +1,27 @@
Copyright (c) 2017 The Iris Authors. All rights reserved. Copyright (c) 2017 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
met: met:
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the in the documentation and/or other materials provided with the
distribution. distribution.
* Neither the name of Iris nor the names of its * Neither the name of Iris nor the names of its
contributors may be used to endorse or promote products derived from contributors may be used to endorse or promote products derived from
this software without specific prior written permission. this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

2114
README.md

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
8.5.4:https://github.com/kataras/iris/blob/master/HISTORY.md#th-26-october-2017--v854 8.5.5:https://github.com/kataras/iris/blob/master/HISTORY.md#tu-02-november-2017--v855

View File

@ -1,354 +1,354 @@
## Hardware ## Hardware
* Processor: Intel(R) Core(TM) **i7-4710HQ** CPU @ 2.50GHz 2.50GHz * Processor: Intel(R) Core(TM) **i7-4710HQ** CPU @ 2.50GHz 2.50GHz
* RAM: **8.00 GB** * RAM: **8.00 GB**
## Software ## Software
* OS: Microsoft **Windows** [Version **10**.0.15063], power plan is "High performance" * OS: Microsoft **Windows** [Version **10**.0.15063], power plan is "High performance"
* HTTP Benchmark Tool: https://github.com/codesenberg/bombardier, latest version **1.1** * HTTP Benchmark Tool: https://github.com/codesenberg/bombardier, latest version **1.1**
* **.NET Core**: https://www.microsoft.com/net/core, latest version **2.0** * **.NET Core**: https://www.microsoft.com/net/core, latest version **2.0**
* **Iris**: https://github.com/kataras/iris, latest version **8.3** built with [go1.8.3](https://golang.org) * **Iris**: https://github.com/kataras/iris, latest version **8.3** built with [go1.8.3](https://golang.org)
# .NET Core MVC vs Iris MVC # .NET Core MVC vs Iris MVC
The first test will contain a simple application with a text response and the second will render templates + a layout. The first test will contain a simple application with a text response and the second will render templates + a layout.
## Simple ## Simple
We will compare two identical things here, in terms of application, the expected response and the stability of their run times, so we will not try to put more things in the game like `JSON` or `XML` encoders and decoders, just a simple text message. To achieve a fair comparison we will use the MVC architecture pattern on both sides, Go and .NET Core. We will compare two identical things here, in terms of application, the expected response and the stability of their run times, so we will not try to put more things in the game like `JSON` or `XML` encoders and decoders, just a simple text message. To achieve a fair comparison we will use the MVC architecture pattern on both sides, Go and .NET Core.
### .NET Core MVC ### .NET Core MVC
```bash ```bash
$ cd netcore-mvc $ cd netcore-mvc
$ dotnet run -c Release $ dotnet run -c Release
Hosting environment: Production Hosting environment: Production
Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore-mvc Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore-mvc
Now listening on: http://localhost:5000 Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down. Application started. Press Ctrl+C to shut down.
``` ```
```bash ```bash
$ bombardier -c 125 -n 5000000 http://localhost:5000/api/values/5 $ bombardier -c 125 -n 5000000 http://localhost:5000/api/values/5
Bombarding http://localhost:5000/api/values/5 with 5000000 requests using 125 connections Bombarding http://localhost:5000/api/values/5 with 5000000 requests using 125 connections
5000000 / 5000000 [=====================================================================================] 100.00% 2m3s 5000000 / 5000000 [=====================================================================================] 100.00% 2m3s
Done! Done!
Statistics Avg Stdev Max Statistics Avg Stdev Max
Reqs/sec 40226.03 8724.30 161919 Reqs/sec 40226.03 8724.30 161919
Latency 3.09ms 1.40ms 169.12ms Latency 3.09ms 1.40ms 169.12ms
HTTP codes: HTTP codes:
1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0 1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0 others - 0
Throughput: 8.91MB/s Throughput: 8.91MB/s
``` ```
### Iris MVC ### Iris MVC
```bash ```bash
$ cd iris-mvc $ cd iris-mvc
$ go run main.go $ go run main.go
Now listening on: http://localhost:5000 Now listening on: http://localhost:5000
Application started. Press CTRL+C to shut down. Application started. Press CTRL+C to shut down.
``` ```
```bash ```bash
$ bombardier -c 125 -n 5000000 http://localhost:5000/api/values/5 $ bombardier -c 125 -n 5000000 http://localhost:5000/api/values/5
Bombarding http://localhost:5000/api/values/5 with 5000000 requests using 125 connections Bombarding http://localhost:5000/api/values/5 with 5000000 requests using 125 connections
5000000 / 5000000 [======================================================================================] 100.00% 47s 5000000 / 5000000 [======================================================================================] 100.00% 47s
Done! Done!
Statistics Avg Stdev Max Statistics Avg Stdev Max
Reqs/sec 105643.81 7687.79 122564 Reqs/sec 105643.81 7687.79 122564
Latency 1.18ms 366.55us 22.01ms Latency 1.18ms 366.55us 22.01ms
HTTP codes: HTTP codes:
1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0 1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0 others - 0
Throughput: 19.65MB/s Throughput: 19.65MB/s
``` ```
Click [here](screens) to navigate to the screenshots. Click [here](screens) to navigate to the screenshots.
### Summary ### Summary
* Time to complete the `5000000 requests` - smaller is better. * Time to complete the `5000000 requests` - smaller is better.
* Reqs/sec - bigger is better. * Reqs/sec - bigger is better.
* Latency - smaller is better * Latency - smaller is better
* Throughput - bigger is better. * Throughput - bigger is better.
* Memory usage - smaller is better. * Memory usage - smaller is better.
* LOC (Lines Of Code) - smaller is better. * LOC (Lines Of Code) - smaller is better.
.NET Core MVC Application, written using 86 lines of code, ran for **2 minutes and 3 seconds** serving **40226.03** requests per second within **3.09ms** latency in average and **169.12ms** max, the memory usage of all these was ~123MB (without the dotnet host). .NET Core MVC Application, written using 86 lines of code, ran for **2 minutes and 3 seconds** serving **40226.03** requests per second within **3.09ms** latency in average and **169.12ms** max, the memory usage of all these was ~123MB (without the dotnet host).
Iris MVC Application, written using 27 lines of code, ran for **47 seconds** serving **105643.71** requests per second within **1.18ms** latency in average and **22.01ms** max, the memory usage of all these was ~12MB. Iris MVC Application, written using 27 lines of code, ran for **47 seconds** serving **105643.71** requests per second within **1.18ms** latency in average and **22.01ms** max, the memory usage of all these was ~12MB.
#### Update: 20 August 2017 #### Update: 20 August 2017
As [Josh Clark](https://twitter.com/clarkis117) and [Scott Hanselman](https://twitter.com/shanselman) pointed out [on this status](https://twitter.com/shanselman/status/899005786826788865), on .NET Core MVC `Startup.cs` file the line with `services.AddMvc();` can be replaced with `services.AddMvcCore();`. I followed their helpful instructions and re-run the benchmarks. The article now contains the latest benchmark output for the .NET Core application with the change both Josh and Scott noted. As [Josh Clark](https://twitter.com/clarkis117) and [Scott Hanselman](https://twitter.com/shanselman) pointed out [on this status](https://twitter.com/shanselman/status/899005786826788865), on .NET Core MVC `Startup.cs` file the line with `services.AddMvc();` can be replaced with `services.AddMvcCore();`. I followed their helpful instructions and re-run the benchmarks. The article now contains the latest benchmark output for the .NET Core application with the change both Josh and Scott noted.
The twitter conversion: https://twitter.com/MakisMaropoulos/status/899113215895982080 The twitter conversion: https://twitter.com/MakisMaropoulos/status/899113215895982080
For those who want to compare with the standard services.AddMvc(); you can see the old output by pressing [here](screens/5m_requests_netcore-mvc.png). For those who want to compare with the standard services.AddMvc(); you can see the old output by pressing [here](screens/5m_requests_netcore-mvc.png).
## MVC + Templates ## MVC + Templates
Lets run one more benchmark, spawn `1000000 requests` but this time we expect HTML generated by templates via the view engine. Lets run one more benchmark, spawn `1000000 requests` but this time we expect HTML generated by templates via the view engine.
### .NET Core MVC with Templates ### .NET Core MVC with Templates
```bash ```bash
$ cd netcore-mvc-templates $ cd netcore-mvc-templates
$ dotnet run -c Release $ dotnet run -c Release
Hosting environment: Production Hosting environment: Production
Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore-mvc-templates Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore-mvc-templates
Now listening on: http://localhost:5000 Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down. Application started. Press Ctrl+C to shut down.
``` ```
```bash ```bash
$ bombardier -c 125 -n 1000000 http://localhost:5000 $ bombardier -c 125 -n 1000000 http://localhost:5000
Bombarding http://localhost:5000 with 1000000 requests using 125 connections Bombarding http://localhost:5000 with 1000000 requests using 125 connections
1000000 / 1000000 [=====================================================================================] 100.00% 1m20s 1000000 / 1000000 [=====================================================================================] 100.00% 1m20s
Done! Done!
Statistics Avg Stdev Max Statistics Avg Stdev Max
Reqs/sec 11738.60 7741.36 125887 Reqs/sec 11738.60 7741.36 125887
Latency 10.10ms 22.10ms 1.97s Latency 10.10ms 22.10ms 1.97s
HTTP codes: HTTP codes:
1xx - 0, 2xx - 1000000, 3xx - 0, 4xx - 0, 5xx - 0 1xx - 0, 2xx - 1000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0 others - 0
Throughput: 89.03MB/s Throughput: 89.03MB/s
``` ```
### Iris MVC with Templates ### Iris MVC with Templates
```bash ```bash
$ cd iris-mvc-templates $ cd iris-mvc-templates
$ go run main.go $ go run main.go
Now listening on: http://localhost:5000 Now listening on: http://localhost:5000
Application started. Press CTRL+C to shut down. Application started. Press CTRL+C to shut down.
``` ```
```bash ```bash
$ bombardier -c 125 -n 1000000 http://localhost:5000 $ bombardier -c 125 -n 1000000 http://localhost:5000
Bombarding http://localhost:5000 with 1000000 requests using 125 connections Bombarding http://localhost:5000 with 1000000 requests using 125 connections
1000000 / 1000000 [======================================================================================] 100.00% 37s 1000000 / 1000000 [======================================================================================] 100.00% 37s
Done! Done!
Statistics Avg Stdev Max Statistics Avg Stdev Max
Reqs/sec 26656.76 1944.73 31188 Reqs/sec 26656.76 1944.73 31188
Latency 4.69ms 1.20ms 22.52ms Latency 4.69ms 1.20ms 22.52ms
HTTP codes: HTTP codes:
1xx - 0, 2xx - 1000000, 3xx - 0, 4xx - 0, 5xx - 0 1xx - 0, 2xx - 1000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0 others - 0
Throughput: 192.51MB/s Throughput: 192.51MB/s
``` ```
### Summary ### Summary
* Time to complete the `1000000 requests` - smaller is better. * Time to complete the `1000000 requests` - smaller is better.
* Reqs/sec - bigger is better. * Reqs/sec - bigger is better.
* Latency - smaller is better * Latency - smaller is better
* Memory usage - smaller is better. * Memory usage - smaller is better.
* Throughput - bigger is better. * Throughput - bigger is better.
.NET Core MVC with Templates Application ran for **1 minute and 20 seconds** serving **11738.60** requests per second with **89.03MB/s** within **10.10ms** latency in average and **1.97s** max, the memory usage of all these was ~193MB (without the dotnet host). .NET Core MVC with Templates Application ran for **1 minute and 20 seconds** serving **11738.60** requests per second with **89.03MB/s** within **10.10ms** latency in average and **1.97s** max, the memory usage of all these was ~193MB (without the dotnet host).
Iris MVC with Templates Application ran for **37 seconds** serving **26656.76** requests per second with **192.51MB/s** within **1.18ms** latency in average and **22.52ms** max, the memory usage of all these was ~17MB. Iris MVC with Templates Application ran for **37 seconds** serving **26656.76** requests per second with **192.51MB/s** within **1.18ms** latency in average and **22.52ms** max, the memory usage of all these was ~17MB.
# .NET Core (Kestrel) vs Iris # .NET Core (Kestrel) vs Iris
_Monday, 21 August 2017_ _Monday, 21 August 2017_
This time we will compare the speed of the “low-level” .NET Cores server implementation named Kestrel and Iris “low-level” handlers, we will test two simple applications, the first will be the same as our previous application but written using handlers and the second test will contain a single route which sets and gets a session value(string) based on a key(string). This time we will compare the speed of the “low-level” .NET Cores server implementation named Kestrel and Iris “low-level” handlers, we will test two simple applications, the first will be the same as our previous application but written using handlers and the second test will contain a single route which sets and gets a session value(string) based on a key(string).
## Simple ## Simple
Spawn `1000000 requests` with 125 different "threads", targeting to a dynamic registered route path, responds with a simple "value" text. Spawn `1000000 requests` with 125 different "threads", targeting to a dynamic registered route path, responds with a simple "value" text.
### .NET Core (Kestrel) ### .NET Core (Kestrel)
```bash ```bash
$ cd netcore $ cd netcore
$ dotnet run -c Release $ dotnet run -c Release
Hosting environment: Production Hosting environment: Production
Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore
Now listening on: http://localhost:5000 Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down. Application started. Press Ctrl+C to shut down.
``` ```
```bash ```bash
$ bombardier -c 125 -n 1000000 http://localhost:5000/api/values/5 $ bombardier -c 125 -n 1000000 http://localhost:5000/api/values/5
Bombarding http://localhost:5000/api/values/5 with 1000000 requests using 125 connections Bombarding http://localhost:5000/api/values/5 with 1000000 requests using 125 connections
1000000 / 1000000 [======================================================================================] 100.00% 10s 1000000 / 1000000 [======================================================================================] 100.00% 10s
Done! Done!
Statistics Avg Stdev Max Statistics Avg Stdev Max
Reqs/sec 97884.57 8699.94 110509 Reqs/sec 97884.57 8699.94 110509
Latency 1.28ms 682.63us 61.04ms Latency 1.28ms 682.63us 61.04ms
HTTP codes: HTTP codes:
1xx - 0, 2xx - 1000000, 3xx - 0, 4xx - 0, 5xx - 0 1xx - 0, 2xx - 1000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0 others - 0
Throughput: 17.73MB/s Throughput: 17.73MB/s
``` ```
### Iris ### Iris
```bash ```bash
$ cd iris $ cd iris
$ go run main.go $ go run main.go
Now listening on: http://localhost:5000 Now listening on: http://localhost:5000
Application started. Press CTRL+C to shut down. Application started. Press CTRL+C to shut down.
``` ```
```bash ```bash
$ bombardier -c 125 -n 1000000 http://localhost:5000/api/values/5 $ bombardier -c 125 -n 1000000 http://localhost:5000/api/values/5
Bombarding http://localhost:5000/api/values/5 with 1000000 requests using 125 connections Bombarding http://localhost:5000/api/values/5 with 1000000 requests using 125 connections
1000000 / 1000000 [=======================================================================================] 100.00% 8s 1000000 / 1000000 [=======================================================================================] 100.00% 8s
Done! Done!
Statistics Avg Stdev Max Statistics Avg Stdev Max
Reqs/sec 117917.79 4437.04 125614 Reqs/sec 117917.79 4437.04 125614
Latency 1.06ms 278.12us 19.03ms Latency 1.06ms 278.12us 19.03ms
HTTP codes: HTTP codes:
1xx - 0, 2xx - 1000000, 3xx - 0, 4xx - 0, 5xx - 0 1xx - 0, 2xx - 1000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0 others - 0
Throughput: 21.93MB/s Throughput: 21.93MB/s
``` ```
### Node.js (Express) ### Node.js (Express)
```bash ```bash
$ cd expressjs $ cd expressjs
$ npm install $ npm install
$ node app.js $ node app.js
Now listening on: http://localhost:5000 Now listening on: http://localhost:5000
Application started. Press CTRL+C to shut down. Application started. Press CTRL+C to shut down.
``` ```
```bash ```bash
$ bombardier -c 125 -n 1000000 http://localhost:5000/api/values/5 $ bombardier -c 125 -n 1000000 http://localhost:5000/api/values/5
Bombarding http://localhost:5000/api/values/5 with 1000000 requests using 125 connections Bombarding http://localhost:5000/api/values/5 with 1000000 requests using 125 connections
1000000 / 1000000 [=======================================================================================] 100.00% 1m25s 1000000 / 1000000 [=======================================================================================] 100.00% 1m25s
Done! Done!
Statistics Avg Stdev Max Statistics Avg Stdev Max
Reqs/sec 11665.30 628.41 21978 Reqs/sec 11665.30 628.41 21978
Latency 10.72ms 1.45ms 112.10ms Latency 10.72ms 1.45ms 112.10ms
HTTP codes: HTTP codes:
1xx - 0, 2xx - 1000000, 3xx - 0, 4xx - 0, 5xx - 0 1xx - 0, 2xx - 1000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0 others - 0
Throughput: 3.14MB/s Throughput: 3.14MB/s
``` ```
### Summary ### Summary
* Time to complete the `1000000 requests` - smaller is better. * Time to complete the `1000000 requests` - smaller is better.
* Reqs/sec - bigger is better. * Reqs/sec - bigger is better.
* Latency - smaller is better * Latency - smaller is better
* Throughput - bigger is better. * Throughput - bigger is better.
* LOC (Lines Of Code) - smaller is better. * LOC (Lines Of Code) - smaller is better.
.NET Core (Kestrel) Application written using **63 code of lines** ran for **10 seconds** serving **97884.57** requests per second with **17.73MB/s** within **1.28ms** latency in average and **61.04ms** max. .NET Core (Kestrel) Application written using **63 code of lines** ran for **10 seconds** serving **97884.57** requests per second with **17.73MB/s** within **1.28ms** latency in average and **61.04ms** max.
Iris Application written using **14 code of lines** ran for **8 seconds** serving **117917.79** requests per second with **21.93MB/s** within **1.06ms** latency in average and **19.03ms** max. Iris Application written using **14 code of lines** ran for **8 seconds** serving **117917.79** requests per second with **21.93MB/s** within **1.06ms** latency in average and **19.03ms** max.
Node.js (Express) Application written using **12 code of lines** ran for **1 minute and 25 seconds** serving **11665.30** requests per second with **3.14MB/s** within **10.72ms** latency in average and **112.10ms** max. Node.js (Express) Application written using **12 code of lines** ran for **1 minute and 25 seconds** serving **11665.30** requests per second with **3.14MB/s** within **10.72ms** latency in average and **112.10ms** max.
## Sessions ## Sessions
Spawn `5000000 requests` with 125 different "threads" targeting a static request path, sets and gets a session based on the name `"key"` and string value `"value"` and write that session value to the response stream. Spawn `5000000 requests` with 125 different "threads" targeting a static request path, sets and gets a session based on the name `"key"` and string value `"value"` and write that session value to the response stream.
### .NET Core (Kestrel) with Sessions ### .NET Core (Kestrel) with Sessions
```bash ```bash
$ cd netcore-sessions $ cd netcore-sessions
$ dotnet run -c Release $ dotnet run -c Release
Hosting environment: Production Hosting environment: Production
Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore-sessions Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore-sessions
Now listening on: http://localhost:5000 Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down. Application started. Press Ctrl+C to shut down.
``` ```
```bash ```bash
$ bombardier -c 125 -n 5000000 http://localhost:5000/setget $ bombardier -c 125 -n 5000000 http://localhost:5000/setget
Bombarding http://localhost:5000/setget with 5000000 requests using 125 connections Bombarding http://localhost:5000/setget with 5000000 requests using 125 connections
5000000 / 5000000 [====================================================================================] 100.00% 2m40s 5000000 / 5000000 [====================================================================================] 100.00% 2m40s
Done! Done!
Statistics Avg Stdev Max Statistics Avg Stdev Max
Reqs/sec 31844.77 13856.19 253746 Reqs/sec 31844.77 13856.19 253746
Latency 4.02ms 15.57ms 0.96s Latency 4.02ms 15.57ms 0.96s
HTTP codes: HTTP codes:
1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0 1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0 others - 0
Throughput: 14.51MB/s Throughput: 14.51MB/s
``` ```
### Iris with Sessions ### Iris with Sessions
```bash ```bash
$ cd iris-sessions $ cd iris-sessions
$ go run main.go $ go run main.go
Now listening on: http://localhost:5000 Now listening on: http://localhost:5000
Application started. Press CTRL+C to shut down. Application started. Press CTRL+C to shut down.
``` ```
```bash ```bash
$ bombardier -c 125 -n 5000000 http://localhost:5000/setget $ bombardier -c 125 -n 5000000 http://localhost:5000/setget
Bombarding http://localhost:5000/setget with 5000000 requests using 125 connections Bombarding http://localhost:5000/setget with 5000000 requests using 125 connections
5000000 / 5000000 [====================================================================================] 100.00% 1m15s 5000000 / 5000000 [====================================================================================] 100.00% 1m15s
Done! Done!
Statistics Avg Stdev Max Statistics Avg Stdev Max
Reqs/sec 66749.70 32110.67 110445 Reqs/sec 66749.70 32110.67 110445
Latency 1.88ms 9.13ms 1.94s Latency 1.88ms 9.13ms 1.94s
HTTP codes: HTTP codes:
1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0 1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0 others - 0
Throughput: 20.65MB/s Throughput: 20.65MB/s
``` ```
### Node.js (Express) with Sessions ### Node.js (Express) with Sessions
```bash ```bash
$ cd expressjs-sessions $ cd expressjs-sessions
$ npm install $ npm install
$ node app.js $ node app.js
Now listening on: http://localhost:5000 Now listening on: http://localhost:5000
Application started. Press CTRL+C to shut down. Application started. Press CTRL+C to shut down.
``` ```
```bash ```bash
$ bombardier -c 125 -n 5000000 http://localhost:5000/setget $ bombardier -c 125 -n 5000000 http://localhost:5000/setget
Bombarding http://localhost:5000/setget with 5000000 requests using 125 connections Bombarding http://localhost:5000/setget with 5000000 requests using 125 connections
5000000 / 5000000 [====================================================================================] 100.00% 15m47s 5000000 / 5000000 [====================================================================================] 100.00% 15m47s
Done! Done!
Statistics Avg Stdev Max Statistics Avg Stdev Max
Reqs/sec 5634.27 2317.30 9945 Reqs/sec 5634.27 2317.30 9945
Latency 22.17ms 8.19ms 119.08ms Latency 22.17ms 8.19ms 119.08ms
HTTP codes: HTTP codes:
1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0 1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0 others - 0
Throughput: 1.48MB/s Throughput: 1.48MB/s
``` ```
### Summary ### Summary
* Time to complete the `5000000 requests` - smaller is better. * Time to complete the `5000000 requests` - smaller is better.
* Reqs/sec - bigger is better. * Reqs/sec - bigger is better.
* Latency - smaller is better * Latency - smaller is better
* Throughput - bigger is better. * Throughput - bigger is better.
.NET Core with Sessions Application ran for **2 minutes and 40 seconds** serving **31844.77** requests per second with **14.51MB/s** within **4.02ms** latency in average and **0.96s** max. .NET Core with Sessions Application ran for **2 minutes and 40 seconds** serving **31844.77** requests per second with **14.51MB/s** within **4.02ms** latency in average and **0.96s** max.
Iris with Sessions Application ran for **1 minute and 15 seconds** serving **66749.70** requests per second with **20.65MB/s** within **1.88ms** latency in average and **1.94s** max. Iris with Sessions Application ran for **1 minute and 15 seconds** serving **66749.70** requests per second with **20.65MB/s** within **1.88ms** latency in average and **1.94s** max.
Node.js (Express) with Sessions Application ran for **15 minutes and 47 seconds** serving **5634.27** requests per second with **1.48MB/s** within **22.17ms** latency in average and **119.08ms** max. Node.js (Express) with Sessions Application ran for **15 minutes and 47 seconds** serving **5634.27** requests per second with **1.48MB/s** within **22.17ms** latency in average and **119.08ms** max.
> Click [here](screens) to navigate to the screenshots. > Click [here](screens) to navigate to the screenshots.
### Articles ### Articles
**Go vs .NET Core in terms of HTTP performance (Sa, 19 August 2017)** **Go vs .NET Core in terms of HTTP performance (Sa, 19 August 2017)**
- https://medium.com/@kataras/go-vs-net-core-in-terms-of-http-performance-7535a61b67b8 - https://medium.com/@kataras/go-vs-net-core-in-terms-of-http-performance-7535a61b67b8
- https://dev.to/kataras/go-vsnet-core-in-terms-of-http-performance - https://dev.to/kataras/go-vsnet-core-in-terms-of-http-performance
**Iris Go vs .NET Core Kestrel in terms of HTTP performance (Mo, 21 August 2017)** **Iris Go vs .NET Core Kestrel in terms of HTTP performance (Mo, 21 August 2017)**
- https://medium.com/@kataras/iris-go-vs-net-core-kestrel-in-terms-of-http-performance-806195dc93d5 - https://medium.com/@kataras/iris-go-vs-net-core-kestrel-in-terms-of-http-performance-806195dc93d5
**Thank you all** for the 100% green feedback, have fun! **Thank you all** for the 100% green feedback, have fun!

View File

@ -1,26 +1,26 @@
process.env.NODE_ENV = 'production'; process.env.NODE_ENV = 'production';
const express = require('express'); const express = require('express');
const app = express(); const app = express();
const session = require('express-session'); const session = require('express-session');
// Use the session middleware // Use the session middleware
app.use(session({ secret: '.cookiesession.id', resave: true, saveUninitialized: false, cookie: { secure: true, maxAge: 60000 } })); app.use(session({ secret: '.cookiesession.id', resave: true, saveUninitialized: false, cookie: { secure: true, maxAge: 60000 } }));
app.get('/setget', function (req, res) { app.get('/setget', function (req, res) {
req.session.key = 'value'; req.session.key = 'value';
var value = req.session.key; var value = req.session.key;
if (value == '') { if (value == '') {
res.send('NOT_OK'); res.send('NOT_OK');
return; return;
} }
res.send(value); res.send(value);
}); });
app.listen(5000, function () { app.listen(5000, function () {
console.log( console.log(
'Now listening on: http://localhost:5000\nApplication started. Press CTRL+C to shut down.' 'Now listening on: http://localhost:5000\nApplication started. Press CTRL+C to shut down.'
) )
}); });

View File

@ -1,14 +1,14 @@
process.env.NODE_ENV = 'production'; process.env.NODE_ENV = 'production';
const express = require('express'); const express = require('express');
const app = express(); const app = express();
app.get('/api/values/:id', function (req, res) { app.get('/api/values/:id', function (req, res) {
res.send('value'); res.send('value');
}); });
app.listen(5000, function () { app.listen(5000, function () {
console.log( console.log(
'Now listening on: http://localhost:5000\nApplication started. Press CTRL+C to shut down.' 'Now listening on: http://localhost:5000\nApplication started. Press CTRL+C to shut down.'
) )
}); });

View File

@ -1,4 +1,4 @@
<h2>{{.Title}}</h2> <h2>{{.Title}}</h2>
<h3>{{.Message}}</h3> <h3>{{.Message}}</h3>
<p>Use this area to provide additional information.</p> <p>Use this area to provide additional information.</p>

View File

@ -1,14 +1,14 @@
<h2>{{.Title}}</h2> <h2>{{.Title}}</h2>
<h3>{{.Message}}</h3> <h3>{{.Message}}</h3>
<address> <address>
One Microsoft Way<br /> One Microsoft Way<br />
Redmond, WA 98052-6399<br /> Redmond, WA 98052-6399<br />
<abbr title="Phone">P:</abbr> <abbr title="Phone">P:</abbr>
425.555.0100 425.555.0100
</address> </address>
<address> <address>
<strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br /> <strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br />
<strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a> <strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a>
</address> </address>

View File

@ -1,104 +1,104 @@
<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="6000"> <div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="6000">
<ol class="carousel-indicators"> <ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li> <li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li> <li data-target="#myCarousel" data-slide-to="1"></li>
<li data-target="#myCarousel" data-slide-to="2"></li> <li data-target="#myCarousel" data-slide-to="2"></li>
<li data-target="#myCarousel" data-slide-to="3"></li> <li data-target="#myCarousel" data-slide-to="3"></li>
</ol> </ol>
<div class="carousel-inner" role="listbox"> <div class="carousel-inner" role="listbox">
<div class="item active"> <div class="item active">
<img src="/public/images/banner1.svg" alt="ASP.NET" class="img-responsive" /> <img src="/public/images/banner1.svg" alt="ASP.NET" class="img-responsive" />
<div class="carousel-caption" role="option"> <div class="carousel-caption" role="option">
<p> <p>
Learn how to build ASP.NET apps that can run anywhere. Learn how to build ASP.NET apps that can run anywhere.
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525028&clcid=0x409"> <a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525028&clcid=0x409">
Learn More Learn More
</a> </a>
</p> </p>
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<img src="/public/images/banner2.svg" alt="Visual Studio" class="img-responsive" /> <img src="/public/images/banner2.svg" alt="Visual Studio" class="img-responsive" />
<div class="carousel-caption" role="option"> <div class="carousel-caption" role="option">
<p> <p>
There are powerful new features in Visual Studio for building modern web apps. There are powerful new features in Visual Studio for building modern web apps.
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525030&clcid=0x409"> <a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525030&clcid=0x409">
Learn More Learn More
</a> </a>
</p> </p>
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<img src="/public/images/banner3.svg" alt="Package Management" class="img-responsive" /> <img src="/public/images/banner3.svg" alt="Package Management" class="img-responsive" />
<div class="carousel-caption" role="option"> <div class="carousel-caption" role="option">
<p> <p>
Bring in libraries from NuGet, Bower, and npm, and automate tasks using Grunt or Gulp. Bring in libraries from NuGet, Bower, and npm, and automate tasks using Grunt or Gulp.
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525029&clcid=0x409"> <a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525029&clcid=0x409">
Learn More Learn More
</a> </a>
</p> </p>
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<img src="/public/images/banner4.svg" alt="Microsoft Azure" class="img-responsive" /> <img src="/public/images/banner4.svg" alt="Microsoft Azure" class="img-responsive" />
<div class="carousel-caption" role="option"> <div class="carousel-caption" role="option">
<p> <p>
Learn how Microsoft's Azure cloud platform allows you to build, deploy, and scale web apps. Learn how Microsoft's Azure cloud platform allows you to build, deploy, and scale web apps.
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525027&clcid=0x409"> <a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525027&clcid=0x409">
Learn More Learn More
</a> </a>
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev"> <a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span> <span class="sr-only">Previous</span>
</a> </a>
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next"> <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span> <span class="sr-only">Next</span>
</a> </a>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-3"> <div class="col-md-3">
<h2>Application uses</h2> <h2>Application uses</h2>
<ul> <ul>
<li>Sample pages using ASP.NET Core MVC</li> <li>Sample pages using ASP.NET Core MVC</li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> for managing client-side libraries</li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> for managing client-side libraries</li>
<li>Theming using <a href="https://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a></li> <li>Theming using <a href="https://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a></li>
</ul> </ul>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<h2>How to</h2> <h2>How to</h2>
<ul> <ul>
<li><a href="https://go.microsoft.com/fwlink/?LinkID=398600">Add a Controller and View</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkID=398600">Add a Controller and View</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699315">Manage User Secrets using Secret Manager.</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=699315">Manage User Secrets using Secret Manager.</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699316">Use logging to log a message.</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=699316">Use logging to log a message.</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699317">Add packages using NuGet.</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=699317">Add packages using NuGet.</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699318">Add client packages using Bower.</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=699318">Add client packages using Bower.</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699319">Target development, staging or production environment.</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=699319">Target development, staging or production environment.</a></li>
</ul> </ul>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<h2>Overview</h2> <h2>Overview</h2>
<ul> <ul>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=518008">Conceptual overview of what is ASP.NET Core</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=518008">Conceptual overview of what is ASP.NET Core</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699320">Fundamentals of ASP.NET Core such as Startup and middleware.</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=699320">Fundamentals of ASP.NET Core such as Startup and middleware.</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=398602">Working with Data</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=398602">Working with Data</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=398603">Security</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=398603">Security</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699321">Client side development</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkID=699321">Client side development</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699322">Develop on different platforms</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkID=699322">Develop on different platforms</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699323">Read more on the documentation site</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkID=699323">Read more on the documentation site</a></li>
</ul> </ul>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<h2>Run &amp; Deploy</h2> <h2>Run &amp; Deploy</h2>
<ul> <ul>
<li><a href="https://go.microsoft.com/fwlink/?LinkID=517851">Run your app</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkID=517851">Run your app</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkID=517853">Run tools such as EF migrations and more</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkID=517853">Run tools such as EF migrations and more</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkID=398609">Publish to Microsoft Azure Web Apps</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkID=398609">Publish to Microsoft Azure Web Apps</a></li>
</ul> </ul>
</div> </div>
</div> </div>

View File

@ -1,4 +1,4 @@
<h1 class="text-danger">Error.</h1> <h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2> <h2 class="text-danger">An error occurred while processing your request.</h2>
<h3>{{.Code}}</h3> <h3>{{.Code}}</h3>

View File

@ -1,50 +1,50 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{.Title}} - iris_mvc_templates</title> <title>{{.Title}} - iris_mvc_templates</title>
<link rel="stylesheet" href="/public/lib/bootstrap/dist/css/bootstrap.min.css" /> <link rel="stylesheet" href="/public/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/public/css/site.min.css" /> <link rel="stylesheet" href="/public/css/site.min.css" />
</head> </head>
<body> <body>
<nav class="navbar navbar-inverse navbar-fixed-top"> <nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container"> <div class="container">
<div class="navbar-header"> <div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span> <span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<a href="/" class="navbar-brand">iris_mvc_templates</a> <a href="/" class="navbar-brand">iris_mvc_templates</a>
</div> </div>
<div class="navbar-collapse collapse"> <div class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a href="/">Home</a></li> <li><a href="/">Home</a></li>
<li><a href="/about">About</a></li> <li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li> <li><a href="/contact">Contact</a></li>
</ul> </ul>
</div> </div>
</div> </div>
</nav> </nav>
<div class="container body-content"> <div class="container body-content">
<!-- Render the current template here --> <!-- Render the current template here -->
{{ yield }} {{ yield }}
<hr /> <hr />
<footer> <footer>
<p>&copy; 2017 - iris_mvc_templates</p> <p>&copy; 2017 - iris_mvc_templates</p>
</footer> </footer>
</div> </div>
<script src="/public/lib/jquery/dist/jquery.min.js"></script> <script src="/public/lib/jquery/dist/jquery.min.js"></script>
<script src="/public/lib/bootstrap/dist/js/bootstrap.min.js"></script> <script src="/public/lib/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="/public/js/site.min.js"></script> <script src="/public/js/site.min.js"></script>
</body> </body>
</html> </html>

View File

@ -1,37 +1,37 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using netcore_mvc_templates.Models; using netcore_mvc_templates.Models;
namespace netcore_mvc_templates.Controllers namespace netcore_mvc_templates.Controllers
{ {
public class HomeController : Controller public class HomeController : Controller
{ {
public IActionResult Index() public IActionResult Index()
{ {
return View(); return View();
} }
public IActionResult About() public IActionResult About()
{ {
ViewData["Message"] = "Your application description page."; ViewData["Message"] = "Your application description page.";
return View(); return View();
} }
public IActionResult Contact() public IActionResult Contact()
{ {
ViewData["Message"] = "Your contact page."; ViewData["Message"] = "Your contact page.";
return View(); return View();
} }
public IActionResult Error() public IActionResult Error()
{ {
return View(new ErrorViewModel { Title = "Error", Code = 500}); return View(new ErrorViewModel { Title = "Error", Code = 500});
} }
} }
} }

View File

@ -1,10 +1,10 @@
using System; using System;
namespace netcore_mvc_templates.Models namespace netcore_mvc_templates.Models
{ {
public class ErrorViewModel public class ErrorViewModel
{ {
public string Title { get; set; } public string Title { get; set; }
public int Code { get; set; } public int Code { get; set; }
} }
} }

View File

@ -1,25 +1,25 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore; using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace netcore_mvc_templates namespace netcore_mvc_templates
{ {
public class Program public class Program
{ {
public static void Main(string[] args) public static void Main(string[] args)
{ {
BuildWebHost(args).Run(); BuildWebHost(args).Run();
} }
public static IWebHost BuildWebHost(string[] args) => public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args) WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>() .UseStartup<Startup>()
.Build(); .Build();
} }
} }

View File

@ -1,46 +1,46 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace netcore_mvc_templates namespace netcore_mvc_templates
{ {
public class Startup public class Startup
{ {
public Startup(IConfiguration configuration) public Startup(IConfiguration configuration)
{ {
Configuration = configuration; Configuration = configuration;
} }
public IConfiguration Configuration { get; } public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container. // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
/* An unhandled exception was thrown by the application. /* An unhandled exception was thrown by the application.
System.InvalidOperationException: No service for type System.InvalidOperationException: No service for type
'Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory' has been registered. 'Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory' has been registered.
Solution: Use AddMvc() instead of AddMvcCore() in Startup.cs and it will work. Solution: Use AddMvc() instead of AddMvcCore() in Startup.cs and it will work.
*/ */
// services.AddMvcCore(); // services.AddMvcCore();
services.AddMvc(); services.AddMvc();
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env) public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{ {
app.UseStaticFiles(); app.UseStaticFiles();
app.UseMvc(routes => app.UseMvc(routes =>
{ {
routes.MapRoute( routes.MapRoute(
name: "default", name: "default",
template: "{controller=Home}/{action=Index}/{id?}"); template: "{controller=Home}/{action=Index}/{id?}");
}); });
} }
} }
} }

View File

@ -1,7 +1,7 @@
@{ @{
ViewData["Title"] = "About"; ViewData["Title"] = "About";
} }
<h2>@ViewData["Title"]</h2> <h2>@ViewData["Title"]</h2>
<h3>@ViewData["Message"]</h3> <h3>@ViewData["Message"]</h3>
<p>Use this area to provide additional information.</p> <p>Use this area to provide additional information.</p>

View File

@ -1,17 +1,17 @@
@{ @{
ViewData["Title"] = "Contact"; ViewData["Title"] = "Contact";
} }
<h2>@ViewData["Title"]</h2> <h2>@ViewData["Title"]</h2>
<h3>@ViewData["Message"]</h3> <h3>@ViewData["Message"]</h3>
<address> <address>
One Microsoft Way<br /> One Microsoft Way<br />
Redmond, WA 98052-6399<br /> Redmond, WA 98052-6399<br />
<abbr title="Phone">P:</abbr> <abbr title="Phone">P:</abbr>
425.555.0100 425.555.0100
</address> </address>
<address> <address>
<strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br /> <strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br />
<strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a> <strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a>
</address> </address>

View File

@ -1,108 +1,108 @@
@{ @{
ViewData["Title"] = "Home Page"; ViewData["Title"] = "Home Page";
} }
<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="6000"> <div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="6000">
<ol class="carousel-indicators"> <ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li> <li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li> <li data-target="#myCarousel" data-slide-to="1"></li>
<li data-target="#myCarousel" data-slide-to="2"></li> <li data-target="#myCarousel" data-slide-to="2"></li>
<li data-target="#myCarousel" data-slide-to="3"></li> <li data-target="#myCarousel" data-slide-to="3"></li>
</ol> </ol>
<div class="carousel-inner" role="listbox"> <div class="carousel-inner" role="listbox">
<div class="item active"> <div class="item active">
<img src="~/images/banner1.svg" alt="ASP.NET" class="img-responsive" /> <img src="~/images/banner1.svg" alt="ASP.NET" class="img-responsive" />
<div class="carousel-caption" role="option"> <div class="carousel-caption" role="option">
<p> <p>
Learn how to build ASP.NET apps that can run anywhere. Learn how to build ASP.NET apps that can run anywhere.
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525028&clcid=0x409"> <a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525028&clcid=0x409">
Learn More Learn More
</a> </a>
</p> </p>
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<img src="~/images/banner2.svg" alt="Visual Studio" class="img-responsive" /> <img src="~/images/banner2.svg" alt="Visual Studio" class="img-responsive" />
<div class="carousel-caption" role="option"> <div class="carousel-caption" role="option">
<p> <p>
There are powerful new features in Visual Studio for building modern web apps. There are powerful new features in Visual Studio for building modern web apps.
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525030&clcid=0x409"> <a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525030&clcid=0x409">
Learn More Learn More
</a> </a>
</p> </p>
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<img src="~/images/banner3.svg" alt="Package Management" class="img-responsive" /> <img src="~/images/banner3.svg" alt="Package Management" class="img-responsive" />
<div class="carousel-caption" role="option"> <div class="carousel-caption" role="option">
<p> <p>
Bring in libraries from NuGet, Bower, and npm, and automate tasks using Grunt or Gulp. Bring in libraries from NuGet, Bower, and npm, and automate tasks using Grunt or Gulp.
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525029&clcid=0x409"> <a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525029&clcid=0x409">
Learn More Learn More
</a> </a>
</p> </p>
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<img src="~/images/banner4.svg" alt="Microsoft Azure" class="img-responsive" /> <img src="~/images/banner4.svg" alt="Microsoft Azure" class="img-responsive" />
<div class="carousel-caption" role="option"> <div class="carousel-caption" role="option">
<p> <p>
Learn how Microsoft's Azure cloud platform allows you to build, deploy, and scale web apps. Learn how Microsoft's Azure cloud platform allows you to build, deploy, and scale web apps.
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525027&clcid=0x409"> <a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525027&clcid=0x409">
Learn More Learn More
</a> </a>
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev"> <a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span> <span class="sr-only">Previous</span>
</a> </a>
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next"> <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span> <span class="sr-only">Next</span>
</a> </a>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-3"> <div class="col-md-3">
<h2>Application uses</h2> <h2>Application uses</h2>
<ul> <ul>
<li>Sample pages using ASP.NET Core MVC</li> <li>Sample pages using ASP.NET Core MVC</li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> for managing client-side libraries</li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> for managing client-side libraries</li>
<li>Theming using <a href="https://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a></li> <li>Theming using <a href="https://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a></li>
</ul> </ul>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<h2>How to</h2> <h2>How to</h2>
<ul> <ul>
<li><a href="https://go.microsoft.com/fwlink/?LinkID=398600">Add a Controller and View</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkID=398600">Add a Controller and View</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699315">Manage User Secrets using Secret Manager.</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=699315">Manage User Secrets using Secret Manager.</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699316">Use logging to log a message.</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=699316">Use logging to log a message.</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699317">Add packages using NuGet.</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=699317">Add packages using NuGet.</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699318">Add client packages using Bower.</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=699318">Add client packages using Bower.</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699319">Target development, staging or production environment.</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=699319">Target development, staging or production environment.</a></li>
</ul> </ul>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<h2>Overview</h2> <h2>Overview</h2>
<ul> <ul>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=518008">Conceptual overview of what is ASP.NET Core</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=518008">Conceptual overview of what is ASP.NET Core</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699320">Fundamentals of ASP.NET Core such as Startup and middleware.</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=699320">Fundamentals of ASP.NET Core such as Startup and middleware.</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=398602">Working with Data</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=398602">Working with Data</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=398603">Security</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkId=398603">Security</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699321">Client side development</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkID=699321">Client side development</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699322">Develop on different platforms</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkID=699322">Develop on different platforms</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699323">Read more on the documentation site</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkID=699323">Read more on the documentation site</a></li>
</ul> </ul>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<h2>Run &amp; Deploy</h2> <h2>Run &amp; Deploy</h2>
<ul> <ul>
<li><a href="https://go.microsoft.com/fwlink/?LinkID=517851">Run your app</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkID=517851">Run your app</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkID=517853">Run tools such as EF migrations and more</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkID=517853">Run tools such as EF migrations and more</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkID=398609">Publish to Microsoft Azure Web Apps</a></li> <li><a href="https://go.microsoft.com/fwlink/?LinkID=398609">Publish to Microsoft Azure Web Apps</a></li>
</ul> </ul>
</div> </div>
</div> </div>

View File

@ -1,9 +1,9 @@
@model ErrorViewModel @model ErrorViewModel
@{ @{
ViewData["Title"] = @Model.Title; ViewData["Title"] = @Model.Title;
} }
<h1 class="text-danger">Error.</h1> <h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2> <h2 class="text-danger">An error occurred while processing your request.</h2>
<h3>@Model.Code</h3> <h3>@Model.Code</h3>

View File

@ -1,45 +1,45 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - netcore_mvc_templates</title> <title>@ViewData["Title"] - netcore_mvc_templates</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" /> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" /> <link rel="stylesheet" href="~/css/site.css" />
</head> </head>
<body> <body>
<nav class="navbar navbar-inverse navbar-fixed-top"> <nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container"> <div class="container">
<div class="navbar-header"> <div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span> <span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<a asp-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">netcore_mvc_templates</a> <a asp-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">netcore_mvc_templates</a>
</div> </div>
<div class="navbar-collapse collapse"> <div class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li> <li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li> <li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li> <li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
</ul> </ul>
</div> </div>
</div> </div>
</nav> </nav>
<div class="container body-content"> <div class="container body-content">
@RenderBody() @RenderBody()
<hr /> <hr />
<footer> <footer>
<p>&copy; 2017 - netcore_mvc_templates</p> <p>&copy; 2017 - netcore_mvc_templates</p>
</footer> </footer>
</div> </div>
<script src="~/lib/jquery/dist/jquery.min.js"></script> <script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.min.js"></script> <script src="~/lib/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="~/js/site.min.js" asp-append-version="true"></script> <script src="~/js/site.min.js" asp-append-version="true"></script>
</body> </body>
</html> </html>

View File

@ -1,3 +1,3 @@
@using netcore_mvc_templates @using netcore_mvc_templates
@using netcore_mvc_templates.Models @using netcore_mvc_templates.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@ -1,3 +1,3 @@
@{ @{
Layout = "_Layout"; Layout = "_Layout";
} }

View File

@ -1,8 +1,8 @@
{ {
"Logging": { "Logging": {
"IncludeScopes": false, "IncludeScopes": false,
"LogLevel": { "LogLevel": {
"Default": "Error" "Default": "Error"
} }
} }
} }

View File

@ -1,15 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework> <TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" /> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,45 +1,45 @@
{ {
"name": "bootstrap", "name": "bootstrap",
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
"keywords": [ "keywords": [
"css", "css",
"js", "js",
"less", "less",
"mobile-first", "mobile-first",
"responsive", "responsive",
"front-end", "front-end",
"framework", "framework",
"web" "web"
], ],
"homepage": "http://getbootstrap.com", "homepage": "http://getbootstrap.com",
"license": "MIT", "license": "MIT",
"moduleType": "globals", "moduleType": "globals",
"main": [ "main": [
"less/bootstrap.less", "less/bootstrap.less",
"dist/js/bootstrap.js" "dist/js/bootstrap.js"
], ],
"ignore": [ "ignore": [
"/.*", "/.*",
"_config.yml", "_config.yml",
"CNAME", "CNAME",
"composer.json", "composer.json",
"CONTRIBUTING.md", "CONTRIBUTING.md",
"docs", "docs",
"js/tests", "js/tests",
"test-infra" "test-infra"
], ],
"dependencies": { "dependencies": {
"jquery": "1.9.1 - 3" "jquery": "1.9.1 - 3"
}, },
"version": "3.3.7", "version": "3.3.7",
"_release": "3.3.7", "_release": "3.3.7",
"_resolution": { "_resolution": {
"type": "version", "type": "version",
"tag": "v3.3.7", "tag": "v3.3.7",
"commit": "0b9c4a4007c44201dce9a6cc1a38407005c26c86" "commit": "0b9c4a4007c44201dce9a6cc1a38407005c26c86"
}, },
"_source": "https://github.com/twbs/bootstrap.git", "_source": "https://github.com/twbs/bootstrap.git",
"_target": "v3.3.7", "_target": "v3.3.7",
"_originalSource": "bootstrap", "_originalSource": "bootstrap",
"_direct": true "_direct": true
} }

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,44 +1,44 @@
{ {
"name": "jquery-validation-unobtrusive", "name": "jquery-validation-unobtrusive",
"version": "3.2.6", "version": "3.2.6",
"homepage": "https://github.com/aspnet/jquery-validation-unobtrusive", "homepage": "https://github.com/aspnet/jquery-validation-unobtrusive",
"description": "Add-on to jQuery Validation to enable unobtrusive validation options in data-* attributes.", "description": "Add-on to jQuery Validation to enable unobtrusive validation options in data-* attributes.",
"main": [ "main": [
"jquery.validate.unobtrusive.js" "jquery.validate.unobtrusive.js"
], ],
"ignore": [ "ignore": [
"**/.*", "**/.*",
"*.json", "*.json",
"*.md", "*.md",
"*.txt", "*.txt",
"gulpfile.js" "gulpfile.js"
], ],
"keywords": [ "keywords": [
"jquery", "jquery",
"asp.net", "asp.net",
"mvc", "mvc",
"validation", "validation",
"unobtrusive" "unobtrusive"
], ],
"authors": [ "authors": [
"Microsoft" "Microsoft"
], ],
"license": "http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm", "license": "http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/aspnet/jquery-validation-unobtrusive.git" "url": "git://github.com/aspnet/jquery-validation-unobtrusive.git"
}, },
"dependencies": { "dependencies": {
"jquery-validation": ">=1.8", "jquery-validation": ">=1.8",
"jquery": ">=1.8" "jquery": ">=1.8"
}, },
"_release": "3.2.6", "_release": "3.2.6",
"_resolution": { "_resolution": {
"type": "version", "type": "version",
"tag": "v3.2.6", "tag": "v3.2.6",
"commit": "13386cd1b5947d8a5d23a12b531ce3960be1eba7" "commit": "13386cd1b5947d8a5d23a12b531ce3960be1eba7"
}, },
"_source": "git://github.com/aspnet/jquery-validation-unobtrusive.git", "_source": "git://github.com/aspnet/jquery-validation-unobtrusive.git",
"_target": "3.2.6", "_target": "3.2.6",
"_originalSource": "jquery-validation-unobtrusive" "_originalSource": "jquery-validation-unobtrusive"
} }

View File

@ -1,40 +1,40 @@
{ {
"name": "jquery-validation", "name": "jquery-validation",
"homepage": "http://jqueryvalidation.org/", "homepage": "http://jqueryvalidation.org/",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/jzaefferer/jquery-validation.git" "url": "git://github.com/jzaefferer/jquery-validation.git"
}, },
"authors": [ "authors": [
"Jörn Zaefferer <joern.zaefferer@gmail.com>" "Jörn Zaefferer <joern.zaefferer@gmail.com>"
], ],
"description": "Form validation made easy", "description": "Form validation made easy",
"main": "dist/jquery.validate.js", "main": "dist/jquery.validate.js",
"keywords": [ "keywords": [
"forms", "forms",
"validation", "validation",
"validate" "validate"
], ],
"license": "MIT", "license": "MIT",
"ignore": [ "ignore": [
"**/.*", "**/.*",
"node_modules", "node_modules",
"bower_components", "bower_components",
"test", "test",
"demo", "demo",
"lib" "lib"
], ],
"dependencies": { "dependencies": {
"jquery": ">= 1.7.2" "jquery": ">= 1.7.2"
}, },
"version": "1.14.0", "version": "1.14.0",
"_release": "1.14.0", "_release": "1.14.0",
"_resolution": { "_resolution": {
"type": "version", "type": "version",
"tag": "1.14.0", "tag": "1.14.0",
"commit": "c1343fb9823392aa9acbe1c3ffd337b8c92fed48" "commit": "c1343fb9823392aa9acbe1c3ffd337b8c92fed48"
}, },
"_source": "git://github.com/jzaefferer/jquery-validation.git", "_source": "git://github.com/jzaefferer/jquery-validation.git",
"_target": ">=1.8", "_target": ">=1.8",
"_originalSource": "jquery-validation" "_originalSource": "jquery-validation"
} }

View File

@ -1,25 +1,25 @@
{ {
"name": "jquery", "name": "jquery",
"main": "dist/jquery.js", "main": "dist/jquery.js",
"license": "MIT", "license": "MIT",
"ignore": [ "ignore": [
"package.json" "package.json"
], ],
"keywords": [ "keywords": [
"jquery", "jquery",
"javascript", "javascript",
"browser", "browser",
"library" "library"
], ],
"homepage": "https://github.com/jquery/jquery-dist", "homepage": "https://github.com/jquery/jquery-dist",
"version": "2.2.0", "version": "2.2.0",
"_release": "2.2.0", "_release": "2.2.0",
"_resolution": { "_resolution": {
"type": "version", "type": "version",
"tag": "2.2.0", "tag": "2.2.0",
"commit": "6fc01e29bdad0964f62ef56d01297039cdcadbe5" "commit": "6fc01e29bdad0964f62ef56d01297039cdcadbe5"
}, },
"_source": "git://github.com/jquery/jquery-dist.git", "_source": "git://github.com/jquery/jquery-dist.git",
"_target": "2.2.0", "_target": "2.2.0",
"_originalSource": "jquery" "_originalSource": "jquery"
} }

View File

@ -1,36 +1,36 @@
Copyright jQuery Foundation and other contributors, https://jquery.org/ Copyright jQuery Foundation and other contributors, https://jquery.org/
This software consists of voluntary contributions made by many This software consists of voluntary contributions made by many
individuals. For exact contribution history, see the revision history individuals. For exact contribution history, see the revision history
available at https://github.com/jquery/jquery available at https://github.com/jquery/jquery
The following license applies to all parts of this software except as The following license applies to all parts of this software except as
documented below: documented below:
==== ====
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to permit persons to whom the Software is furnished to do so, subject to
the following conditions: the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
==== ====
All files located in the node_modules and external directories are All files located in the node_modules and external directories are
externally maintained libraries used by this software which have their externally maintained libraries used by this software which have their
own licenses; we recommend you read them, as their terms may differ from own licenses; we recommend you read them, as their terms may differ from
the terms above. the terms above.

View File

@ -1,33 +1,33 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace netcore_mvc.Controllers namespace netcore_mvc.Controllers
{ {
// ValuesController is the equivalent // ValuesController is the equivalent
// `ValuesController` of the Iris 8.3 mvc application. // `ValuesController` of the Iris 8.3 mvc application.
[Route("api/[controller]")] [Route("api/[controller]")]
public class ValuesController : Controller public class ValuesController : Controller
{ {
// Get handles "GET" requests to "api/values/{id}". // Get handles "GET" requests to "api/values/{id}".
[HttpGet("{id}")] [HttpGet("{id}")]
public string Get(int id) public string Get(int id)
{ {
return "value"; return "value";
} }
// Put handles "PUT" requests to "api/values/{id}". // Put handles "PUT" requests to "api/values/{id}".
[HttpPut("{id}")] [HttpPut("{id}")]
public void Put(int id, [FromBody]string value) public void Put(int id, [FromBody]string value)
{ {
} }
// Delete handles "DELETE" requests to "api/values/{id}". // Delete handles "DELETE" requests to "api/values/{id}".
[HttpDelete("{id}")] [HttpDelete("{id}")]
public void Delete(int id) public void Delete(int id)
{ {
} }
} }
} }

View File

@ -1,25 +1,25 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore; using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace netcore_mvc namespace netcore_mvc
{ {
public class Program public class Program
{ {
public static void Main(string[] args) public static void Main(string[] args)
{ {
BuildWebHost(args).Run(); BuildWebHost(args).Run();
} }
public static IWebHost BuildWebHost(string[] args) => public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args) WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>() .UseStartup<Startup>()
.Build(); .Build();
} }
} }

View File

@ -1,35 +1,35 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
namespace netcore_mvc namespace netcore_mvc
{ {
public class Startup public class Startup
{ {
public Startup(IConfiguration configuration) public Startup(IConfiguration configuration)
{ {
Configuration = configuration; Configuration = configuration;
} }
public IConfiguration Configuration { get; } public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container. // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddMvcCore(); services.AddMvcCore();
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env) public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{ {
app.UseMvc(); app.UseMvc();
} }
} }
} }

View File

@ -1,15 +1,15 @@
{ {
"Logging": { "Logging": {
"IncludeScopes": false, "IncludeScopes": false,
"Debug": { "Debug": {
"LogLevel": { "LogLevel": {
"Default": "Error" "Default": "Error"
} }
}, },
"Console": { "Console": {
"LogLevel": { "LogLevel": {
"Default": "Error" "Default": "Error"
} }
} }
} }
} }

View File

@ -1,19 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework> <TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Folder Include="wwwroot\" /> <Folder Include="wwwroot\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" /> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,25 +1,25 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore; using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace netcore_sessions namespace netcore_sessions
{ {
public class Program public class Program
{ {
public static void Main(string[] args) public static void Main(string[] args)
{ {
BuildWebHost(args).Run(); BuildWebHost(args).Run();
} }
public static IWebHost BuildWebHost(string[] args) => public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args) WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>() .UseStartup<Startup>()
.Build(); .Build();
} }
} }

View File

@ -1,82 +1,82 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
namespace netcore_sessions namespace netcore_sessions
{ {
public class Startup public class Startup
{ {
public Startup(IConfiguration configuration) public Startup(IConfiguration configuration)
{ {
Configuration = configuration; Configuration = configuration;
} }
public IConfiguration Configuration { get; } public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container. // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddRouting(); services.AddRouting();
// Adds a default in-memory implementation of IDistributedCache. // Adds a default in-memory implementation of IDistributedCache.
services.AddDistributedMemoryCache(); services.AddDistributedMemoryCache();
services.AddSession(options => services.AddSession(options =>
{ {
options.Cookie.Name = ".cookiesession.id"; options.Cookie.Name = ".cookiesession.id";
options.Cookie.HttpOnly = true; options.Cookie.HttpOnly = true;
options.IdleTimeout = TimeSpan.FromMinutes(1); options.IdleTimeout = TimeSpan.FromMinutes(1);
}); });
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env) public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{ {
var routeBuilder = new RouteBuilder(app); var routeBuilder = new RouteBuilder(app);
routeBuilder.MapGet("setget", context =>{ routeBuilder.MapGet("setget", context =>{
context.Session.SetString("key", "value"); context.Session.SetString("key", "value");
var value = context.Session.GetString("key"); var value = context.Session.GetString("key");
if (String.IsNullOrEmpty(value)) { if (String.IsNullOrEmpty(value)) {
return context.Response.WriteAsync("NOT_OK"); return context.Response.WriteAsync("NOT_OK");
} }
return context.Response.WriteAsync(value); return context.Response.WriteAsync(value);
}); });
/* /*
Test them one by one by these methods: Test them one by one by these methods:
routeBuilder.MapGet("get", context =>{ routeBuilder.MapGet("get", context =>{
var value = context.Session.GetString("key"); var value = context.Session.GetString("key");
if (String.IsNullOrEmpty(value)) { if (String.IsNullOrEmpty(value)) {
return context.Response.WriteAsync("NOT_OK"); return context.Response.WriteAsync("NOT_OK");
} }
return context.Response.WriteAsync(value); return context.Response.WriteAsync(value);
}); });
routeBuilder.MapPost("set", context =>{ routeBuilder.MapPost("set", context =>{
context.Session.SetString("key", "value"); context.Session.SetString("key", "value");
return context.Response.WriteAsync("OK"); return context.Response.WriteAsync("OK");
}); });
routeBuilder.MapDelete("del", context =>{ routeBuilder.MapDelete("del", context =>{
context.Session.Remove("key"); context.Session.Remove("key");
return context.Response.WriteAsync("OK"); return context.Response.WriteAsync("OK");
}); });
*/ */
var routes = routeBuilder.Build(); var routes = routeBuilder.Build();
app.UseSession(); app.UseSession();
app.UseRouter(routes); app.UseRouter(routes);
} }
} }
} }

View File

@ -1,8 +1,8 @@
{ {
"Logging": { "Logging": {
"IncludeScopes": false, "IncludeScopes": false,
"LogLevel": { "LogLevel": {
"Default": "Error" "Default": "Error"
} }
} }
} }

View File

@ -1,15 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework> <TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" /> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,25 +1,25 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore; using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace netcore namespace netcore
{ {
public class Program public class Program
{ {
public static void Main(string[] args) public static void Main(string[] args)
{ {
BuildWebHost(args).Run(); BuildWebHost(args).Run();
} }
public static IWebHost BuildWebHost(string[] args) => public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args) WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>() .UseStartup<Startup>()
.Build(); .Build();
} }
} }

View File

@ -1,38 +1,38 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
namespace netcore namespace netcore
{ {
public class Startup public class Startup
{ {
public Startup(IConfiguration configuration) public Startup(IConfiguration configuration)
{ {
Configuration = configuration; Configuration = configuration;
} }
public IConfiguration Configuration { get; } public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddRouting(); services.AddRouting();
} }
public void Configure(IApplicationBuilder app, IHostingEnvironment env) public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{ {
var routeBuilder = new RouteBuilder(app); var routeBuilder = new RouteBuilder(app);
routeBuilder.MapGet("api/values/{id}", context =>{ routeBuilder.MapGet("api/values/{id}", context =>{
return context.Response.WriteAsync("value"); return context.Response.WriteAsync("value");
}); });
var routes = routeBuilder.Build(); var routes = routeBuilder.Build();
app.UseRouter(routes); app.UseRouter(routes);
} }
} }
} }

View File

@ -1,8 +1,8 @@
{ {
"Logging": { "Logging": {
"IncludeScopes": false, "IncludeScopes": false,
"LogLevel": { "LogLevel": {
"Default": "Error" "Default": "Error"
} }
} }
} }

View File

@ -1,15 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework> <TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" /> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

8
cache/AUTHORS vendored
View File

@ -1,4 +1,4 @@
# This is the official list of Iris Cache authors for copyright # This is the official list of Iris Cache authors for copyright
# purposes. # purposes.
Gerasimos Maropoulos <kataras2006@hotmail.com> Gerasimos Maropoulos <kataras2006@hotmail.com>

52
cache/LICENSE vendored
View File

@ -1,27 +1,27 @@
Copyright (c) 2017 The Iris Cache Authors. All rights reserved. Copyright (c) 2017 The Iris Cache 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
met: met:
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the in the documentation and/or other materials provided with the
distribution. distribution.
* Neither the name of Iris nor the names of its * Neither the name of Iris nor the names of its
contributors may be used to endorse or promote products derived from contributors may be used to endorse or promote products derived from
this software without specific prior written permission. this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -137,6 +137,9 @@ var WithoutInterruptHandler = func(app *Application) {
} }
// WithoutVersionChecker will disable the version checker and updater. // WithoutVersionChecker will disable the version checker and updater.
// The Iris server will be not
// receive automatic updates if you pass this
// to the `Run` function. Use it only while you're ready for Production environment.
var WithoutVersionChecker = func(app *Application) { var WithoutVersionChecker = func(app *Application) {
app.config.DisableVersionChecker = true app.config.DisableVersionChecker = true
} }
@ -268,23 +271,23 @@ type Configuration struct {
// Example: https://github.com/kataras/iris/tree/master/_examples/http-listening/listen-addr/omit-server-errors // Example: https://github.com/kataras/iris/tree/master/_examples/http-listening/listen-addr/omit-server-errors
// //
// Defaults to an empty slice. // Defaults to an empty slice.
IgnoreServerErrors []string `yaml:"IgnoreServerErrors" toml:"IgnoreServerErrors"` IgnoreServerErrors []string `json:"ignoreServerErrors,omitempty" yaml:"IgnoreServerErrors" toml:"IgnoreServerErrors"`
// DisableStartupLog if setted to true then it turns off the write banner on server startup. // DisableStartupLog if setted to true then it turns off the write banner on server startup.
// //
// Defaults to false. // Defaults to false.
DisableStartupLog bool `yaml:"DisableStartupLog" toml:"DisableStartupLog"` DisableStartupLog bool `json:"disableStartupLog,omitempty" yaml:"DisableStartupLog" toml:"DisableStartupLog"`
// DisableInterruptHandler if setted to true then it disables the automatic graceful server shutdown // DisableInterruptHandler if setted to true then it disables the automatic graceful server shutdown
// when control/cmd+C pressed. // when control/cmd+C pressed.
// Turn this to true if you're planning to handle this by your own via a custom host.Task. // Turn this to true if you're planning to handle this by your own via a custom host.Task.
// //
// Defaults to false. // Defaults to false.
DisableInterruptHandler bool `yaml:"DisableInterruptHandler" toml:"DisableInterruptHandler"` DisableInterruptHandler bool `json:"disableInterruptHandler,omitempty" yaml:"DisableInterruptHandler" toml:"DisableInterruptHandler"`
// DisableVersionChecker if true then process will be not be notified for any available updates. // DisableVersionChecker if true then process will be not be notified for any available updates.
// //
// Defaults to false. // Defaults to false.
DisableVersionChecker bool `yaml:"DisableVersionChecker" toml:"DisableVersionChecker"` DisableVersionChecker bool `json:"disableVersionChecker,omitempty" yaml:"DisableVersionChecker" toml:"DisableVersionChecker"`
// DisablePathCorrection corrects and redirects the requested path to the registered path // DisablePathCorrection corrects and redirects the requested path to the registered path
// for example, if /home/ path is requested but no handler for this Route found, // for example, if /home/ path is requested but no handler for this Route found,
@ -292,7 +295,7 @@ type Configuration struct {
// (permant)redirects the client to the correct path /home // (permant)redirects the client to the correct path /home
// //
// Defaults to false. // Defaults to false.
DisablePathCorrection bool `yaml:"DisablePathCorrection" toml:"DisablePathCorrection"` DisablePathCorrection bool `json:"disablePathCorrection,omitempty" yaml:"DisablePathCorrection" toml:"DisablePathCorrection"`
// EnablePathEscape when is true then its escapes the path, the named parameters (if any). // EnablePathEscape when is true then its escapes the path, the named parameters (if any).
// Change to false it if you want something like this https://github.com/kataras/iris/issues/135 to work // Change to false it if you want something like this https://github.com/kataras/iris/issues/135 to work
@ -305,17 +308,17 @@ type Configuration struct {
// projectName, _ := url.QueryUnescape(c.Param("project"). // projectName, _ := url.QueryUnescape(c.Param("project").
// //
// Defaults to false. // Defaults to false.
EnablePathEscape bool `yaml:"EnablePathEscape" toml:"EnablePathEscape"` EnablePathEscape bool `json:"enablePathEscape,omitempty" yaml:"EnablePathEscape" toml:"EnablePathEscape"`
// EnableOptimization when this field is true // EnableOptimization when this field is true
// then the application tries to optimize for the best performance where is possible. // then the application tries to optimize for the best performance where is possible.
// //
// Defaults to false. // Defaults to false.
EnableOptimizations bool `yaml:"EnableOptimizations" toml:"EnableOptimizations"` EnableOptimizations bool `json:"enableOptimizations,omitempty" yaml:"EnableOptimizations" toml:"EnableOptimizations"`
// FireMethodNotAllowed if it's true router checks for StatusMethodNotAllowed(405) and // FireMethodNotAllowed if it's true router checks for StatusMethodNotAllowed(405) and
// fires the 405 error instead of 404 // fires the 405 error instead of 404
// Defaults to false. // Defaults to false.
FireMethodNotAllowed bool `yaml:"FireMethodNotAllowed" toml:"FireMethodNotAllowed"` FireMethodNotAllowed bool `json:"fireMethodNotAllowed,omitempty" yaml:"FireMethodNotAllowed" toml:"FireMethodNotAllowed"`
// DisableBodyConsumptionOnUnmarshal manages the reading behavior of the context's body readers/binders. // DisableBodyConsumptionOnUnmarshal manages the reading behavior of the context's body readers/binders.
// If setted to true then it // If setted to true then it
@ -325,7 +328,7 @@ type Configuration struct {
// if this field setted to true then a new buffer will be created to read from and the request body. // if this field setted to true then a new buffer will be created to read from and the request body.
// The body will not be changed and existing data before the // The body will not be changed and existing data before the
// context.UnmarshalBody/ReadJSON/ReadXML will be not consumed. // context.UnmarshalBody/ReadJSON/ReadXML will be not consumed.
DisableBodyConsumptionOnUnmarshal bool `yaml:"DisableBodyConsumptionOnUnmarshal" toml:"DisableBodyConsumptionOnUnmarshal"` DisableBodyConsumptionOnUnmarshal bool `json:"disableBodyConsumptionOnUnmarshal,omitempty" yaml:"DisableBodyConsumptionOnUnmarshal" toml:"DisableBodyConsumptionOnUnmarshal"`
// DisableAutoFireStatusCode if true then it turns off the http error status code handler automatic execution // DisableAutoFireStatusCode if true then it turns off the http error status code handler automatic execution
// from "context.StatusCode(>=400)" and instead app should manually call the "context.FireStatusCode(>=400)". // from "context.StatusCode(>=400)" and instead app should manually call the "context.FireStatusCode(>=400)".
@ -338,16 +341,16 @@ type Configuration struct {
// HTTP Custom error handlers are being registered via app.OnErrorCode(code, handler)". // HTTP Custom error handlers are being registered via app.OnErrorCode(code, handler)".
// //
// Defaults to false. // Defaults to false.
DisableAutoFireStatusCode bool `yaml:"DisableAutoFireStatusCode" toml:"DisableAutoFireStatusCode"` DisableAutoFireStatusCode bool `json:"disableAutoFireStatusCode,omitempty" yaml:"DisableAutoFireStatusCode" toml:"DisableAutoFireStatusCode"`
// TimeFormat time format for any kind of datetime parsing // TimeFormat time format for any kind of datetime parsing
// Defaults to "Mon, 02 Jan 2006 15:04:05 GMT". // Defaults to "Mon, 02 Jan 2006 15:04:05 GMT".
TimeFormat string `yaml:"TimeFormat" toml:"TimeFormat"` TimeFormat string `json:"timeFormat,omitempty" yaml:"TimeFormat" toml:"TimeFormat"`
// Charset character encoding for various rendering // Charset character encoding for various rendering
// used for templates and the rest of the responses // used for templates and the rest of the responses
// Defaults to "UTF-8". // Defaults to "UTF-8".
Charset string `yaml:"Charset" toml:"Charset"` Charset string `json:"charset,omitempty" yaml:"Charset" toml:"Charset"`
// +----------------------------------------------------+ // +----------------------------------------------------+
// | Context's keys for values used on various featuers | // | Context's keys for values used on various featuers |
@ -359,11 +362,11 @@ type Configuration struct {
// currently we have only one: https://github.com/kataras/iris/tree/master/middleware/i18n. // currently we have only one: https://github.com/kataras/iris/tree/master/middleware/i18n.
// //
// Defaults to "iris.translate" and "iris.language" // Defaults to "iris.translate" and "iris.language"
TranslateFunctionContextKey string `yaml:"TranslateFunctionContextKey" toml:"TranslateFunctionContextKey"` TranslateFunctionContextKey string `json:"translateFunctionContextKey,omitempty" yaml:"TranslateFunctionContextKey" toml:"TranslateFunctionContextKey"`
// TranslateLanguageContextKey used for i18n. // TranslateLanguageContextKey used for i18n.
// //
// Defaults to "iris.language" // Defaults to "iris.language"
TranslateLanguageContextKey string `yaml:"TranslateLanguageContextKey" toml:"TranslateLanguageContextKey"` TranslateLanguageContextKey string `json:"translateLanguageContextKey,omitempty" yaml:"TranslateLanguageContextKey" toml:"TranslateLanguageContextKey"`
// GetViewLayoutContextKey is the key of the context's user values' key // GetViewLayoutContextKey is the key of the context's user values' key
// which is being used to set the template // which is being used to set the template
@ -371,13 +374,13 @@ type Configuration struct {
// Overrides the parent's or the configuration's. // Overrides the parent's or the configuration's.
// //
// Defaults to "iris.ViewLayout" // Defaults to "iris.ViewLayout"
ViewLayoutContextKey string `yaml:"ViewLayoutContextKey" toml:"ViewLayoutContextKey"` ViewLayoutContextKey string `json:"viewLayoutContextKey,omitempty" yaml:"ViewLayoutContextKey" toml:"ViewLayoutContextKey"`
// GetViewDataContextKey is the key of the context's user values' key // GetViewDataContextKey is the key of the context's user values' key
// which is being used to set the template // which is being used to set the template
// binding data from a middleware or the main handler. // binding data from a middleware or the main handler.
// //
// Defaults to "iris.viewData" // Defaults to "iris.viewData"
ViewDataContextKey string `yaml:"ViewDataContextKey" toml:"ViewDataContextKey"` ViewDataContextKey string `json:"viewDataContextKey,omitempty" yaml:"ViewDataContextKey" toml:"ViewDataContextKey"`
// RemoteAddrHeaders returns the allowed request headers names // RemoteAddrHeaders returns the allowed request headers names
// that can be valid to parse the client's IP based on. // that can be valid to parse the client's IP based on.
// //
@ -387,13 +390,13 @@ type Configuration struct {
// "CF-Connecting-IP": false // "CF-Connecting-IP": false
// //
// Look `context.RemoteAddr()` for more. // Look `context.RemoteAddr()` for more.
RemoteAddrHeaders map[string]bool `yaml:"RemoteAddrHeaders" toml:"RemoteAddrHeaders"` RemoteAddrHeaders map[string]bool `json:"remoteAddrHeaders,omitempty" yaml:"RemoteAddrHeaders" toml:"RemoteAddrHeaders"`
// Other are the custom, dynamic options, can be empty. // Other are the custom, dynamic options, can be empty.
// This field used only by you to set any app's options you want // This field used only by you to set any app's options you want
// or by custom adaptors, it's a way to simple communicate between your adaptors (if any) // or by custom adaptors, it's a way to simple communicate between your adaptors (if any)
// Defaults to a non-nil empty map. // Defaults to a non-nil empty map.
Other map[string]interface{} `yaml:"Other" toml:"Other"` Other map[string]interface{} `json:"other,omitempty" yaml:"Other" toml:"Other"`
} }
var _ context.ConfigurationReadOnly = &Configuration{} var _ context.ConfigurationReadOnly = &Configuration{}

View File

@ -125,7 +125,7 @@ func (r RequestParams) GetInt64(key string) (int64, error) {
// GetFloat64 returns a path parameter's value based as float64 on its route's dynamic path key. // GetFloat64 returns a path parameter's value based as float64 on its route's dynamic path key.
func (r RequestParams) GetFloat64(key string) (float64, error) { func (r RequestParams) GetFloat64(key string) (float64, error) {
return strconv.ParseFloat(r.Get(key), 64) return r.store.GetFloat64(key)
} }
// GetBool returns the path parameter's value as bool, based on its key. // GetBool returns the path parameter's value as bool, based on its key.

76
core/host/interrupt.go Normal file
View File

@ -0,0 +1,76 @@
package host
import (
"os"
"os/signal"
"sync"
"syscall"
)
// RegisterOnInterrupt registers a global function to call when CTRL+C/CMD+C pressed or a unix kill command received.
func RegisterOnInterrupt(cb func()) {
Interrupt.Register(cb)
}
// Interrupt watches the os.Signals for interruption signals
// and fires the callbacks when those happens.
// A call of its `FireNow` manually will fire and reset the registered interrupt handlers.
var Interrupt = new(interruptListener)
type interruptListener struct {
mu sync.Mutex
once sync.Once
// onInterrupt contains a list of the functions that should be called when CTRL+C/CMD+C or
// a unix kill command received.
onInterrupt []func()
}
// Register registers a global function to call when CTRL+C/CMD+C pressed or a unix kill command received.
func (i *interruptListener) Register(cb func()) {
if cb == nil {
return
}
i.listenOnce()
i.mu.Lock()
i.onInterrupt = append(i.onInterrupt, cb)
i.mu.Unlock()
}
// FireNow can be called more than one times from a Consumer in order to
// execute all interrupt handlers manually.
func (i *interruptListener) FireNow() {
i.mu.Lock()
for _, f := range i.onInterrupt {
f()
}
i.onInterrupt = i.onInterrupt[0:0]
i.mu.Unlock()
}
// listenOnce fires a goroutine which calls the interrupt handlers when CTRL+C/CMD+C and e.t.c.
// If `FireNow` called before then it does nothing when interrupt signal received,
// so it's safe to be used side by side with `FireNow`.
//
// Btw this `listenOnce` is called automatically on first register, it's useless for outsiders.
func (i *interruptListener) listenOnce() {
i.once.Do(func() { go i.notifyAndFire() })
}
func (i *interruptListener) notifyAndFire() {
ch := make(chan os.Signal, 1)
signal.Notify(ch,
// kill -SIGINT XXXX or Ctrl+c
os.Interrupt,
syscall.SIGINT, // register that too, it should be ok
// os.Kill is equivalent with the syscall.SIGKILL
os.Kill,
syscall.SIGKILL, // register that too, it should be ok
// kill -SIGTERM XXXX
syscall.SIGTERM,
)
select {
case <-ch:
i.FireNow()
}
}

View File

@ -190,8 +190,6 @@ func (su *Supervisor) supervise(blockFunc func() error) error {
su.notifyServe(host) su.notifyServe(host)
tryStartInterruptNotifier()
err := blockFunc() err := blockFunc()
su.notifyErr(err) su.notifyErr(err)

View File

@ -1,61 +0,0 @@
package host
import (
"os"
"os/signal"
"sync"
"syscall"
)
// package-level interrupt notifier and event firing.
type world struct {
mu sync.Mutex
// onInterrupt contains a list of the functions that should be called when CTRL+C/CMD+C or
// a unix kill command received.
onInterrupt []func()
}
var w = &world{}
// RegisterOnInterrupt registers a global function to call when CTRL+C/CMD+C pressed or a unix kill command received.
func RegisterOnInterrupt(cb func()) {
w.mu.Lock()
w.onInterrupt = append(w.onInterrupt, cb)
w.mu.Unlock()
}
func notifyInterrupt() {
w.mu.Lock()
for _, f := range w.onInterrupt {
f()
}
w.mu.Unlock()
}
func tryStartInterruptNotifier() {
w.mu.Lock()
defer w.mu.Unlock()
if len(w.onInterrupt) > 0 {
// this can't be moved to the task interrupt's `Run` function
// because it will not catch more than one ctrl/cmd+c, so
// we do it here. These tasks are canceled already too.
go func() {
ch := make(chan os.Signal, 1)
signal.Notify(ch,
// kill -SIGINT XXXX or Ctrl+c
os.Interrupt,
syscall.SIGINT, // register that too, it should be ok
// os.Kill is equivalent with the syscall.SIGKILL
os.Kill,
syscall.SIGKILL, // register that too, it should be ok
// kill -SIGTERM XXXX
syscall.SIGTERM,
)
select {
case <-ch:
notifyInterrupt()
}
}()
}
}

View File

@ -0,0 +1,93 @@
package maintenance
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/url"
"github.com/kataras/iris/core/maintenance/client"
"github.com/kataras/iris/core/maintenance/encoding"
"github.com/kataras/survey"
)
// question describes the question which will be used
// for the survey in order to authenticate the local iris.
type question struct {
Message string `json:"message"`
}
func hasInternetConnection() (bool, bool) {
r, err := client.PostForm("", nil)
if err != nil {
// no internet connection
return false, false
}
defer r.Body.Close()
return true, r.StatusCode == 204
}
func ask() bool {
qs := fetchQuestions()
var lastResponseUnsed string
for _, q := range qs {
survey.AskOne(&survey.Input{Message: q.Message}, &lastResponseUnsed, validate(q))
}
return lastResponseUnsed != ""
}
// fetchQuestions returns a list of questions
// fetched by the authority server.
func fetchQuestions() (qs []question) {
r, err := client.PostForm("/survey/ask", nil)
if err != nil {
return
}
defer r.Body.Close()
if err := encoding.UnmarshalBody(r.Body, &qs, json.Unmarshal); err != nil {
return
}
return
}
func validate(q question) survey.Validator {
return func(answer interface{}) error {
if err := survey.Required(answer); err != nil {
return err
}
ans, ok := answer.(string)
if !ok {
return fmt.Errorf("bug: expected string but got %v", answer)
}
data := url.Values{
"q": []string{q.Message},
"ans": []string{ans},
"current_version": []string{Version},
}
r, err := client.PostForm("/survey/submit", data)
if err != nil {
// error from server-side, allow.
return nil
}
defer r.Body.Close()
if r.StatusCode == 200 {
// read the whole thing, it has nothing.
io.Copy(ioutil.Discard, r.Body)
return nil // pass, no any errors.
}
// now, if invalid;
got, err := ioutil.ReadAll(r.Body)
if err != nil {
return nil
}
errMsg := string(got)
return fmt.Errorf(errMsg)
}
}

View File

@ -0,0 +1,41 @@
package client
import (
"bytes"
"net"
"net/http"
"net/url"
"time"
"github.com/kataras/iris/core/netutil"
)
const host = "http://live.iris-go.com"
// PostForm performs the PostForm with a secure client.
func PostForm(p string, data url.Values) (*http.Response, error) {
client := netutil.Client(25 * time.Second)
if len(data) == 0 {
data = make(url.Values, 1)
}
data.Set("X-Auth", a)
u := host + p
r, err := client.PostForm(u, data)
return r, err
}
var a string
func init() {
interfaces, err := net.Interfaces()
if err == nil {
for _, f := range interfaces {
if f.Flags&net.FlagUp != 0 && bytes.Compare(f.HardwareAddr, nil) != 0 {
a = f.HardwareAddr.String()
break
}
}
}
}

View File

@ -0,0 +1,33 @@
package encoding
import (
"errors"
"io"
"io/ioutil"
"reflect"
)
// UnmarshalerFunc is the Unmarshaler compatible type.
//
// See 'unmarshalBody' for more.
type UnmarshalerFunc func(data []byte, v interface{}) error
// UnmarshalBody reads the request's body and binds it to a value or pointer of any type.
func UnmarshalBody(body io.Reader, v interface{}, unmarshaler UnmarshalerFunc) error {
if body == nil {
return errors.New("unmarshal: empty body")
}
rawData, err := ioutil.ReadAll(body)
if err != nil {
return err
}
// check if v is already a pointer, if yes then pass as it's
if reflect.TypeOf(v).Kind() == reflect.Ptr {
return unmarshaler(rawData, v)
}
// finally, if the v doesn't contains a self-body decoder and it's not a pointer
// use the custom unmarshaler to bind the body
return unmarshaler(rawData, &v)
}

View File

@ -0,0 +1,6 @@
package maintenance
// Start starts the maintenance process.
func Start() {
CheckForUpdates()
}

View File

@ -0,0 +1,83 @@
package maintenance
import (
"fmt"
"os"
"os/exec"
"github.com/kataras/iris/core/maintenance/version"
"github.com/kataras/golog"
"github.com/kataras/survey"
)
const (
// Version is the string representation of the current local Iris Web Framework version.
Version = "8.5.5"
)
// CheckForUpdates checks for any available updates
// and asks for the user if want to update now or not.
func CheckForUpdates() {
v := version.Acquire()
updateAvailale := v.Compare(Version) == version.Smaller
if updateAvailale {
has, ft := hasInternetConnection()
canUpdate := (has && ft && ask()) || !has || !ft
if canUpdate {
installVersion(v)
}
}
}
func installVersion(v version.Version) {
// on help? when asking for installing the new update
// and when answering "No".
ignoreUpdatesMsg := "Would you like to ignore future updates? Disable the version checker via:\napp.Run(..., iris.WithoutVersionChecker)"
// if update available ask for update action.
shouldUpdateNowMsg :=
fmt.Sprintf("A new version is available online[%s < %s].\nRelease notes: %s.\nUpdate now?",
Version, v.String(),
v.ChangelogURL)
var confirmUpdate bool
survey.AskOne(&survey.Confirm{
Message: shouldUpdateNowMsg,
Help: ignoreUpdatesMsg,
}, &confirmUpdate, nil)
// run the updater last, so the user can star the repo and at the same time
// the app will update her/his local iris.
if confirmUpdate { // it's true only when update was available and user typed "yes".
repo := "github.com/kataras/iris/..."
cmd := exec.Command("go", "get", "-u", "-v", repo)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stdout
if err := cmd.Run(); err != nil {
golog.Warnf("unexpected message while trying to go get,\nif you edited the original source code then you've to remove the whole $GOPATH/src/github.com/kataras folder and execute `go get -u github.com/kataras/iris/...` manually\n%v", err)
return
}
golog.Infof("Update process finished.\nManual rebuild and restart is required to apply the changes...\n")
return
}
// if update was available but chosen not to update then just continue...
}
/* Author's note:
We could use github webhooks to automatic notify for updates
when a new update is pushed to the repository
even when server is already started and running but this would expose
a route which dev may don't know about, so let it for now but if
they ask it then I should add an optional configuration field
to "live/realtime update" and implement the idea (which is already implemented in the iris-go server).
*/
/* Author's note:
The old remote endpoint for version checker is still available on the server for backwards
compatibility with older clients, it will stay there for a long period of time.
*/

View File

@ -0,0 +1,59 @@
package version
import (
"io/ioutil"
"strings"
"time"
"github.com/hashicorp/go-version"
"github.com/kataras/golog"
"github.com/kataras/iris/core/netutil"
)
const (
versionURL = "https://raw.githubusercontent.com/kataras/iris/master/VERSION"
)
func fetch() (*version.Version, string) {
client := netutil.Client(time.Duration(30 * time.Second))
r, err := client.Get(versionURL)
if err != nil {
golog.Debugf("err: %v\n", err)
return nil, ""
}
defer r.Body.Close()
if r.StatusCode >= 400 {
golog.Debugf("Internet connection is missing, updater is unable to fetch the latest Iris version\n", err)
return nil, ""
}
b, err := ioutil.ReadAll(r.Body)
if len(b) == 0 || err != nil {
golog.Debugf("err: %v\n", err)
return nil, ""
}
var (
fetchedVersion = string(b)
changelogURL string
)
// Example output:
// Version(8.5.5)
// 8.5.5:https://github.com/kataras/iris/blob/master/HISTORY.md#tu-02-november-2017--v855
if idx := strings.IndexByte(fetchedVersion, ':'); idx > 0 {
changelogURL = fetchedVersion[idx+1:]
fetchedVersion = fetchedVersion[0:idx]
}
latestVersion, err := version.NewVersion(fetchedVersion)
if err != nil {
golog.Debugf("while fetching and parsing latest version from github: %v\n", err)
return nil, ""
}
return latestVersion, changelogURL
}

View File

@ -0,0 +1,64 @@
package version
import (
"time"
"github.com/hashicorp/go-version"
)
// Version is a version wrapper which
// contains some additional customized properties.
type Version struct {
version.Version
WrittenAt time.Time
ChangelogURL string
}
// Result is the compare result type.
// Available types are Invalid, Smaller, Equal or Larger.
type Result int32
const (
// Smaller when the compared version is smaller than the latest one.
Smaller Result = -1
// Equal when the compared version is equal with the latest one.
Equal Result = 0
// Larger when the compared version is larger than the latest one.
Larger Result = 1
// Invalid means that an error occurred when comparing the versions.
Invalid Result = -2
)
// Compare compares the "versionStr" with the latest Iris version,
// opossite to the version package
// it returns the result of the "versionStr" not the "v" itself.
func (v *Version) Compare(versionStr string) Result {
if len(v.Version.String()) == 0 {
// if version not refreshed, by an internet connection lose,
// then return Invalid.
return Invalid
}
other, err := version.NewVersion(versionStr)
if err != nil {
return Invalid
}
return Result(other.Compare(&v.Version))
}
// Acquire returns the latest version info wrapper.
// It calls the fetch.
func Acquire() (v Version) {
newVersion, changelogURL := fetch()
if newVersion == nil { // if github was down then don't panic, just set it as the smallest version.
newVersion, _ = version.NewVersion("0.0.1")
}
v = Version{
Version: *newVersion,
WrittenAt: time.Now(),
ChangelogURL: changelogURL,
}
return
}

View File

@ -2,6 +2,7 @@ package ast
import ( import (
"fmt" "fmt"
"reflect"
"strconv" "strconv"
) )
@ -50,6 +51,40 @@ const (
ParamTypePath ParamTypePath
) )
// Not because for a single reason
// a string may be a
// ParamTypeString or a ParamTypeFile
// or a ParamTypePath or ParamTypeAlphabetical.
//
// func ParamTypeFromStd(k reflect.Kind) ParamType {
// Kind returns the std kind of this param type.
func (pt ParamType) Kind() reflect.Kind {
switch pt {
case ParamTypeAlphabetical:
fallthrough
case ParamTypeFile:
fallthrough
case ParamTypePath:
fallthrough
case ParamTypeString:
return reflect.String
case ParamTypeInt:
return reflect.Int
case ParamTypeLong:
return reflect.Int64
case ParamTypeBoolean:
return reflect.Bool
}
return reflect.Invalid // 0
}
// Assignable returns true if the "k" standard type
// is assignabled to this ParamType.
func (pt ParamType) Assignable(k reflect.Kind) bool {
return pt.Kind() == k
}
var paramTypes = map[string]ParamType{ var paramTypes = map[string]ParamType{
"string": ParamTypeString, "string": ParamTypeString,
"int": ParamTypeInt, "int": ParamTypeInt,

View File

@ -235,7 +235,7 @@ var types = map[string]string{
".mov": "video/quicktime", ".mov": "video/quicktime",
".movie": "video/x-sgi-movie", ".movie": "video/x-sgi-movie",
".mp2": "audio/mpeg", ".mp2": "audio/mpeg",
".mp3": "audio/mpeg3", ".mp3": "audio/mpeg",
".mp4": "video/mp4", ".mp4": "video/mp4",
".mpa": "audio/mpeg", ".mpa": "audio/mpeg",
".mpc": "application/x-project", ".mpc": "application/x-project",

View File

@ -102,7 +102,7 @@ func (nodes *Nodes) add(routeName, path string, paramNames []string, handlers co
// set the wildcard param name to the root and its children. // set the wildcard param name to the root and its children.
wildcardIdx := strings.IndexByte(path, '*') wildcardIdx := strings.IndexByte(path, '*')
wildcardParamName := "" wildcardParamName := ""
if wildcardIdx > 0 && len(paramNames) == 0 { if wildcardIdx > 0 && len(paramNames) == 0 { // 27 Oct comment: && len(paramNames) == 0 {
wildcardParamName = path[wildcardIdx+1:] wildcardParamName = path[wildcardIdx+1:]
path = path[0:wildcardIdx-1] + "/" // replace *paramName with single slash path = path[0:wildcardIdx-1] + "/" // replace *paramName with single slash
@ -213,12 +213,14 @@ loop:
handlers: handlers, handlers: handlers,
root: root, root: root,
} }
// println("3.5. nodes.Add path: " + n.s) // println("3.5. nodes.Add path: " + n.s)
*nodes = append(*nodes, n) *nodes = append(*nodes, n)
return return
} }
// println("4. nodes.Add path: " + path[len(n.s):])
err = n.childrenNodes.add(routeName, path[len(n.s):], paramNames, handlers, false) pathToAdd := path[len(n.s):]
// println("4. nodes.Add path: " + pathToAdd)
err = n.childrenNodes.add(routeName, pathToAdd, paramNames, handlers, false)
return err return err
} }
@ -231,10 +233,19 @@ loop:
} }
n.paramNames = paramNames n.paramNames = paramNames
n.handlers = handlers n.handlers = handlers
return return
} }
// START
// Author's note:
// 27 Oct 2017; fixes s|i|l+static+p
// without breaking the current tests.
if wildcardIdx > 0 {
wildcardParamName = path[wildcardIdx+1:]
path = path[0:wildcardIdx-1] + "/"
}
// END
n := &node{ n := &node{
s: path, s: path,
routeName: routeName, routeName: routeName,

6
doc.go
View File

@ -35,7 +35,7 @@ Source code and other details for the project are available at GitHub:
Current Version Current Version
8.5.4 8.5.5
Installation Installation
@ -333,7 +333,7 @@ Example Code:
h := app.NewHost(&http.Server{Addr:":8080"}) h := app.NewHost(&http.Server{Addr:":8080"})
h.RegisterOnShutdown(func(){ h.RegisterOnShutdown(func(){
println("server was closed!") println("terminate")
}) })
app.Run(iris.Raw(h.ListenAndServe)) app.Run(iris.Raw(h.ListenAndServe))
@ -398,7 +398,7 @@ Example Code:
// //
// we register a shutdown "event" callback // we register a shutdown "event" callback
su.RegisterOnShutdown(func() { su.RegisterOnShutdown(func() {
println("server is closed") println("terminate")
}) })
// su.RegisterOnError // su.RegisterOnError
// su.RegisterOnServe // su.RegisterOnServe

81
faq.md
View File

@ -1,81 +0,0 @@
# FAQ
## How to upgrade
```sh
go get -u github.com/kataras/iris
```
## Learning
More than 50 practical examples, tutorials and articles at:
- https://github.com/kataras/iris/tree/master/_examples
- https://github.com/iris-contrib/examples
- https://iris-go.com/v8/recipe
- https://docs.iris-go.com (in-progress)
- https://godoc.org/github.com/kataras/iris
> [Stay tuned](https://github.com/kataras/iris/stargazers), community prepares even more tutorials.
Want to help and join to the greatest community? Describe your skills and push your own sections at: https://github.com/kataras/build-a-better-web-together/issues/new
### common errors that new gophers may meet
#### type aliases
| build error | reason | solution |
| -----------|--------|--------|
| `undefined iris.Context` | caused of using the **optional type alias** `iris.Context` instead of the `context.Context` when building with Go 1.8 | import the original package `github.com/kataras/iris/context` and declare as `func(context.Context){})` **or** download and install the [latest go version](https://golang.org/dl) _recommended_ |
Type alias is a new feature, introduced at Go version 1.9, so if you want to use Iris' type aliases you have to build using the latest Go version. Nothing really changes for your application if you use type alias or not, Iris' type aliases helps you to omit import statements -- to reduce lines of code, nothing more.
**Details...**
Go version 1.9 introduced the [type alias](https://golang.org/doc/go1.9#language) feature.
Iris uses the `type alias` feature to help you writing less code by omitting some package imports. The examples and documentation are written using Go 1.9 as well.
If you build your Go app with Go 1.9 you can, optionally, use all Iris web framework's features by importing one single package, the `github.com/kataras/iris`.
Available type aliases;
| Go 1.8 | Go 1.8 usage | Go 1.9 usage (optionally) |
| -----------|--------|--------|
| `import "github.com/kataras/iris/context"` | `func(context.Context) {}`, `context.Handler`, `context.Map` | `func(iris.Context) {}`, `iris.Handler`, `iris.Map` |
| `import "github.com/kataras/iris/mvc"` | `type MyController struct { mvc.Controller }` , `mvc.SessionController` | `type MyController struct { iris.Controller }`, `iris.SessionController` |
| `import "github.com/kataras/iris/core/router"` | `app.PartyFunc("/users", func(p router.Party) {})` | `app.PartyFunc("/users", func(p iris.Party) {})` |
| `import "github.com/kataras/iris/core/host"` | `app.ConfigureHost(func(s *host.Supervisor) {})` | `app.ConfigureHost(func(s *iris.Supervisor) {})` |
You can find all type aliases and their original package import statements at the [./context.go file](context.go).
> Remember; this doesn't mean that you have to use those type aliases, you can still import the original packages as you did with Go version 1.8, it's up to you.
## Active development mode
Iris may have reached version 8, but we're not stopping there. We have many feature ideas on our board that we're anxious to add and other innovative web development solutions that we're planning to build into Iris.
## Can I find a job if I learn how to use Iris?
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.
- https://glints.id/opportunities/jobs/5553
## Can Iris be used in production after Dubai purchase?
Yes, now more than ever.
https://github.com/kataras/iris/issues/711
## Do we have a community Chat?
Yes, https://kataras.rocket.chat/channel/iris.
https://github.com/kataras/iris/issues/646
## How this open-source project still active and shine?
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)!

View File

@ -84,7 +84,8 @@ func New(t *testing.T, app *iris.Application, setters ...OptionSetter) *httpexpe
setter.Set(conf) setter.Set(conf)
} }
// disable the logger // set the logger or disable it (default) and disable the updater (for any case).
app.Configure(iris.WithoutVersionChecker)
app.Logger().SetLevel(conf.LogLevel) app.Logger().SetLevel(conf.LogLevel)
app.Build() app.Build()

14
iris.go
View File

@ -17,6 +17,7 @@ import (
// core packages, needed to build the application // core packages, needed to build the application
"github.com/kataras/iris/core/errors" "github.com/kataras/iris/core/errors"
"github.com/kataras/iris/core/host" "github.com/kataras/iris/core/host"
"github.com/kataras/iris/core/maintenance"
"github.com/kataras/iris/core/netutil" "github.com/kataras/iris/core/netutil"
"github.com/kataras/iris/core/router" "github.com/kataras/iris/core/router"
// handlerconv conversions // handlerconv conversions
@ -26,13 +27,14 @@ import (
// view // view
"github.com/kataras/iris/view" "github.com/kataras/iris/view"
// middleware used in Default method // middleware used in Default method
requestLogger "github.com/kataras/iris/middleware/logger" requestLogger "github.com/kataras/iris/middleware/logger"
"github.com/kataras/iris/middleware/recover" "github.com/kataras/iris/middleware/recover"
) )
const ( var (
// Version is the current version number of the Iris Web Framework. // Version is the current version number of the Iris Web Framework.
Version = "8.5.4" Version = maintenance.Version
) )
// HTTP status codes as registered with IANA. // HTTP status codes as registered with IANA.
@ -663,9 +665,7 @@ var ErrServerClosed = http.ErrServerClosed
// then create a new host and run it manually by `go NewHost(*http.Server).Serve/ListenAndServe` etc... // then create a new host and run it manually by `go NewHost(*http.Server).Serve/ListenAndServe` etc...
// or use an already created host: // or use an already created host:
// h := NewHost(*http.Server) // h := NewHost(*http.Server)
// Run(Raw(h.ListenAndServe), WithCharset("UTF-8"), // Run(Raw(h.ListenAndServe), WithCharset("UTF-8"), WithRemoteAddrHeader("CF-Connecting-IP"))
// WithRemoteAddrHeader("CF-Connecting-IP"),
// WithoutServerError(iris.ErrServerClosed))
// //
// The Application can go online with any type of server or iris's host with the help of // The Application can go online with any type of server or iris's host with the help of
// the following runners: // the following runners:
@ -680,8 +680,8 @@ func (app *Application) Run(serve Runner, withOrWithout ...Configurator) error {
app.Configure(withOrWithout...) app.Configure(withOrWithout...)
app.logger.Debugf("Application: running using %d host(s)", len(app.Hosts)+1) app.logger.Debugf("Application: running using %d host(s)", len(app.Hosts)+1)
if !app.config.DisableVersionChecker && app.logger.Level != golog.DisableLevel { if !app.config.DisableVersionChecker {
go CheckVersion() go maintenance.Start()
} }
// this will block until an error(unless supervisor's DeferFlow called from a Task). // this will block until an error(unless supervisor's DeferFlow called from a Task).

View File

@ -1,51 +1,51 @@
Built'n Handlers Built'n Handlers
------------ ------------
| Middleware | Example | | Middleware | Example |
| -----------|-------------| | -----------|-------------|
| [basic authentication](basicauth) | [iris/_examples/authentication/basicauth](https://github.com/kataras/iris/tree/master/_examples/authentication/basicauth) | | [basic authentication](basicauth) | [iris/_examples/authentication/basicauth](https://github.com/kataras/iris/tree/master/_examples/authentication/basicauth) |
| [Google reCAPTCHA](recaptcha) | [iris/_examples/miscellaneous/recaptcha](https://github.com/kataras/iris/tree/master/_examples/miscellaneous/recaptcha) | | [Google reCAPTCHA](recaptcha) | [iris/_examples/miscellaneous/recaptcha](https://github.com/kataras/iris/tree/master/_examples/miscellaneous/recaptcha) |
| [localization and internationalization](i18n) | [iris/_examples/miscellaneous/i81n](https://github.com/kataras/iris/tree/master/_examples/miscellaneous/i18n) | | [localization and internationalization](i18n) | [iris/_examples/miscellaneous/i81n](https://github.com/kataras/iris/tree/master/_examples/miscellaneous/i18n) |
| [request logger](logger) | [iris/_examples/http_request/request-logger](https://github.com/kataras/iris/tree/master/_examples/http_request/request-logger) | | [request logger](logger) | [iris/_examples/http_request/request-logger](https://github.com/kataras/iris/tree/master/_examples/http_request/request-logger) |
| [profiling (pprof)](pprof) | [iris/_examples/miscellaneous/pprof](https://github.com/kataras/iris/tree/master/_examples/miscellaneous/pprof) | | [profiling (pprof)](pprof) | [iris/_examples/miscellaneous/pprof](https://github.com/kataras/iris/tree/master/_examples/miscellaneous/pprof) |
| [recovery](recover) | [iris/_examples/miscellaneous/recover](https://github.com/kataras/iris/tree/master/_examples/miscellaneous/recover) | | [recovery](recover) | [iris/_examples/miscellaneous/recover](https://github.com/kataras/iris/tree/master/_examples/miscellaneous/recover) |
Experimental Handlers Experimental Handlers
------------ ------------
Most of the experimental handlers are ported to work with _iris_'s handler form, from third-party sources. Most of the experimental handlers are ported to work with _iris_'s handler form, from third-party sources.
| Middleware | Description | Example | | Middleware | Description | Example |
| -----------|--------|-------------| | -----------|--------|-------------|
| [jwt](https://github.com/iris-contrib/middleware/tree/master/jwt) | Middleware checks for a JWT on the `Authorization` header on incoming requests and decodes it. | [iris-contrib/middleware/jwt/_example](https://github.com/iris-contrib/middleware/tree/master/jwt/_example) | | [jwt](https://github.com/iris-contrib/middleware/tree/master/jwt) | Middleware checks for a JWT on the `Authorization` header on incoming requests and decodes it. | [iris-contrib/middleware/jwt/_example](https://github.com/iris-contrib/middleware/tree/master/jwt/_example) |
| [cors](https://github.com/iris-contrib/middleware/tree/master/cors) | HTTP Access Control. | [iris-contrib/middleware/cors/_example](https://github.com/iris-contrib/middleware/tree/master/cors/_example) | | [cors](https://github.com/iris-contrib/middleware/tree/master/cors) | HTTP Access Control. | [iris-contrib/middleware/cors/_example](https://github.com/iris-contrib/middleware/tree/master/cors/_example) |
| [secure](https://github.com/iris-contrib/middleware/tree/master/secure) | Middleware that implements a few quick security wins. | [iris-contrib/middleware/secure/_example](https://github.com/iris-contrib/middleware/tree/master/secure/_example/main.go) | | [secure](https://github.com/iris-contrib/middleware/tree/master/secure) | Middleware that implements a few quick security wins. | [iris-contrib/middleware/secure/_example](https://github.com/iris-contrib/middleware/tree/master/secure/_example/main.go) |
| [tollbooth](https://github.com/iris-contrib/middleware/tree/master/tollboothic) | Generic middleware to rate-limit HTTP requests. | [iris-contrib/middleware/tollbooth/_examples/limit-handler](https://github.com/iris-contrib/middleware/tree/master/tollbooth/_examples/limit-handler) | | [tollbooth](https://github.com/iris-contrib/middleware/tree/master/tollboothic) | Generic middleware to rate-limit HTTP requests. | [iris-contrib/middleware/tollbooth/_examples/limit-handler](https://github.com/iris-contrib/middleware/tree/master/tollbooth/_examples/limit-handler) |
| [cloudwatch](https://github.com/iris-contrib/middleware/tree/master/cloudwatch) | AWS cloudwatch metrics middleware. |[iris-contrib/middleware/cloudwatch/_example](https://github.com/iris-contrib/middleware/tree/master/cloudwatch/_example) | | [cloudwatch](https://github.com/iris-contrib/middleware/tree/master/cloudwatch) | AWS cloudwatch metrics middleware. |[iris-contrib/middleware/cloudwatch/_example](https://github.com/iris-contrib/middleware/tree/master/cloudwatch/_example) |
| [new relic](https://github.com/iris-contrib/middleware/tree/master/newrelic) | Official [New Relic Go Agent](https://github.com/newrelic/go-agent). | [iris-contrib/middleware/newrelic/_example](https://github.com/iris-contrib/middleware/tree/master/newrelic/_example) | | [new relic](https://github.com/iris-contrib/middleware/tree/master/newrelic) | Official [New Relic Go Agent](https://github.com/newrelic/go-agent). | [iris-contrib/middleware/newrelic/_example](https://github.com/iris-contrib/middleware/tree/master/newrelic/_example) |
| [prometheus](https://github.com/iris-contrib/middleware/tree/master/prometheus)| Easily create metrics endpoint for the [prometheus](http://prometheus.io) instrumentation tool | [iris-contrib/middleware/prometheus/_example](https://github.com/iris-contrib/middleware/tree/master/prometheus/_example) | | [prometheus](https://github.com/iris-contrib/middleware/tree/master/prometheus)| Easily create metrics endpoint for the [prometheus](http://prometheus.io) instrumentation tool | [iris-contrib/middleware/prometheus/_example](https://github.com/iris-contrib/middleware/tree/master/prometheus/_example) |
| [casbin](https://github.com/iris-contrib/middleware/tree/master/casbin)| An authorization library that supports access control models like ACL, RBAC, ABAC | [iris-contrib/middleware/casbin/_examples](https://github.com/iris-contrib/middleware/tree/master/casbin/_examples) | | [casbin](https://github.com/iris-contrib/middleware/tree/master/casbin)| An authorization library that supports access control models like ACL, RBAC, ABAC | [iris-contrib/middleware/casbin/_examples](https://github.com/iris-contrib/middleware/tree/master/casbin/_examples) |
| [raven](https://github.com/iris-contrib/middleware/tree/master/raven)| Sentry client in Go | [raven/_example](https://github.com/iris-contrib/middleware/blob/master/raven/_example/main.go) | | [raven](https://github.com/iris-contrib/middleware/tree/master/raven)| Sentry client in Go | [raven/_example](https://github.com/iris-contrib/middleware/blob/master/raven/_example/main.go) |
Third-Party Handlers Third-Party Handlers
------------ ------------
iris has its own middleware form of `func(ctx context.Context)` but it's also compatible with all `net/http` middleware forms. See [here](https://github.com/kataras/iris/tree/master/_examples/convert-handlers). iris has its own middleware form of `func(ctx context.Context)` but it's also compatible with all `net/http` middleware forms. See [here](https://github.com/kataras/iris/tree/master/_examples/convert-handlers).
Here's a small list of useful third-party handlers: Here's a small list of useful third-party handlers:
| Middleware | Description | | Middleware | Description |
| -----------|-------------| | -----------|-------------|
| [goth](https://github.com/markbates/goth) | OAuth, OAuth2 authentication. [Example](https://github.com/kataras/iris/tree/master/_examples/authentication/oauth2) | | [goth](https://github.com/markbates/goth) | OAuth, OAuth2 authentication. [Example](https://github.com/kataras/iris/tree/master/_examples/authentication/oauth2) |
| [binding](https://github.com/mholt/binding) | Data binding from HTTP requests into structs | | [binding](https://github.com/mholt/binding) | Data binding from HTTP requests into structs |
| [csp](https://github.com/awakenetworks/csp) | [Content Security Policy](https://www.w3.org/TR/CSP2/) (CSP) support | | [csp](https://github.com/awakenetworks/csp) | [Content Security Policy](https://www.w3.org/TR/CSP2/) (CSP) support |
| [delay](https://github.com/jeffbmartinez/delay) | Add delays/latency to endpoints. Useful when testing effects of high latency | | [delay](https://github.com/jeffbmartinez/delay) | Add delays/latency to endpoints. Useful when testing effects of high latency |
| [onthefly](https://github.com/xyproto/onthefly) | Generate TinySVG, HTML and CSS on the fly | | [onthefly](https://github.com/xyproto/onthefly) | Generate TinySVG, HTML and CSS on the fly |
| [permissions2](https://github.com/xyproto/permissions2) | Cookies, users and permissions | | [permissions2](https://github.com/xyproto/permissions2) | Cookies, users and permissions |
| [RestGate](https://github.com/pjebs/restgate) | Secure authentication for REST API endpoints | | [RestGate](https://github.com/pjebs/restgate) | Secure authentication for REST API endpoints |
| [stats](https://github.com/thoas/stats) | Store information about your web application (response time, etc.) | | [stats](https://github.com/thoas/stats) | Store information about your web application (response time, etc.) |
| [VanGoH](https://github.com/auroratechnologies/vangoh) | Configurable [AWS-Style](http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html) HMAC authentication middleware | | [VanGoH](https://github.com/auroratechnologies/vangoh) | Configurable [AWS-Style](http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html) HMAC authentication middleware |
| [xrequestid](https://github.com/pilu/xrequestid) | Middleware that assigns a random X-Request-Id header to each request | | [xrequestid](https://github.com/pilu/xrequestid) | Middleware that assigns a random X-Request-Id header to each request |
| [digits](https://github.com/bamarni/digits) | Middleware that handles [Twitter Digits](https://get.digits.com/) authentication | | [digits](https://github.com/bamarni/digits) | Middleware that handles [Twitter Digits](https://get.digits.com/) authentication |
> Feel free to put up your own middleware in this list! > Feel free to put up your own middleware in this list!

View File

@ -1,4 +1,4 @@
# This is the official list of Iris Sessions authors for copyright # This is the official list of Iris Sessions authors for copyright
# purposes. # purposes.
Gerasimos Maropoulos <kataras2006@hotmail.com> Gerasimos Maropoulos <kataras2006@hotmail.com>

View File

@ -1,27 +1,27 @@
Copyright (c) 2017 The Iris Sessions Authors. All rights reserved. Copyright (c) 2017 The Iris Sessions 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
met: met:
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the in the documentation and/or other materials provided with the
distribution. distribution.
* Neither the name of Iris nor the names of its * Neither the name of Iris nor the names of its
contributors may be used to endorse or promote products derived from contributors may be used to endorse or promote products derived from
this software without specific prior written permission. this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -14,7 +14,7 @@ import (
// DefaultFileMode used as the default database's "fileMode" // DefaultFileMode used as the default database's "fileMode"
// for creating the sessions directory path, opening and write the session file. // for creating the sessions directory path, opening and write the session file.
var ( var (
DefaultFileMode = 0666 DefaultFileMode = 0755
) )
// Database the badger(key-value file-based) session storage. // Database the badger(key-value file-based) session storage.
@ -23,7 +23,6 @@ type Database struct {
// it's initialized at `New` or `NewFromDB`. // it's initialized at `New` or `NewFromDB`.
// Can be used to get stats. // Can be used to get stats.
Service *badger.DB Service *badger.DB
async bool
} }
// New creates and returns a new badger(key-value file-based) storage // New creates and returns a new badger(key-value file-based) storage
@ -109,10 +108,9 @@ func (db *Database) Cleanup() (err error) {
return rep.Return() return rep.Return()
} }
// Async if true passed then it will use different // Async is DEPRECATED
// go routines to update the badger(key-value file-based) storage. // if it was true then it could use different to update the back-end storage, now it does nothing.
func (db *Database) Async(useGoRoutines bool) *Database { func (db *Database) Async(useGoRoutines bool) *Database {
db.async = useGoRoutines
return db return db
} }
@ -146,11 +144,7 @@ func (db *Database) Load(sid string) (storeDB sessions.RemoteStore) {
// Sync syncs the database with the session's (memory) store. // Sync syncs the database with the session's (memory) store.
func (db *Database) Sync(p sessions.SyncPayload) { func (db *Database) Sync(p sessions.SyncPayload) {
if db.async { db.sync(p)
go db.sync(p)
} else {
db.sync(p)
}
} }
func (db *Database) sync(p sessions.SyncPayload) { func (db *Database) sync(p sessions.SyncPayload) {

View File

@ -17,7 +17,7 @@ import (
// for creating the sessions directory path, opening and write // for creating the sessions directory path, opening and write
// the session boltdb(file-based) storage. // the session boltdb(file-based) storage.
var ( var (
DefaultFileMode = 0666 DefaultFileMode = 0755
) )
// Database the BoltDB(file-based) session storage. // Database the BoltDB(file-based) session storage.
@ -27,7 +27,6 @@ type Database struct {
// it's initialized at `New` or `NewFromDB`. // it's initialized at `New` or `NewFromDB`.
// Can be used to get stats. // Can be used to get stats.
Service *bolt.DB Service *bolt.DB
async bool
} }
var ( var (
@ -115,10 +114,9 @@ func (db *Database) Cleanup() error {
return err return err
} }
// Async if true passed then it will use different // Async is DEPRECATED
// go routines to update the BoltDB(file-based) storage. // if it was true then it could use different to update the back-end storage, now it does nothing.
func (db *Database) Async(useGoRoutines bool) *Database { func (db *Database) Async(useGoRoutines bool) *Database {
db.async = useGoRoutines
return db return db
} }
@ -151,11 +149,7 @@ func (db *Database) Load(sid string) (storeDB sessions.RemoteStore) {
// Sync syncs the database with the session's (memory) store. // Sync syncs the database with the session's (memory) store.
func (db *Database) Sync(p sessions.SyncPayload) { func (db *Database) Sync(p sessions.SyncPayload) {
if db.async { db.sync(p)
go db.sync(p)
} else {
db.sync(p)
}
} }
func (db *Database) sync(p sessions.SyncPayload) { func (db *Database) sync(p sessions.SyncPayload) {

View File

@ -13,7 +13,7 @@ import (
// DefaultFileMode used as the default database's "fileMode" // DefaultFileMode used as the default database's "fileMode"
// for creating the sessions directory path, opening and write the session file. // for creating the sessions directory path, opening and write the session file.
var ( var (
DefaultFileMode = 0666 DefaultFileMode = 0755
) )
// Database is the basic file-storage session database. // Database is the basic file-storage session database.
@ -28,12 +28,7 @@ var (
// Remember: sessions are not a storage for large data, everywhere: on any platform on any programming language. // Remember: sessions are not a storage for large data, everywhere: on any platform on any programming language.
type Database struct { type Database struct {
dir string dir string
fileMode os.FileMode // defaults to 0666 if missing. fileMode os.FileMode // defaults to DefaultFileMode if missing.
// if true then it will use go routines to:
// append or re-write a file
// create a file
// remove a file
async bool
} }
// New creates and returns a new file-storage database instance based on the "directoryPath". // New creates and returns a new file-storage database instance based on the "directoryPath".
@ -77,20 +72,15 @@ func (db *Database) Cleanup() error {
// FileMode for creating the sessions directory path, opening and write the session file. // FileMode for creating the sessions directory path, opening and write the session file.
// //
// Defaults to 0666. // Defaults to 0755.
func (db *Database) FileMode(fileMode uint32) *Database { func (db *Database) FileMode(fileMode uint32) *Database {
db.fileMode = os.FileMode(fileMode) db.fileMode = os.FileMode(fileMode)
return db return db
} }
// Async if true passed then it will use go routines to: // Async is DEPRECATED
// append or re-write a file // if it was true then it could use different to update the back-end storage, now it does nothing.
// create a file
// remove a file.
//
// Defaults to false.
func (db *Database) Async(useGoRoutines bool) *Database { func (db *Database) Async(useGoRoutines bool) *Database {
db.async = useGoRoutines
return db return db
} }
@ -137,11 +127,7 @@ func (db *Database) load(fileName string) (storeDB sessions.RemoteStore, loadErr
// Sync syncs the database. // Sync syncs the database.
func (db *Database) Sync(p sessions.SyncPayload) { func (db *Database) Sync(p sessions.SyncPayload) {
if db.async { db.sync(p)
go db.sync(p)
} else {
db.sync(p)
}
} }
func (db *Database) sync(p sessions.SyncPayload) { func (db *Database) sync(p sessions.SyncPayload) {

View File

@ -27,7 +27,6 @@ type Database struct {
// it's initialized at `New` or `NewFromDB`. // it's initialized at `New` or `NewFromDB`.
// Can be used to get stats. // Can be used to get stats.
Service *leveldb.DB Service *leveldb.DB
async bool
} }
// New creates and returns a new LevelDB(file-based) storage // New creates and returns a new LevelDB(file-based) storage
@ -98,10 +97,9 @@ func (db *Database) Cleanup() error {
return iter.Error() return iter.Error()
} }
// Async if true passed then it will use different // Async is DEPRECATED
// go routines to update the LevelDB(file-based) storage. // if it was true then it could use different to update the back-end storage, now it does nothing.
func (db *Database) Async(useGoRoutines bool) *Database { func (db *Database) Async(useGoRoutines bool) *Database {
db.async = useGoRoutines
return db return db
} }
@ -140,11 +138,7 @@ func (db *Database) Load(sid string) (storeDB sessions.RemoteStore) {
// Sync syncs the database with the session's (memory) store. // Sync syncs the database with the session's (memory) store.
func (db *Database) Sync(p sessions.SyncPayload) { func (db *Database) Sync(p sessions.SyncPayload) {
if db.async { db.sync(p)
go db.sync(p)
} else {
db.sync(p)
}
} }
func (db *Database) sync(p sessions.SyncPayload) { func (db *Database) sync(p sessions.SyncPayload) {

View File

@ -12,7 +12,6 @@ import (
// Database the redis back-end session database for the sessions. // Database the redis back-end session database for the sessions.
type Database struct { type Database struct {
redis *service.Service redis *service.Service
async bool
} }
// New returns a new redis database. // New returns a new redis database.
@ -27,10 +26,9 @@ func (db *Database) Config() *service.Config {
return db.redis.Config return db.redis.Config
} }
// Async if true passed then it will use different // Async is DEPRECATED
// go routines to update the redis storage. // if it was true then it could use different to update the back-end storage, now it does nothing.
func (db *Database) Async(useGoRoutines bool) *Database { func (db *Database) Async(useGoRoutines bool) *Database {
db.async = useGoRoutines
return db return db
} }
@ -70,11 +68,7 @@ func (db *Database) Load(sid string) (storeDB sessions.RemoteStore) {
// Sync syncs the database. // Sync syncs the database.
func (db *Database) Sync(p sessions.SyncPayload) { func (db *Database) Sync(p sessions.SyncPayload) {
if db.async { db.sync(p)
go db.sync(p)
} else {
db.sync(p)
}
} }
func (db *Database) sync(p sessions.SyncPayload) { func (db *Database) sync(p sessions.SyncPayload) {

View File

@ -1,4 +1,4 @@
# This is the official list of Iris Typescript authors for copyright # This is the official list of Iris Typescript authors for copyright
# purposes. # purposes.
Gerasimos Maropoulos <kataras2006@hotmail.com> Gerasimos Maropoulos <kataras2006@hotmail.com>

View File

@ -1,27 +1,27 @@
Copyright (c) 2017 The Iris Typescript Authors. All rights reserved. Copyright (c) 2017 The Iris Typescript 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
met: met:
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the in the documentation and/or other materials provided with the
distribution. distribution.
* Neither the name of Iris nor the names of its * Neither the name of Iris nor the names of its
contributors may be used to endorse or promote products derived from contributors may be used to endorse or promote products derived from
this software without specific prior written permission. this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,9 +1,9 @@
# Typescript # Typescript
[Typescript](http://www.typescriptlang.org/) and [alm-tools cloud editor](http://alm.tools/) automation tools for the [iris](https://github.com/kataras/iris) web framework. [Typescript](http://www.typescriptlang.org/) and [alm-tools cloud editor](http://alm.tools/) automation tools for the [iris](https://github.com/kataras/iris) web framework.
## Table of contents ## Table of contents
* [Typescript compiler](_examples/typescript/main.go) * [Typescript compiler](_examples/typescript/main.go)
* [Alm-tools cloud editor](_examples/editor/main.go) * [Alm-tools cloud editor](_examples/editor/main.go)

View File

@ -1,8 +1,8 @@
<html> <html>
<head> <head>
<title>Load my script</title> <title>Load my script</title>
</head> </head>
<body> <body>
<script src="scripts/app.js"></script> <script src="scripts/app.js"></script>
</body> </body>
</html> </html>

View File

@ -1,16 +1,16 @@
class User{ class User{
private name: string; private name: string;
constructor(fullname:string) { constructor(fullname:string) {
this.name = fullname; this.name = fullname;
} }
Hi(msg: string): string { Hi(msg: string): string {
return msg + " " + this.name; return msg + " " + this.name;
} }
} }
var user = new User("iris web framework!"); var user = new User("iris web framework!");
var hi = user.Hi("Hello"); var hi = user.Hi("Hello");
window.alert(hi); window.alert(hi);

View File

@ -1,22 +1,22 @@
{ {
"compilerOptions": { "compilerOptions": {
"module": "commonjs", "module": "commonjs",
"noImplicitAny": false, "noImplicitAny": false,
"removeComments": true, "removeComments": true,
"preserveConstEnums": true, "preserveConstEnums": true,
"sourceMap": false, "sourceMap": false,
"target": "ES5", "target": "ES5",
"noEmit": false, "noEmit": false,
"watch":true, "watch":true,
"noEmitOnError": true, "noEmitOnError": true,
"experimentalDecorators": false, "experimentalDecorators": false,
"outDir": "./", "outDir": "./",
"charset": "UTF-8", "charset": "UTF-8",
"noLib": false, "noLib": false,
"diagnostics": true, "diagnostics": true,
"declaration": false "declaration": false
}, },
"files": [ "files": [
"./app.ts" "./app.ts"
] ]
} }

View File

@ -1,8 +1,8 @@
<html> <html>
<head> <head>
<title>Load my script</title> <title>Load my script</title>
</head> </head>
<body> <body>
<script src="scripts/app.js"></script> <script src="scripts/app.js"></script>
</body> </body>
</html> </html>

View File

@ -1,16 +1,16 @@
class User{ class User{
private name: string; private name: string;
constructor(fullname:string) { constructor(fullname:string) {
this.name = fullname; this.name = fullname;
} }
Hi(msg: string): string { Hi(msg: string): string {
return msg + " "+ this.name; return msg + " "+ this.name;
} }
} }
var user = new User("iris web framework"); var user = new User("iris web framework");
var hi = user.Hi("Hello"); var hi = user.Hi("Hello");
window.alert(hi); window.alert(hi);

View File

@ -1,151 +0,0 @@
package iris
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/url"
"os"
"os/exec"
"sync"
"time"
"github.com/kataras/golog"
"github.com/kataras/iris/core/netutil"
"github.com/kataras/survey"
"github.com/skratchdot/open-golang/open"
)
var checkVersionOnce = sync.Once{}
// CheckVersion checks for any available updates.
func CheckVersion() {
checkVersionOnce.Do(func() {
checkVersion()
})
}
type versionInfo struct {
Version string `json:"version"`
ChangelogURL string `json:"changelog_url"`
UpdateAvailable bool `json:"update_available"`
FirstTime bool `json:"first_time"`
}
func checkVersion() {
client := netutil.Client(25 * time.Second)
r, err := client.PostForm("https://iris-go.com/version", url.Values{"current_version": {Version}})
if err != nil {
golog.Debugf("%v", err)
return
}
defer r.Body.Close()
if r.StatusCode >= 400 {
return
}
b, err := ioutil.ReadAll(r.Body)
if len(b) == 0 || err != nil {
golog.Debugf("%v", err)
return
}
v := new(versionInfo)
if err := json.Unmarshal(b, v); err != nil {
golog.Debugf("error while unmarshal the response body: %v", err)
return
}
var qs []*survey.Question
// on help? when asking for installing the new update
// and when answering "No".
ignoreUpdatesMsg := "Would you like to ignore future updates? Disable the version checker via:\napp.Run(..., iris.WithoutVersionChecker)"
if v.UpdateAvailable {
// if update available ask for update action.
shouldUpdateNowMsg :=
fmt.Sprintf("A new version is available online[%s > %s].\nRelease notes: %s.\nUpdate now?",
v.Version, Version,
v.ChangelogURL)
qs = append(qs, &survey.Question{
Name: "shouldUpdateNow",
Prompt: &survey.Confirm{
Message: shouldUpdateNowMsg,
Help: ignoreUpdatesMsg,
},
Validate: survey.Required,
})
}
// firs time and update available is not relative because if no update often server will decide when to ask this,
// so separate the actions and if statements here.
if v.FirstTime {
// if first time that this server was updated then ask if enjoying the framework.
qs = append(qs, &survey.Question{
Name: "enjoyingIris",
Prompt: &survey.Confirm{
Message: "Enjoying Iris Framework?",
Help: "yes or no",
},
Validate: survey.Required,
})
}
// Ask if should update(if available) and enjoying iris(if first time) in the same survey.
ans := struct {
ShouldUpdateNow bool `survey:"shouldUpdateNow"`
EnjoyingIris bool `survey:"enjoyingIris"`
}{}
survey.Ask(qs, &ans)
if ans.EnjoyingIris {
// if the answer to the previous survey about enjoying the framework
// was positive then do the survey (currently only one question and its action).
qs2 := []*survey.Question{
{
Name: "starNow",
Prompt: &survey.Confirm{
Message: "Would you mind giving us a star on GitHub? It really helps us out! Thanks for your support:)",
Help: "Its free so let's do that, type 'y'",
},
Validate: survey.Required,
},
/* any future questions should be here, at this second survey. */
}
ans2 := struct {
StarNow bool `survey:"starNow"`
}{}
survey.Ask(qs2, &ans2)
if ans2.StarNow {
starRepo := "https://github.com/kataras/iris/stargazers"
if err := open.Run(starRepo); err != nil {
golog.Warnf("tried to open the browser for you but failed, please give us a star at: %s\n", starRepo)
}
}
}
// run the updater last, so the user can star the repo and at the same time
// the app will update her/his local iris.
if ans.ShouldUpdateNow { // it's true only when update was available and user typed "yes".
repo := "github.com/kataras/iris/..."
cmd := exec.Command("go", "get", "-u", "-v", repo)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stdout
if err := cmd.Run(); err != nil {
golog.Warnf("unexpected message while trying to go get,\nif you edited the original source code then you've to remove the whole $GOPATH/src/github.com/kataras folder and execute `go get -u github.com/kataras/iris/...` manually\n%v", err)
return
}
golog.Infof("Update process finished.\nManual rebuild and restart is required to apply the changes...\n")
} else if v.UpdateAvailable { // if update was available but choosen not to update.
golog.Infof(ignoreUpdatesMsg)
}
}

View File

@ -1,4 +1,4 @@
# This is the official list of Iris Websocket authors for copyright # This is the official list of Iris Websocket authors for copyright
# purposes. # purposes.
Gerasimos Maropoulos <kataras2006@hotmail.com> Gerasimos Maropoulos <kataras2006@hotmail.com>

View File

@ -1,27 +1,27 @@
Copyright (c) 2017 The Iris Websocket Authors. All rights reserved. Copyright (c) 2017 The Iris Websocket 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
met: met:
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the in the documentation and/or other materials provided with the
distribution. distribution.
* Neither the name of Iris nor the names of its * Neither the name of Iris nor the names of its
contributors may be used to endorse or promote products derived from contributors may be used to endorse or promote products derived from
this software without specific prior written permission. this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,255 +1,255 @@
// export to client.go:ClientSource []byte // export to client.go:ClientSource []byte
const websocketStringMessageType = 0; const websocketStringMessageType = 0;
const websocketIntMessageType = 1; const websocketIntMessageType = 1;
const websocketBoolMessageType = 2; const websocketBoolMessageType = 2;
// bytes is missing here for reasons I will explain somewhen // bytes is missing here for reasons I will explain somewhen
const websocketJSONMessageType = 4; const websocketJSONMessageType = 4;
const websocketMessagePrefix = "iris-websocket-message:"; const websocketMessagePrefix = "iris-websocket-message:";
const websocketMessageSeparator = ";"; const websocketMessageSeparator = ";";
const websocketMessagePrefixLen = websocketMessagePrefix.length; const websocketMessagePrefixLen = websocketMessagePrefix.length;
var websocketMessageSeparatorLen = websocketMessageSeparator.length; var websocketMessageSeparatorLen = websocketMessageSeparator.length;
var websocketMessagePrefixAndSepIdx = websocketMessagePrefixLen + websocketMessageSeparatorLen - 1; var websocketMessagePrefixAndSepIdx = websocketMessagePrefixLen + websocketMessageSeparatorLen - 1;
var websocketMessagePrefixIdx = websocketMessagePrefixLen - 1; var websocketMessagePrefixIdx = websocketMessagePrefixLen - 1;
var websocketMessageSeparatorIdx = websocketMessageSeparatorLen - 1; var websocketMessageSeparatorIdx = websocketMessageSeparatorLen - 1;
type onConnectFunc = () => void; type onConnectFunc = () => void;
type onWebsocketDisconnectFunc = () => void; type onWebsocketDisconnectFunc = () => void;
type onWebsocketNativeMessageFunc = (websocketMessage: string) => void; type onWebsocketNativeMessageFunc = (websocketMessage: string) => void;
type onMessageFunc = (message: any) => void; type onMessageFunc = (message: any) => void;
class Ws { class Ws {
private conn: WebSocket; private conn: WebSocket;
private isReady: boolean; private isReady: boolean;
// events listeners // events listeners
private connectListeners: onConnectFunc[] = []; private connectListeners: onConnectFunc[] = [];
private disconnectListeners: onWebsocketDisconnectFunc[] = []; private disconnectListeners: onWebsocketDisconnectFunc[] = [];
private nativeMessageListeners: onWebsocketNativeMessageFunc[] = []; private nativeMessageListeners: onWebsocketNativeMessageFunc[] = [];
private messageListeners: { [event: string]: onMessageFunc[] } = {}; private messageListeners: { [event: string]: onMessageFunc[] } = {};
// //
constructor(endpoint: string, protocols?: string[]) { constructor(endpoint: string, protocols?: string[]) {
if (!window["WebSocket"]) { if (!window["WebSocket"]) {
return; return;
} }
if (endpoint.indexOf("ws") == -1) { if (endpoint.indexOf("ws") == -1) {
endpoint = "ws://" + endpoint; endpoint = "ws://" + endpoint;
} }
if (protocols != null && protocols.length > 0) { if (protocols != null && protocols.length > 0) {
this.conn = new WebSocket(endpoint, protocols); this.conn = new WebSocket(endpoint, protocols);
} else { } else {
this.conn = new WebSocket(endpoint); this.conn = new WebSocket(endpoint);
} }
this.conn.onopen = ((evt: Event): any => { this.conn.onopen = ((evt: Event): any => {
this.fireConnect(); this.fireConnect();
this.isReady = true; this.isReady = true;
return null; return null;
}); });
this.conn.onclose = ((evt: Event): any => { this.conn.onclose = ((evt: Event): any => {
this.fireDisconnect(); this.fireDisconnect();
return null; return null;
}); });
this.conn.onmessage = ((evt: MessageEvent) => { this.conn.onmessage = ((evt: MessageEvent) => {
this.messageReceivedFromConn(evt); this.messageReceivedFromConn(evt);
}); });
} }
//utils //utils
private isNumber(obj: any): boolean { private isNumber(obj: any): boolean {
return !isNaN(obj - 0) && obj !== null && obj !== "" && obj !== false; return !isNaN(obj - 0) && obj !== null && obj !== "" && obj !== false;
} }
private isString(obj: any): boolean { private isString(obj: any): boolean {
return Object.prototype.toString.call(obj) == "[object String]"; return Object.prototype.toString.call(obj) == "[object String]";
} }
private isBoolean(obj: any): boolean { private isBoolean(obj: any): boolean {
return typeof obj === 'boolean' || return typeof obj === 'boolean' ||
(typeof obj === 'object' && typeof obj.valueOf() === 'boolean'); (typeof obj === 'object' && typeof obj.valueOf() === 'boolean');
} }
private isJSON(obj: any): boolean { private isJSON(obj: any): boolean {
return typeof obj === 'object'; return typeof obj === 'object';
} }
// //
// messages // messages
private _msg(event: string, websocketMessageType: number, dataMessage: string): string { private _msg(event: string, websocketMessageType: number, dataMessage: string): string {
return websocketMessagePrefix + event + websocketMessageSeparator + String(websocketMessageType) + websocketMessageSeparator + dataMessage; return websocketMessagePrefix + event + websocketMessageSeparator + String(websocketMessageType) + websocketMessageSeparator + dataMessage;
} }
private encodeMessage(event: string, data: any): string { private encodeMessage(event: string, data: any): string {
let m = ""; let m = "";
let t = 0; let t = 0;
if (this.isNumber(data)) { if (this.isNumber(data)) {
t = websocketIntMessageType; t = websocketIntMessageType;
m = data.toString(); m = data.toString();
} else if (this.isBoolean(data)) { } else if (this.isBoolean(data)) {
t = websocketBoolMessageType; t = websocketBoolMessageType;
m = data.toString(); m = data.toString();
} else if (this.isString(data)) { } else if (this.isString(data)) {
t = websocketStringMessageType; t = websocketStringMessageType;
m = data.toString(); m = data.toString();
} else if (this.isJSON(data)) { } else if (this.isJSON(data)) {
//propably json-object //propably json-object
t = websocketJSONMessageType; t = websocketJSONMessageType;
m = JSON.stringify(data); m = JSON.stringify(data);
} else { } else {
console.log("Invalid, javascript-side should contains an empty second parameter."); console.log("Invalid, javascript-side should contains an empty second parameter.");
} }
return this._msg(event, t, m); return this._msg(event, t, m);
} }
private decodeMessage<T>(event: string, websocketMessage: string): T | any { private decodeMessage<T>(event: string, websocketMessage: string): T | any {
//iris-websocket-message;user;4;themarshaledstringfromajsonstruct //iris-websocket-message;user;4;themarshaledstringfromajsonstruct
let skipLen = websocketMessagePrefixLen + websocketMessageSeparatorLen + event.length + 2; let skipLen = websocketMessagePrefixLen + websocketMessageSeparatorLen + event.length + 2;
if (websocketMessage.length < skipLen + 1) { if (websocketMessage.length < skipLen + 1) {
return null; return null;
} }
let websocketMessageType = parseInt(websocketMessage.charAt(skipLen - 2)); let websocketMessageType = parseInt(websocketMessage.charAt(skipLen - 2));
let theMessage = websocketMessage.substring(skipLen, websocketMessage.length); let theMessage = websocketMessage.substring(skipLen, websocketMessage.length);
if (websocketMessageType == websocketIntMessageType) { if (websocketMessageType == websocketIntMessageType) {
return parseInt(theMessage); return parseInt(theMessage);
} else if (websocketMessageType == websocketBoolMessageType) { } else if (websocketMessageType == websocketBoolMessageType) {
return Boolean(theMessage); return Boolean(theMessage);
} else if (websocketMessageType == websocketStringMessageType) { } else if (websocketMessageType == websocketStringMessageType) {
return theMessage; return theMessage;
} else if (websocketMessageType == websocketJSONMessageType) { } else if (websocketMessageType == websocketJSONMessageType) {
return JSON.parse(theMessage); return JSON.parse(theMessage);
} else { } else {
return null; // invalid return null; // invalid
} }
} }
private getWebsocketCustomEvent(websocketMessage: string): string { private getWebsocketCustomEvent(websocketMessage: string): string {
if (websocketMessage.length < websocketMessagePrefixAndSepIdx) { if (websocketMessage.length < websocketMessagePrefixAndSepIdx) {
return ""; return "";
} }
let s = websocketMessage.substring(websocketMessagePrefixAndSepIdx, websocketMessage.length); let s = websocketMessage.substring(websocketMessagePrefixAndSepIdx, websocketMessage.length);
let evt = s.substring(0, s.indexOf(websocketMessageSeparator)); let evt = s.substring(0, s.indexOf(websocketMessageSeparator));
return evt; return evt;
} }
private getCustomMessage(event: string, websocketMessage: string): string { private getCustomMessage(event: string, websocketMessage: string): string {
let eventIdx = websocketMessage.indexOf(event + websocketMessageSeparator); let eventIdx = websocketMessage.indexOf(event + websocketMessageSeparator);
let s = websocketMessage.substring(eventIdx + event.length + websocketMessageSeparator.length + 2, websocketMessage.length); let s = websocketMessage.substring(eventIdx + event.length + websocketMessageSeparator.length + 2, websocketMessage.length);
return s; return s;
} }
// //
// Ws Events // Ws Events
// messageReceivedFromConn this is the func which decides // messageReceivedFromConn this is the func which decides
// if it's a native websocket message or a custom qws message // if it's a native websocket message or a custom qws message
// if native message then calls the fireNativeMessage // if native message then calls the fireNativeMessage
// else calls the fireMessage // else calls the fireMessage
// //
// remember iris gives you the freedom of native websocket messages if you don't want to use this client side at all. // remember iris gives you the freedom of native websocket messages if you don't want to use this client side at all.
private messageReceivedFromConn(evt: MessageEvent): void { private messageReceivedFromConn(evt: MessageEvent): void {
//check if qws message //check if qws message
let message = <string>evt.data; let message = <string>evt.data;
if (message.indexOf(websocketMessagePrefix) != -1) { if (message.indexOf(websocketMessagePrefix) != -1) {
let event = this.getWebsocketCustomEvent(message); let event = this.getWebsocketCustomEvent(message);
if (event != "") { if (event != "") {
// it's a custom message // it's a custom message
this.fireMessage(event, this.getCustomMessage(event, message)); this.fireMessage(event, this.getCustomMessage(event, message));
return; return;
} }
} }
// it's a native websocket message // it's a native websocket message
this.fireNativeMessage(message); this.fireNativeMessage(message);
} }
OnConnect(fn: onConnectFunc): void { OnConnect(fn: onConnectFunc): void {
if (this.isReady) { if (this.isReady) {
fn(); fn();
} }
this.connectListeners.push(fn); this.connectListeners.push(fn);
} }
fireConnect(): void { fireConnect(): void {
for (let i = 0; i < this.connectListeners.length; i++) { for (let i = 0; i < this.connectListeners.length; i++) {
this.connectListeners[i](); this.connectListeners[i]();
} }
} }
OnDisconnect(fn: onWebsocketDisconnectFunc): void { OnDisconnect(fn: onWebsocketDisconnectFunc): void {
this.disconnectListeners.push(fn); this.disconnectListeners.push(fn);
} }
fireDisconnect(): void { fireDisconnect(): void {
for (let i = 0; i < this.disconnectListeners.length; i++) { for (let i = 0; i < this.disconnectListeners.length; i++) {
this.disconnectListeners[i](); this.disconnectListeners[i]();
} }
} }
OnMessage(cb: onWebsocketNativeMessageFunc): void { OnMessage(cb: onWebsocketNativeMessageFunc): void {
this.nativeMessageListeners.push(cb); this.nativeMessageListeners.push(cb);
} }
fireNativeMessage(websocketMessage: string): void { fireNativeMessage(websocketMessage: string): void {
for (let i = 0; i < this.nativeMessageListeners.length; i++) { for (let i = 0; i < this.nativeMessageListeners.length; i++) {
this.nativeMessageListeners[i](websocketMessage); this.nativeMessageListeners[i](websocketMessage);
} }
} }
On(event: string, cb: onMessageFunc): void { On(event: string, cb: onMessageFunc): void {
if (this.messageListeners[event] == null || this.messageListeners[event] == undefined) { if (this.messageListeners[event] == null || this.messageListeners[event] == undefined) {
this.messageListeners[event] = []; this.messageListeners[event] = [];
} }
this.messageListeners[event].push(cb); this.messageListeners[event].push(cb);
} }
fireMessage(event: string, message: any): void { fireMessage(event: string, message: any): void {
for (let key in this.messageListeners) { for (let key in this.messageListeners) {
if (this.messageListeners.hasOwnProperty(key)) { if (this.messageListeners.hasOwnProperty(key)) {
if (key == event) { if (key == event) {
for (let i = 0; i < this.messageListeners[key].length; i++) { for (let i = 0; i < this.messageListeners[key].length; i++) {
this.messageListeners[key][i](message); this.messageListeners[key][i](message);
} }
} }
} }
} }
} }
// //
// Ws Actions // Ws Actions
Disconnect(): void { Disconnect(): void {
this.conn.close(); this.conn.close();
} }
// EmitMessage sends a native websocket message // EmitMessage sends a native websocket message
EmitMessage(websocketMessage: string): void { EmitMessage(websocketMessage: string): void {
this.conn.send(websocketMessage); this.conn.send(websocketMessage);
} }
// Emit sends an iris-custom websocket message // Emit sends an iris-custom websocket message
Emit(event: string, data: any): void { Emit(event: string, data: any): void {
let messageStr = this.encodeMessage(event, data); let messageStr = this.encodeMessage(event, data);
this.EmitMessage(messageStr); this.EmitMessage(messageStr);
} }
// //
} }
// node-modules export {Ws}; // node-modules export {Ws};