mirror of
https://github.com/kataras/iris.git
synced 2025-02-02 15:30:36 +01:00
Release of version 10.4.0 - x8 faster embedded file server | Star and Read HISTORY.md
Former-commit-id: 4f8b8c95c1b107a9be3b1ef6835ece949a75ceb6
This commit is contained in:
parent
1e0c707366
commit
56215eeb71
2
Gopkg.lock
generated
2
Gopkg.lock
generated
|
@ -89,7 +89,7 @@
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/iris-contrib/httpexpect"
|
name = "github.com/iris-contrib/httpexpect"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "65e93247e7071782e760f82086e8b677cca0c78a"
|
revision = "ebe99fcebbcedf6e7916320cce24c3e1832766ac"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
|
27
HISTORY.md
27
HISTORY.md
|
@ -17,6 +17,33 @@ Developers are not forced to upgrade if they don't really need it. Upgrade whene
|
||||||
|
|
||||||
**How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris` or let the automatic updater do that for you.
|
**How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris` or let the automatic updater do that for you.
|
||||||
|
|
||||||
|
# We, 14 March 2018 | v10.4.0
|
||||||
|
|
||||||
|
- fix `APIBuilder, Party#StaticWeb` and `APIBuilder, Party#StaticEmbedded` wrong strip prefix inside children parties
|
||||||
|
- keep the `iris, core/router#StaticEmbeddedHandler` and remove the `core/router/APIBuilder#StaticEmbeddedHandler`, (note the `Handler` suffix) it's global and has nothing to do with the `Party` or the `APIBuilder`
|
||||||
|
- fix high path cleaning between `{}` (we already escape those contents at the [interpreter](core/router/macro/interpreter) level but some symbols are still removed by the higher-level api builder) , i.e `\\` from the string's macro function `regex` contents as reported at [927](https://github.com/kataras/iris/issues/927) by [commit e85b113476eeefffbc7823297cc63cd152ebddfd](https://github.com/kataras/iris/commit/e85b113476eeefffbc7823297cc63cd152ebddfd)
|
||||||
|
- sync the `golang.org/x/sys/unix` vendor
|
||||||
|
|
||||||
|
## The most important
|
||||||
|
|
||||||
|
We've made static files served up to 8 times faster using the new tool, <https://github.com/kataras/bindata> which is a fork of your beloved `go-bindata`, some unnecessary things for us were removed there and contains some additions for performance boost.
|
||||||
|
|
||||||
|
## Reqs/sec with [shuLhan/go-bindata](https://github.com/shuLhan/go-bindata) and alternatives
|
||||||
|
|
||||||
|
![go-bindata](https://github.com/kataras/bindata/raw/master/go-bindata-benchmark.png)
|
||||||
|
|
||||||
|
## Reqs/sec with [kataras/bindata](https://github.com/kataras/bindata)
|
||||||
|
|
||||||
|
![bindata](https://github.com/kataras/bindata/raw/master/bindata-benchmark.png)
|
||||||
|
|
||||||
|
A **new** function `Party#StaticEmbeddedGzip` which has the same input arguments as the `Party#StaticEmbedded` added. The difference is that the **new** `StaticEmbeddedGzip` accepts the `GzipAsset` and `GzipAssetNames` from the `bindata` (go get -u github.com/kataras/bindata/cmd/bindata).
|
||||||
|
|
||||||
|
You can still use both `bindata` and `go-bindata` tools in the same folder, the first for embedding the rest of the static files (javascript, css, ...) and the second for embedding the templates!
|
||||||
|
|
||||||
|
A full example can be found at: [_examples/file-server/embedding-gziped-files-into-app/main.go](_examples/file-server/embedding-gziped-files-into-app/main.go).
|
||||||
|
|
||||||
|
_Happy Coding!_
|
||||||
|
|
||||||
# Sa, 10 March 2018 | v10.3.0
|
# Sa, 10 March 2018 | v10.3.0
|
||||||
|
|
||||||
- The only one API Change is the [Application/Context/Router#RouteExists](https://godoc.org/github.com/kataras/iris/core/router#Router.RouteExists), it accepts the `Context` as its first argument instead of last now.
|
- The only one API Change is the [Application/Context/Router#RouteExists](https://godoc.org/github.com/kataras/iris/core/router#Router.RouteExists), it accepts the `Context` as its first argument instead of last now.
|
||||||
|
|
|
@ -17,9 +17,13 @@
|
||||||
|
|
||||||
**Πώς να αναβαθμίσετε**: Ανοίξτε την γραμμή εντολών σας και εκτελέστε αυτήν την εντολή: `go get -u github.com/kataras/iris` ή αφήστε το αυτόματο updater να το κάνει αυτό για σας.
|
**Πώς να αναβαθμίσετε**: Ανοίξτε την γραμμή εντολών σας και εκτελέστε αυτήν την εντολή: `go get -u github.com/kataras/iris` ή αφήστε το αυτόματο updater να το κάνει αυτό για σας.
|
||||||
|
|
||||||
|
# We, 14 March 2018 | v10.4.0
|
||||||
|
|
||||||
|
This history entry is not translated yet to the Greek language yet, please refer to the english version of the [HISTORY entry](https://github.com/kataras/iris/blob/master/HISTORY.md#we-14-march-2018--v1040) instead.
|
||||||
|
|
||||||
# Sa, 10 March 2018 | v10.3.0
|
# Sa, 10 March 2018 | v10.3.0
|
||||||
|
|
||||||
This history entry is not translated yet to the Greek language yet, please refer to the original [HISTORY entry](https://github.com/kataras/iris/blob/master/HISTORY.md#sa-10-march-2018--v1030) instead.
|
This history entry is not translated yet to the Greek language yet, please refer to the english version of the [HISTORY entry](https://github.com/kataras/iris/blob/master/HISTORY.md#sa-10-march-2018--v1030) instead.
|
||||||
|
|
||||||
# Th, 15 February 2018 | v10.2.1
|
# Th, 15 February 2018 | v10.2.1
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,10 @@
|
||||||
|
|
||||||
**如何升级**: 打开命令行执行以下命令: `go get -u github.com/kataras/iris` 或者等待自动更新。
|
**如何升级**: 打开命令行执行以下命令: `go get -u github.com/kataras/iris` 或者等待自动更新。
|
||||||
|
|
||||||
|
# We, 14 March 2018 | v10.4.0
|
||||||
|
|
||||||
|
This history entry is not translated yet to the Chinese language yet, please refer to the english version of the [HISTORY entry](https://github.com/kataras/iris/blob/master/HISTORY.md#we-14-march-2018--v1040) instead.
|
||||||
|
|
||||||
# 2018 3月10号 | v10.3.0 版本更新
|
# 2018 3月10号 | v10.3.0 版本更新
|
||||||
|
|
||||||
- 只有一项 API 更改 [Application/Context/Router#RouteExists](https://godoc.org/github.com/kataras/iris/core/router#Router.RouteExists), 将 `Context` 作为第一参数,而不是最后一个。
|
- 只有一项 API 更改 [Application/Context/Router#RouteExists](https://godoc.org/github.com/kataras/iris/core/router#Router.RouteExists), 将 `Context` 作为第一参数,而不是最后一个。
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<a href="https://iris-go.com"> <img align="right" width="169px" src="https://iris-go.com/images/icon.svg?v=a" title="logo created by @merry.dii" /> </a>
|
<a href="https://iris-go.com"> <img align="right" width="169px" src="https://iris-go.com/images/icon.svg?v=a" title="logo created by @merry.dii" /> </a>
|
||||||
|
|
||||||
[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris)<!-- [![release](https://img.shields.io/github/release/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/releases)--> [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=kataras2006.iris)<!--[![github closed issues](https://img.shields.io/github/issues-closed-raw/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/issues?q=is%3Aissue+is%3Aclosed)--> [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](https://iris-go.com/v10/recipe) [![release](https://img.shields.io/badge/release%20-v10.3-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
|
[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris)<!-- [![release](https://img.shields.io/github/release/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/releases)--> [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=kataras2006.iris)<!--[![github closed issues](https://img.shields.io/github/issues-closed-raw/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/issues?q=is%3Aissue+is%3Aclosed)--> [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](https://iris-go.com/v10/recipe) [![release](https://img.shields.io/badge/release%20-v10.4-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
|
||||||
|
|
||||||
Iris is a fast, simple yet fully featured and very efficient web framework for Go.
|
Iris is a fast, simple yet fully featured and very efficient web framework for Go.
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ _Updated at: [Tuesday, 21 November 2017](_benchmarks/README_UNIX.md)_
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
- [HISTORY](HISTORY.md#sa-10-march-2018--v1030) file is your best friend, it contains information about the latest features and changes
|
- [HISTORY](HISTORY.md#we-14-march-2018--v1040) file is your best friend, it contains information about the latest features and changes
|
||||||
- Did you happen to find a bug? Post it at [github issues](https://github.com/kataras/iris/issues)
|
- Did you happen to find a bug? Post it at [github issues](https://github.com/kataras/iris/issues)
|
||||||
- Do you have any questions or need to speak with someone experienced to solve a problem at real-time? Join us to the [community chat](https://chat.iris-go.com)
|
- Do you have any questions or need to speak with someone experienced to solve a problem at real-time? Join us to the [community chat](https://chat.iris-go.com)
|
||||||
- Complete our form-based user experience report by clicking [here](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
- Complete our form-based user experience report by clicking [here](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<a href="https://iris-go.com"> <img align="right" width="169px" src="https://iris-go.com/images/icon.svg?v=a" title="logo created by @merry.dii" /> </a>
|
<a href="https://iris-go.com"> <img align="right" width="169px" src="https://iris-go.com/images/icon.svg?v=a" title="logo created by @merry.dii" /> </a>
|
||||||
|
|
||||||
[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris)<!-- [![release](https://img.shields.io/github/release/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/releases)--> [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=kataras2006.iris)<!--[![github closed issues](https://img.shields.io/github/issues-closed-raw/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/issues?q=is%3Aissue+is%3Aclosed)--> [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](https://iris-go.com/v10/recipe) [![release](https://img.shields.io/badge/release%20-v10.3-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
|
[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris)<!-- [![release](https://img.shields.io/github/release/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/releases)--> [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=kataras2006.iris)<!--[![github closed issues](https://img.shields.io/github/issues-closed-raw/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/issues?q=is%3Aissue+is%3Aclosed)--> [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](https://iris-go.com/v10/recipe) [![release](https://img.shields.io/badge/release%20-v10.4-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
|
||||||
|
|
||||||
Το Iris είναι ένα γρήγορο, απλό αλλά και πλήρως λειτουργικό και πολύ αποδοτικό web framework για τη Go.
|
Το Iris είναι ένα γρήγορο, απλό αλλά και πλήρως λειτουργικό και πολύ αποδοτικό web framework για τη Go.
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ _Η τελευταία ενημέρωση έγινε την [Τρίτη, 21 Νο
|
||||||
|
|
||||||
## Υποστήριξη
|
## Υποστήριξη
|
||||||
|
|
||||||
- To [HISTORY](HISTORY_GR.md#sa-10-march-2018--v1030) αρχείο είναι ο καλύτερος σας φίλος, περιέχει πληροφορίες σχετικά με τις τελευταίες λειτουργίες(features) και αλλαγές
|
- To [HISTORY](HISTORY_GR.md#we-14-march-2018--v1040) αρχείο είναι ο καλύτερος σας φίλος, περιέχει πληροφορίες σχετικά με τις τελευταίες λειτουργίες(features) και αλλαγές
|
||||||
- Μήπως τυχαίνει να βρήκατε κάποιο bug; Δημοσιεύστε το στα [github issues](https://github.com/kataras/iris/issues)
|
- Μήπως τυχαίνει να βρήκατε κάποιο bug; Δημοσιεύστε το στα [github issues](https://github.com/kataras/iris/issues)
|
||||||
- Έχετε οποιεσδήποτε ερωτήσεις ή πρέπει να μιλήσετε με κάποιον έμπειρο για την επίλυση ενός προβλήματος σε πραγματικό χρόνο; Ελάτε μαζί μας στην [συνομιλία κοινότητας](https://chat.iris-go.com)
|
- Έχετε οποιεσδήποτε ερωτήσεις ή πρέπει να μιλήσετε με κάποιον έμπειρο για την επίλυση ενός προβλήματος σε πραγματικό χρόνο; Ελάτε μαζί μας στην [συνομιλία κοινότητας](https://chat.iris-go.com)
|
||||||
- Συμπληρώστε την αναφορά εμπειρίας χρήστη κάνοντας κλικ [εδώ](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
- Συμπληρώστε την αναφορά εμπειρίας χρήστη κάνοντας κλικ [εδώ](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<a href="https://iris-go.com"> <img align="right" width="169px" src="https://iris-go.com/images/icon.svg?v=a" title="logo created by @merry.dii" /> </a>
|
<a href="https://iris-go.com"> <img align="right" width="169px" src="https://iris-go.com/images/icon.svg?v=a" title="logo created by @merry.dii" /> </a>
|
||||||
|
|
||||||
[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris)<!-- [![release](https://img.shields.io/github/release/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/releases)--> [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=kataras2006.iris)<!--[![github closed issues](https://img.shields.io/github/issues-closed-raw/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/issues?q=is%3Aissue+is%3Aclosed)--> [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](https://iris-go.com/v10/recipe) [![release](https://img.shields.io/badge/release%20-v10.3-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
|
[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris)<!-- [![release](https://img.shields.io/github/release/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/releases)--> [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=kataras2006.iris)<!--[![github closed issues](https://img.shields.io/github/issues-closed-raw/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/issues?q=is%3Aissue+is%3Aclosed)--> [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](https://iris-go.com/v10/recipe) [![release](https://img.shields.io/badge/release%20-v10.4-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
|
||||||
|
|
||||||
Iris - это быстрая, простая, но полнофункциональная и очень эффективная веб-платформа для Go.
|
Iris - это быстрая, простая, но полнофункциональная и очень эффективная веб-платформа для Go.
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ _Обновлено: [Вторник, 21 ноября 2017 г.](_benchmarks/READ
|
||||||
|
|
||||||
## Поддержка
|
## Поддержка
|
||||||
|
|
||||||
- Файл [HISTORY](HISTORY.md#sa-10-march-2018--v1030) - ваш лучший друг, он содержит информацию о последних особенностях и всех изменениях
|
- Файл [HISTORY](HISTORY.md#we-14-march-2018--v1040) - ваш лучший друг, он содержит информацию о последних особенностях и всех изменениях
|
||||||
- Вы случайно обнаружили ошибку? Опубликуйте ее на [Github вопросы](https://github.com/kataras/iris/issues)
|
- Вы случайно обнаружили ошибку? Опубликуйте ее на [Github вопросы](https://github.com/kataras/iris/issues)
|
||||||
- У Вас есть какие-либо вопросы или Вам нужно поговорить с кем-то, кто бы смог решить Вашу проблему в режиме реального времени? Присоединяйтесь к нам в [чате сообщества](https://chat.iris-go.com)
|
- У Вас есть какие-либо вопросы или Вам нужно поговорить с кем-то, кто бы смог решить Вашу проблему в режиме реального времени? Присоединяйтесь к нам в [чате сообщества](https://chat.iris-go.com)
|
||||||
- Заполните наш отчет о пользовательском опыте на основе формы, нажав [здесь](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
- Заполните наш отчет о пользовательском опыте на основе формы, нажав [здесь](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<a href="https://iris-go.com"> <img align="right" width="169px" src="https://iris-go.com/images/icon.svg?v=a" title="logo created by @merry.dii" /> </a>
|
<a href="https://iris-go.com"> <img align="right" width="169px" src="https://iris-go.com/images/icon.svg?v=a" title="logo created by @merry.dii" /> </a>
|
||||||
|
|
||||||
[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris)<!-- [![release](https://img.shields.io/github/release/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/releases)--> [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=kataras2006.iris)<!--[![github closed issues](https://img.shields.io/github/issues-closed-raw/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/issues?q=is%3Aissue+is%3Aclosed)--> [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](https://iris-go.com/v10/recipe) [![release](https://img.shields.io/badge/release%20-v10.3-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
|
[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris)<!-- [![release](https://img.shields.io/github/release/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/releases)--> [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=kataras2006.iris)<!--[![github closed issues](https://img.shields.io/github/issues-closed-raw/kataras/iris.svg?style=flat-square)](https://github.com/kataras/iris/issues?q=is%3Aissue+is%3Aclosed)--> [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](https://iris-go.com/v10/recipe) [![release](https://img.shields.io/badge/release%20-v10.4-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
|
||||||
|
|
||||||
Iris 是一款超快、简洁高效的 Go 语言 Web开发框架。
|
Iris 是一款超快、简洁高效的 Go 语言 Web开发框架。
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ _更新于: [2017年11月21日星期二](_benchmarks/README_UNIX.md)_
|
||||||
|
|
||||||
## 支持
|
## 支持
|
||||||
|
|
||||||
- [更新记录](HISTORY_ZH.md#sa-10-march-2018--v1030) 是您最好的朋友,它包含有关最新功能和更改的信息
|
- [更新记录](HISTORY_ZH.md#we-14-march-2018--v1040) 是您最好的朋友,它包含有关最新功能和更改的信息
|
||||||
- 你碰巧找到了一个错误? 请提交 [github issues](https://github.com/kataras/iris/issues)
|
- 你碰巧找到了一个错误? 请提交 [github issues](https://github.com/kataras/iris/issues)
|
||||||
- 您是否有任何疑问或需要与有经验的人士交谈以实时解决问题? [加入我们的聊天](https://chat.iris-go.com)
|
- 您是否有任何疑问或需要与有经验的人士交谈以实时解决问题? [加入我们的聊天](https://chat.iris-go.com)
|
||||||
- [点击这里完成我们基于表单的用户体验报告](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
- [点击这里完成我们基于表单的用户体验报告](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
10.3.0:https://github.com/kataras/iris/blob/master/HISTORY.md#sa-10-march-2018--v1030
|
10.4.0:https://github.com/kataras/iris/blob/master/HISTORY.md#we-14-march-2018--v1040
|
|
@ -310,6 +310,7 @@ You can serve [quicktemplate](https://github.com/valyala/quicktemplate) and [her
|
||||||
- [Favicon](file-server/favicon/main.go)
|
- [Favicon](file-server/favicon/main.go)
|
||||||
- [Basic](file-server/basic/main.go)
|
- [Basic](file-server/basic/main.go)
|
||||||
- [Embedding Files Into App Executable File](file-server/embedding-files-into-app/main.go)
|
- [Embedding Files Into App Executable File](file-server/embedding-files-into-app/main.go)
|
||||||
|
- [Embedding Gziped Files Into App Executable File](file-server/embedding-gziped-files-into-app/main.go) **NEW**
|
||||||
- [Send/Force-Download Files](file-server/send-files/main.go)
|
- [Send/Force-Download Files](file-server/send-files/main.go)
|
||||||
- Single Page Applications
|
- Single Page Applications
|
||||||
* [single Page Application](file-server/single-page-application/basic/main.go)
|
* [single Page Application](file-server/single-page-application/basic/main.go)
|
||||||
|
|
|
@ -10,7 +10,8 @@ import (
|
||||||
// $ go build
|
// $ go build
|
||||||
// $ ./embedding-files-into-app
|
// $ ./embedding-files-into-app
|
||||||
// "physical" files are not used, you can delete the "assets" folder and run the example.
|
// "physical" files are not used, you can delete the "assets" folder and run the example.
|
||||||
|
//
|
||||||
|
// See `file-server/embedding-gziped-files-into-app` example as well.
|
||||||
func newApp() *iris.Application {
|
func newApp() *iris.Application {
|
||||||
app := iris.New()
|
app := iris.New()
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ func (r resource) loadFromBase(dir string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
result := string(b)
|
result := string(b)
|
||||||
|
|
||||||
if runtime.GOOS != "windows" {
|
if runtime.GOOS != "windows" {
|
||||||
result = strings.Replace(result, "\n", "\r\n", -1)
|
result = strings.Replace(result, "\n", "\r\n", -1)
|
||||||
}
|
}
|
||||||
|
|
7225
_examples/file-server/embedding-gziped-files-into-app/assets/css/bootstrap.min.css
vendored
Normal file
7225
_examples/file-server/embedding-gziped-files-into-app/assets/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
9190
_examples/file-server/embedding-gziped-files-into-app/assets/js/jquery-2.1.1.js
vendored
Normal file
9190
_examples/file-server/embedding-gziped-files-into-app/assets/js/jquery-2.1.1.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,35 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kataras/iris"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NOTE: need different tool than the "embedding-files-into-app" example.
|
||||||
|
//
|
||||||
|
// Follow these steps first:
|
||||||
|
// $ go get -u github.com/kataras/bindata/cmd/bindata
|
||||||
|
// $ bindata ./assets/...
|
||||||
|
// $ go build
|
||||||
|
// $ ./embedding-gziped-files-into-app
|
||||||
|
// "physical" files are not used, you can delete the "assets" folder and run the example.
|
||||||
|
|
||||||
|
func newApp() *iris.Application {
|
||||||
|
app := iris.New()
|
||||||
|
|
||||||
|
// Note the `GzipAsset` and `GzipAssetNames` are different from `go-bindata`'s `Asset` and `AssetNames,
|
||||||
|
// that means that you can use both `go-bindata` and `bindata` tools,
|
||||||
|
// the `go-bindata` can be used for the view engine's `Binary` method
|
||||||
|
// and the `bindata` with the `StaticEmbeddedGzip` (x8 times faster than the StaticEmbeded with `go-bindata`).
|
||||||
|
app.StaticEmbeddedGzip("/static", "./assets", GzipAsset, GzipAssetNames)
|
||||||
|
|
||||||
|
return app
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := newApp()
|
||||||
|
|
||||||
|
// http://localhost:8080/static/css/bootstrap.min.css
|
||||||
|
// http://localhost:8080/static/js/jquery-2.1.1.js
|
||||||
|
// http://localhost:8080/static/favicon.ico
|
||||||
|
app.Run(iris.Addr(":8080"))
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/kataras/iris/httptest"
|
||||||
|
"github.com/klauspost/compress/gzip"
|
||||||
|
)
|
||||||
|
|
||||||
|
type resource string
|
||||||
|
|
||||||
|
func (r resource) String() string {
|
||||||
|
return string(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r resource) strip(strip string) string {
|
||||||
|
s := r.String()
|
||||||
|
return strings.TrimPrefix(s, strip)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r resource) loadFromBase(dir string) string {
|
||||||
|
filename := r.String()
|
||||||
|
|
||||||
|
filename = r.strip("/static")
|
||||||
|
|
||||||
|
fullpath := filepath.Join(dir, filename)
|
||||||
|
|
||||||
|
b, err := ioutil.ReadFile(fullpath)
|
||||||
|
if err != nil {
|
||||||
|
panic(fullpath + " failed with error: " + err.Error())
|
||||||
|
}
|
||||||
|
result := string(b)
|
||||||
|
|
||||||
|
if runtime.GOOS != "windows" {
|
||||||
|
result = strings.Replace(result, "\n", "\r\n", -1)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
var urls = []resource{
|
||||||
|
"/static/css/bootstrap.min.css",
|
||||||
|
"/static/js/jquery-2.1.1.js",
|
||||||
|
"/static/favicon.ico",
|
||||||
|
}
|
||||||
|
|
||||||
|
// if bindata's values matches with the assets/... contents
|
||||||
|
// and secondly if the StaticEmbedded had successfully registered
|
||||||
|
// the routes and gave the correct response.
|
||||||
|
func TestEmbeddingGzipFilesIntoApp(t *testing.T) {
|
||||||
|
app := newApp()
|
||||||
|
e := httptest.New(t, app)
|
||||||
|
|
||||||
|
if runtime.GOOS != "windows" {
|
||||||
|
// remove the embedded static favicon for !windows,
|
||||||
|
// it should be built for unix-specific in order to be work
|
||||||
|
urls = urls[0 : len(urls)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, u := range urls {
|
||||||
|
url := u.String()
|
||||||
|
rawContents := u.loadFromBase("./assets")
|
||||||
|
|
||||||
|
response := e.GET(url).Expect()
|
||||||
|
|
||||||
|
if expected, got := response.Raw().StatusCode, httptest.StatusOK; expected != got {
|
||||||
|
t.Fatalf("[%d] of '%s': expected %d status code but got %d", i, url, expected, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
func() {
|
||||||
|
reader, err := gzip.NewReader(bytes.NewBuffer(response.Content))
|
||||||
|
defer reader.Close()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("[%d] of '%s': %v", i, url, err)
|
||||||
|
}
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
reader.WriteTo(buf)
|
||||||
|
if rawContents != buf.String() {
|
||||||
|
t.Fatalf("[%d] of '%s': expected body:\n%s but got:\n%s", i, url, rawContents, buf.String())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ func newApp() *iris.Application {
|
||||||
ctx.View("index.html")
|
ctx.View("index.html")
|
||||||
})
|
})
|
||||||
|
|
||||||
assetHandler := app.StaticEmbeddedHandler("./public", Asset, AssetNames)
|
assetHandler := iris.StaticEmbeddedHandler("./public", Asset, AssetNames, false) // keep that false if you use the `go-bindata` tool.
|
||||||
// as an alternative of SPA you can take a look at the /routing/dynamic-path/root-wildcard
|
// as an alternative of SPA you can take a look at the /routing/dynamic-path/root-wildcard
|
||||||
// example too
|
// example too
|
||||||
// or
|
// or
|
||||||
|
|
|
@ -2208,6 +2208,7 @@ var (
|
||||||
contentDispositionHeaderKey = "Content-Disposition"
|
contentDispositionHeaderKey = "Content-Disposition"
|
||||||
cacheControlHeaderKey = "Cache-Control"
|
cacheControlHeaderKey = "Cache-Control"
|
||||||
contentEncodingHeaderKey = "Content-Encoding"
|
contentEncodingHeaderKey = "Content-Encoding"
|
||||||
|
gzipHeaderValue = "gzip"
|
||||||
acceptEncodingHeaderKey = "Accept-Encoding"
|
acceptEncodingHeaderKey = "Accept-Encoding"
|
||||||
varyHeaderKey = "Vary"
|
varyHeaderKey = "Vary"
|
||||||
)
|
)
|
||||||
|
@ -2360,7 +2361,7 @@ func (ctx *context) StreamWriter(writer func(w io.Writer) bool) {
|
||||||
func (ctx *context) ClientSupportsGzip() bool {
|
func (ctx *context) ClientSupportsGzip() bool {
|
||||||
if h := ctx.GetHeader(acceptEncodingHeaderKey); h != "" {
|
if h := ctx.GetHeader(acceptEncodingHeaderKey); h != "" {
|
||||||
for _, v := range strings.Split(h, ";") {
|
for _, v := range strings.Split(h, ";") {
|
||||||
if strings.Contains(v, "gzip") { // we do Contains because sometimes browsers has the q=, we don't use it atm. || strings.Contains(v,"deflate"){
|
if strings.Contains(v, gzipHeaderValue) { // we do Contains because sometimes browsers has the q=, we don't use it atm. || strings.Contains(v,"deflate"){
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2915,8 +2916,10 @@ func (ctx *context) ServeContent(content io.ReadSeeker, filename string, modtime
|
||||||
ctx.SetLastModified(modtime)
|
ctx.SetLastModified(modtime)
|
||||||
var out io.Writer
|
var out io.Writer
|
||||||
if gzipCompression && ctx.ClientSupportsGzip() {
|
if gzipCompression && ctx.ClientSupportsGzip() {
|
||||||
ctx.writer.Header().Add(varyHeaderKey, acceptEncodingHeaderKey)
|
AddGzipHeaders(ctx.writer)
|
||||||
ctx.Header(contentEncodingHeaderKey, "gzip")
|
|
||||||
|
// ctx.writer.Header().Add(varyHeaderKey, acceptEncodingHeaderKey)
|
||||||
|
// ctx.Header(contentEncodingHeaderKey,gzipHeaderValue)
|
||||||
|
|
||||||
gzipWriter := acquireGzipWriter(ctx.writer)
|
gzipWriter := acquireGzipWriter(ctx.writer)
|
||||||
defer releaseGzipWriter(gzipWriter)
|
defer releaseGzipWriter(gzipWriter)
|
||||||
|
@ -3191,7 +3194,6 @@ func (ctx *context) Exec(method string, path string) {
|
||||||
req.RequestURI = path
|
req.RequestURI = path
|
||||||
req.URL.Path = path
|
req.URL.Path = path
|
||||||
req.Method = method
|
req.Method = method
|
||||||
req.Host = req.Host
|
|
||||||
|
|
||||||
// execute the route from the (internal) context router
|
// execute the route from the (internal) context router
|
||||||
// this way we keep the sessions and the values
|
// this way we keep the sessions and the values
|
||||||
|
|
|
@ -165,12 +165,11 @@ func (w *GzipResponseWriter) WriteNow(contents []byte) (int, error) {
|
||||||
// Or a better idea, acquire and adapt the gzip writer on-time when is not disabled.
|
// Or a better idea, acquire and adapt the gzip writer on-time when is not disabled.
|
||||||
// So that is not needed any more:
|
// So that is not needed any more:
|
||||||
// w.gzipWriter.Reset(noop)
|
// w.gzipWriter.Reset(noop)
|
||||||
|
|
||||||
return w.ResponseWriter.Write(contents)
|
return w.ResponseWriter.Write(contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
w.ResponseWriter.Header().Add(varyHeaderKey, "Accept-Encoding")
|
AddGzipHeaders(w.ResponseWriter)
|
||||||
w.ResponseWriter.Header().Add(contentEncodingHeaderKey, "gzip")
|
|
||||||
|
|
||||||
// if not `WriteNow` but "Content-Length" header
|
// if not `WriteNow` but "Content-Length" header
|
||||||
// is exists, then delete it before `.Write`
|
// is exists, then delete it before `.Write`
|
||||||
// Content-Length should not be there.
|
// Content-Length should not be there.
|
||||||
|
@ -178,6 +177,13 @@ func (w *GzipResponseWriter) WriteNow(contents []byte) (int, error) {
|
||||||
return writeGzip(w.ResponseWriter, contents)
|
return writeGzip(w.ResponseWriter, contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddGzipHeaders just adds the headers "Vary" to "Accept-Encoding"
|
||||||
|
// and "Content-Encoding" to "gzip".
|
||||||
|
func AddGzipHeaders(w ResponseWriter) {
|
||||||
|
w.Header().Add(varyHeaderKey, acceptEncodingHeaderKey)
|
||||||
|
w.Header().Add(contentEncodingHeaderKey, gzipHeaderValue)
|
||||||
|
}
|
||||||
|
|
||||||
// FlushResponse validates the response headers in order to be compatible with the gzip written data
|
// FlushResponse validates the response headers in order to be compatible with the gzip written data
|
||||||
// and writes the data to the underline ResponseWriter.
|
// and writes the data to the underline ResponseWriter.
|
||||||
func (w *GzipResponseWriter) FlushResponse() {
|
func (w *GzipResponseWriter) FlushResponse() {
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Version is the string representation of the current local Iris Web Framework version.
|
// Version is the string representation of the current local Iris Web Framework version.
|
||||||
Version = "10.3.0"
|
Version = "10.4.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CheckForUpdates checks for any available updates
|
// CheckForUpdates checks for any available updates
|
||||||
|
|
|
@ -627,18 +627,6 @@ func (api *APIBuilder) StaticContent(reqPath string, cType string, content []byt
|
||||||
return api.registerResourceRoute(reqPath, h)
|
return api.registerResourceRoute(reqPath, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
// StaticEmbeddedHandler returns a Handler which can serve
|
|
||||||
// embedded into executable files.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Examples: https://github.com/kataras/iris/tree/master/_examples/file-server
|
|
||||||
func (api *APIBuilder) StaticEmbeddedHandler(vdir string, assetFn func(name string) ([]byte, error), namesFn func() []string) context.Handler {
|
|
||||||
// Notes:
|
|
||||||
// This doesn't need to be APIBuilder's scope,
|
|
||||||
// but we'll keep it here for consistently.
|
|
||||||
return StaticEmbeddedHandler(vdir, assetFn, namesFn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StaticEmbedded used when files are distributed inside the app executable, using go-bindata mostly
|
// StaticEmbedded used when files are distributed inside the app executable, using go-bindata mostly
|
||||||
// First parameter is the request path, the path which the files in the vdir will be served to, for example "/static"
|
// First parameter is the request path, the path which the files in the vdir will be served to, for example "/static"
|
||||||
// Second parameter is the (virtual) directory path, for example "./assets"
|
// Second parameter is the (virtual) directory path, for example "./assets"
|
||||||
|
@ -647,8 +635,25 @@ func (api *APIBuilder) StaticEmbeddedHandler(vdir string, assetFn func(name stri
|
||||||
//
|
//
|
||||||
// Returns the GET *Route.
|
// Returns the GET *Route.
|
||||||
//
|
//
|
||||||
// Examples: https://github.com/kataras/iris/tree/master/_examples/file-server
|
// Example: https://github.com/kataras/iris/tree/master/_examples/file-server/embedding-files-into-app
|
||||||
func (api *APIBuilder) StaticEmbedded(requestPath string, vdir string, assetFn func(name string) ([]byte, error), namesFn func() []string) *Route {
|
func (api *APIBuilder) StaticEmbedded(requestPath string, vdir string, assetFn func(name string) ([]byte, error), namesFn func() []string) *Route {
|
||||||
|
return api.staticEmbedded(requestPath, vdir, assetFn, namesFn, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StaticEmbeddedGzip registers a route which can serve embedded gziped files
|
||||||
|
// that are embedded using the https://github.com/kataras/bindata tool and only.
|
||||||
|
// It's 8 times faster than the `StaticEmbeddedHandler` with `go-bindata` but
|
||||||
|
// it sends gzip response only, so the client must be aware that is expecting a gzip body
|
||||||
|
// (browsers and most modern browsers do that, so you can use it without fair).
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Example: https://github.com/kataras/iris/tree/master/_examples/file-server/embedding-gziped-files-into-app
|
||||||
|
func (api *APIBuilder) StaticEmbeddedGzip(requestPath string, vdir string, gzipAssetFn func(name string) ([]byte, error), gzipNamesFn func() []string) *Route {
|
||||||
|
return api.staticEmbedded(requestPath, vdir, gzipAssetFn, gzipNamesFn, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// look fs.go#StaticEmbeddedHandler
|
||||||
|
func (api *APIBuilder) staticEmbedded(requestPath string, vdir string, assetFn func(name string) ([]byte, error), namesFn func() []string, assetsGziped bool) *Route {
|
||||||
fullpath := joinPath(api.relativePath, requestPath)
|
fullpath := joinPath(api.relativePath, requestPath)
|
||||||
// if subdomain,
|
// if subdomain,
|
||||||
// here we get the full path of the path only,
|
// here we get the full path of the path only,
|
||||||
|
@ -656,9 +661,10 @@ func (api *APIBuilder) StaticEmbedded(requestPath string, vdir string, assetFn f
|
||||||
// and we need that path to call the `StripPrefix`.
|
// and we need that path to call the `StripPrefix`.
|
||||||
_, fullpath = splitSubdomainAndPath(fullpath)
|
_, fullpath = splitSubdomainAndPath(fullpath)
|
||||||
|
|
||||||
requestPath = joinPath(fullpath, WildcardParam("file"))
|
paramName := "file"
|
||||||
|
requestPath = joinPath(requestPath, WildcardParam(paramName))
|
||||||
|
|
||||||
h := api.StaticEmbeddedHandler(vdir, assetFn, namesFn)
|
h := StaticEmbeddedHandler(vdir, assetFn, namesFn, assetsGziped)
|
||||||
|
|
||||||
if fullpath != "/" {
|
if fullpath != "/" {
|
||||||
h = StripPrefix(fullpath, h)
|
h = StripPrefix(fullpath, h)
|
||||||
|
@ -745,16 +751,17 @@ func (api *APIBuilder) Favicon(favPath string, requestPath ...string) *Route {
|
||||||
//
|
//
|
||||||
// Returns the GET *Route.
|
// Returns the GET *Route.
|
||||||
func (api *APIBuilder) StaticWeb(requestPath string, systemPath string) *Route {
|
func (api *APIBuilder) StaticWeb(requestPath string, systemPath string) *Route {
|
||||||
paramName := "file"
|
|
||||||
|
|
||||||
fullpath := joinPath(api.relativePath, requestPath)
|
fullpath := joinPath(api.relativePath, requestPath)
|
||||||
|
|
||||||
// if subdomain,
|
// if subdomain,
|
||||||
// here we get the full path of the path only,
|
// here we get the full path of the path only,
|
||||||
// because a subdomain can have parties as well
|
// because a subdomain can have parties as well
|
||||||
// and we need that path to call the `StripPrefix`.
|
// and we need that path to call the `StripPrefix`.
|
||||||
_, fullpath = splitSubdomainAndPath(fullpath)
|
_, fullpath = splitSubdomainAndPath(fullpath)
|
||||||
|
|
||||||
requestPath = joinPath(fullpath, WildcardParam(paramName))
|
paramName := "file"
|
||||||
|
requestPath = joinPath(requestPath, WildcardParam(paramName))
|
||||||
|
|
||||||
h := NewStaticHandlerBuilder(systemPath).Listing(false).Build()
|
h := NewStaticHandlerBuilder(systemPath).Listing(false).Build()
|
||||||
|
|
||||||
if fullpath != "/" {
|
if fullpath != "/" {
|
||||||
|
|
|
@ -21,12 +21,11 @@ import (
|
||||||
"github.com/kataras/iris/context"
|
"github.com/kataras/iris/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StaticEmbeddedHandler returns a Handler which can serve
|
// StaticEmbeddedHandler returns a Handler which can serve embedded files
|
||||||
// embedded into executable files.
|
// that are embedded using the go-bindata tool(assetsGziped = false) or the kataras/bindata tool (assetsGziped = true).
|
||||||
//
|
|
||||||
//
|
//
|
||||||
// Examples: https://github.com/kataras/iris/tree/master/_examples/file-server
|
// Examples: https://github.com/kataras/iris/tree/master/_examples/file-server
|
||||||
func StaticEmbeddedHandler(vdir string, assetFn func(name string) ([]byte, error), namesFn func() []string) context.Handler {
|
func StaticEmbeddedHandler(vdir string, assetFn func(name string) ([]byte, error), namesFn func() []string, assetsGziped bool) context.Handler {
|
||||||
// Depends on the command the user gave to the go-bindata
|
// Depends on the command the user gave to the go-bindata
|
||||||
// the assset path (names) may be or may not be prepended with a slash.
|
// the assset path (names) may be or may not be prepended with a slash.
|
||||||
// What we do: we remove the ./ from the vdir which should be
|
// What we do: we remove the ./ from the vdir which should be
|
||||||
|
@ -63,6 +62,7 @@ func StaticEmbeddedHandler(vdir string, assetFn func(name string) ([]byte, error
|
||||||
|
|
||||||
modtime := time.Now()
|
modtime := time.Now()
|
||||||
h := func(ctx context.Context) {
|
h := func(ctx context.Context) {
|
||||||
|
|
||||||
reqPath := strings.TrimPrefix(ctx.Request().URL.Path, "/"+vdir)
|
reqPath := strings.TrimPrefix(ctx.Request().URL.Path, "/"+vdir)
|
||||||
// i.e : /css/main.css
|
// i.e : /css/main.css
|
||||||
|
|
||||||
|
@ -80,9 +80,17 @@ func StaticEmbeddedHandler(vdir string, assetFn func(name string) ([]byte, error
|
||||||
|
|
||||||
buf, err := assetFn(path) // remove the first slash
|
buf, err := assetFn(path) // remove the first slash
|
||||||
|
|
||||||
|
if assetsGziped {
|
||||||
|
// this will add the "Vary" : "Accept-Encoding"
|
||||||
|
// and "Content-Encoding": "gzip"
|
||||||
|
// headers.
|
||||||
|
context.AddGzipHeaders(ctx.ResponseWriter())
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.ContentType(cType)
|
ctx.ContentType(cType)
|
||||||
if _, err := ctx.WriteWithExpiration(buf, modtime); err != nil {
|
if _, err := ctx.WriteWithExpiration(buf, modtime); err != nil {
|
||||||
ctx.StatusCode(http.StatusInternalServerError)
|
ctx.StatusCode(http.StatusInternalServerError)
|
||||||
|
@ -93,7 +101,6 @@ func StaticEmbeddedHandler(vdir string, assetFn func(name string) ([]byte, error
|
||||||
|
|
||||||
// not found or error
|
// not found or error
|
||||||
ctx.NotFound()
|
ctx.NotFound()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return h
|
return h
|
||||||
|
@ -140,6 +147,7 @@ type fsHandler struct {
|
||||||
// user options, only directory is required.
|
// user options, only directory is required.
|
||||||
directory http.Dir
|
directory http.Dir
|
||||||
listDirectories bool
|
listDirectories bool
|
||||||
|
gzip bool
|
||||||
// these are init on the Build() call
|
// these are init on the Build() call
|
||||||
filesystem http.FileSystem
|
filesystem http.FileSystem
|
||||||
once sync.Once
|
once sync.Once
|
||||||
|
@ -183,18 +191,17 @@ func NewStaticHandlerBuilder(dir string) StaticHandlerBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gzip if enable is true then gzip compression is enabled for this static directory
|
// Gzip if enable is true then gzip compression is enabled for this static directory.
|
||||||
// Defaults to false
|
//
|
||||||
|
// Defaults to false.
|
||||||
func (w *fsHandler) Gzip(enable bool) StaticHandlerBuilder {
|
func (w *fsHandler) Gzip(enable bool) StaticHandlerBuilder {
|
||||||
w.begin = append(w.begin, func(ctx context.Context) {
|
w.gzip = enable
|
||||||
ctx.Gzip(true)
|
|
||||||
ctx.Next()
|
|
||||||
})
|
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listing turn on/off the 'show files and directories'.
|
// Listing turn on/off the 'show files and directories'.
|
||||||
// Defaults to false
|
//
|
||||||
|
// Defaults to false.
|
||||||
func (w *fsHandler) Listing(listDirectoriesOnOff bool) StaticHandlerBuilder {
|
func (w *fsHandler) Listing(listDirectoriesOnOff bool) StaticHandlerBuilder {
|
||||||
w.listDirectories = listDirectoriesOnOff
|
w.listDirectories = listDirectoriesOnOff
|
||||||
return w
|
return w
|
||||||
|
@ -243,9 +250,15 @@ func (w *fsHandler) Build() context.Handler {
|
||||||
|
|
||||||
// Note the request.url.path is changed but request.RequestURI is not
|
// Note the request.url.path is changed but request.RequestURI is not
|
||||||
// so on custom errors we use the requesturi instead.
|
// so on custom errors we use the requesturi instead.
|
||||||
// this can be changed
|
// this can be changed.
|
||||||
|
|
||||||
|
// take the gzip setting.
|
||||||
|
gzipEnabled := w.gzip
|
||||||
|
if !gzipEnabled {
|
||||||
|
// if false then check if the dev did something like `ctx.Gzip(true)`.
|
||||||
|
_, gzipEnabled = ctx.ResponseWriter().(*context.GzipResponseWriter)
|
||||||
|
}
|
||||||
|
|
||||||
_, gzipEnabled := ctx.ResponseWriter().(*context.GzipResponseWriter)
|
|
||||||
_, prevStatusCode := serveFile(ctx,
|
_, prevStatusCode := serveFile(ctx,
|
||||||
w.filesystem,
|
w.filesystem,
|
||||||
path.Clean(upath),
|
path.Clean(upath),
|
||||||
|
@ -272,15 +285,10 @@ func (w *fsHandler) Build() context.Handler {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// go to the next middleware
|
// go to the next middleware, if any.
|
||||||
ctx.Next()
|
ctx.Next()
|
||||||
}
|
}
|
||||||
if len(w.begin) > 0 {
|
|
||||||
handlers := append(w.begin[0:], fileserver)
|
|
||||||
w.handler = func(ctx context.Context) {
|
|
||||||
ctx.Do(handlers)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.handler = fileserver
|
w.handler = fileserver
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -294,10 +302,10 @@ func (w *fsHandler) Build() context.Handler {
|
||||||
// replying with an HTTP 404 not found error.
|
// replying with an HTTP 404 not found error.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// fileserver := iris.StaticHandler("./static_files", false, false)
|
// fileserver := Party#StaticHandler("./static_files", false, false)
|
||||||
// h := router.StripPrefix("/static", fileserver)
|
// h := router.StripPrefix("/static", fileserver)
|
||||||
// app.Get("/static", h)
|
// app.Get("/static/{f:path}", h)
|
||||||
//
|
// app.Head("/static/{f:path}", h)
|
||||||
func StripPrefix(prefix string, h context.Handler) context.Handler {
|
func StripPrefix(prefix string, h context.Handler) context.Handler {
|
||||||
if prefix == "" {
|
if prefix == "" {
|
||||||
return h
|
return h
|
||||||
|
@ -821,7 +829,7 @@ func serveFile(ctx context.Context, fs http.FileSystem, name string, redirect bo
|
||||||
|
|
||||||
// try to find and send the correct content type based on the filename
|
// try to find and send the correct content type based on the filename
|
||||||
// and the binary data inside "f".
|
// and the binary data inside "f".
|
||||||
detectOrWriteContentType(ctx, d.Name(), f)
|
// detectOrWriteContentType(ctx, d.Name(), f)
|
||||||
|
|
||||||
return "", http.StatusOK
|
return "", http.StatusOK
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ func cleanPath(s string) string {
|
||||||
return "/"
|
return "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove suffix "/".
|
// remove suffix "/", if it's root "/" then it will add it as a prefix below.
|
||||||
if lidx := len(s) - 1; s[lidx] == '/' {
|
if lidx := len(s) - 1; s[lidx] == '/' {
|
||||||
s = s[:lidx]
|
s = s[:lidx]
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ func TestCleanPath(t *testing.T) {
|
||||||
path string
|
path string
|
||||||
expected string
|
expected string
|
||||||
}{
|
}{
|
||||||
|
{"/",
|
||||||
|
"/"},
|
||||||
{"noslashPrefix",
|
{"noslashPrefix",
|
||||||
"/noslashPrefix"},
|
"/noslashPrefix"},
|
||||||
{"slashSuffix/",
|
{"slashSuffix/",
|
||||||
|
|
2
doc.go
2
doc.go
|
@ -35,7 +35,7 @@ Source code and other details for the project are available at GitHub:
|
||||||
|
|
||||||
Current Version
|
Current Version
|
||||||
|
|
||||||
10.3.0
|
10.4.0
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
|
|
||||||
|
|
12
iris.go
12
iris.go
|
@ -346,6 +346,18 @@ var (
|
||||||
//
|
//
|
||||||
// Examples: https://github.com/kataras/iris/tree/master/_examples/file-server
|
// Examples: https://github.com/kataras/iris/tree/master/_examples/file-server
|
||||||
StaticEmbeddedHandler = router.StaticEmbeddedHandler
|
StaticEmbeddedHandler = router.StaticEmbeddedHandler
|
||||||
|
// StripPrefix returns a handler that serves HTTP requests
|
||||||
|
// by removing the given prefix from the request URL's Path
|
||||||
|
// and invoking the handler h. StripPrefix handles a
|
||||||
|
// request for a path that doesn't begin with prefix by
|
||||||
|
// replying with an HTTP 404 not found error.
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
// fileserver := Party#StaticHandler("./static_files", false, false)
|
||||||
|
// h := iris.StripPrefix("/static", fileserver)
|
||||||
|
// app.Get("/static/{f:path}", h)
|
||||||
|
// app.Head("/static/{f:path}", h)
|
||||||
|
StripPrefix = router.StripPrefix
|
||||||
// Gzip is a middleware which enables writing
|
// Gzip is a middleware which enables writing
|
||||||
// using gzip compression, if client supports.
|
// using gzip compression, if client supports.
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue
Block a user