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:
Gerasimos Maropoulos 2018-03-14 07:17:35 +02:00
parent 1e0c707366
commit 56215eeb71
28 changed files with 20453 additions and 67 deletions

2
Gopkg.lock generated
View File

@ -89,7 +89,7 @@
branch = "master"
name = "github.com/iris-contrib/httpexpect"
packages = ["."]
revision = "65e93247e7071782e760f82086e8b677cca0c78a"
revision = "ebe99fcebbcedf6e7916320cce24c3e1832766ac"
[[projects]]
branch = "master"

View File

@ -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.
# 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
- 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.

View File

@ -17,9 +17,13 @@
**Πώς να αναβαθμίσετε**: Ανοίξτε την γραμμή εντολών σας και εκτελέστε αυτήν την εντολή: `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
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

View File

@ -17,6 +17,10 @@
**如何升级**: 打开命令行执行以下命令: `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 版本更新
- 只有一项 API 更改 [Application/Context/Router#RouteExists](https://godoc.org/github.com/kataras/iris/core/router#Router.RouteExists), 将 `Context` 作为第一参数,而不是最后一个。

View File

@ -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>
[![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.
@ -106,7 +106,7 @@ _Updated at: [Tuesday, 21 November 2017](_benchmarks/README_UNIX.md)_
## 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)
- 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)

View File

@ -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>
[![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.
@ -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)
- Έχετε οποιεσδήποτε ερωτήσεις ή πρέπει να μιλήσετε με κάποιον έμπειρο για την επίλυση ενός προβλήματος σε πραγματικό χρόνο; Ελάτε μαζί μας στην [συνομιλία κοινότητας](https://chat.iris-go.com)
- Συμπληρώστε την αναφορά εμπειρίας χρήστη κάνοντας κλικ [εδώ](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)

View File

@ -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>
[![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.
@ -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)
- У Вас есть какие-либо вопросы или Вам нужно поговорить с кем-то, кто бы смог решить Вашу проблему в режиме реального времени? Присоединяйтесь к нам в [чате сообщества](https://chat.iris-go.com)
- Заполните наш отчет о пользовательском опыте на основе формы, нажав [здесь](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)

View File

@ -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>
[![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开发框架。
@ -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)
- 您是否有任何疑问或需要与有经验的人士交谈以实时解决问题? [加入我们的聊天](https://chat.iris-go.com)
- [点击这里完成我们基于表单的用户体验报告](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)

View File

@ -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

View File

@ -310,6 +310,7 @@ You can serve [quicktemplate](https://github.com/valyala/quicktemplate) and [her
- [Favicon](file-server/favicon/main.go)
- [Basic](file-server/basic/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)
- Single Page Applications
* [single Page Application](file-server/single-page-application/basic/main.go)

View File

@ -10,7 +10,8 @@ import (
// $ go build
// $ ./embedding-files-into-app
// "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 {
app := iris.New()

View File

@ -34,6 +34,7 @@ func (r resource) loadFromBase(dir string) string {
}
result := string(b)
if runtime.GOOS != "windows" {
result = strings.Replace(result, "\n", "\r\n", -1)
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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"))
}

View File

@ -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())
}
}()
}
}

View File

@ -22,7 +22,7 @@ func newApp() *iris.Application {
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
// example too
// or

View File

@ -2208,6 +2208,7 @@ var (
contentDispositionHeaderKey = "Content-Disposition"
cacheControlHeaderKey = "Cache-Control"
contentEncodingHeaderKey = "Content-Encoding"
gzipHeaderValue = "gzip"
acceptEncodingHeaderKey = "Accept-Encoding"
varyHeaderKey = "Vary"
)
@ -2360,7 +2361,7 @@ func (ctx *context) StreamWriter(writer func(w io.Writer) bool) {
func (ctx *context) ClientSupportsGzip() bool {
if h := ctx.GetHeader(acceptEncodingHeaderKey); 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
}
}
@ -2915,8 +2916,10 @@ func (ctx *context) ServeContent(content io.ReadSeeker, filename string, modtime
ctx.SetLastModified(modtime)
var out io.Writer
if gzipCompression && ctx.ClientSupportsGzip() {
ctx.writer.Header().Add(varyHeaderKey, acceptEncodingHeaderKey)
ctx.Header(contentEncodingHeaderKey, "gzip")
AddGzipHeaders(ctx.writer)
// ctx.writer.Header().Add(varyHeaderKey, acceptEncodingHeaderKey)
// ctx.Header(contentEncodingHeaderKey,gzipHeaderValue)
gzipWriter := acquireGzipWriter(ctx.writer)
defer releaseGzipWriter(gzipWriter)
@ -3191,7 +3194,6 @@ func (ctx *context) Exec(method string, path string) {
req.RequestURI = path
req.URL.Path = path
req.Method = method
req.Host = req.Host
// execute the route from the (internal) context router
// this way we keep the sessions and the values

View File

@ -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.
// So that is not needed any more:
// w.gzipWriter.Reset(noop)
return w.ResponseWriter.Write(contents)
}
w.ResponseWriter.Header().Add(varyHeaderKey, "Accept-Encoding")
w.ResponseWriter.Header().Add(contentEncodingHeaderKey, "gzip")
AddGzipHeaders(w.ResponseWriter)
// if not `WriteNow` but "Content-Length" header
// is exists, then delete it before `.Write`
// Content-Length should not be there.
@ -178,6 +177,13 @@ func (w *GzipResponseWriter) WriteNow(contents []byte) (int, error) {
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
// and writes the data to the underline ResponseWriter.
func (w *GzipResponseWriter) FlushResponse() {

View File

@ -13,7 +13,7 @@ import (
const (
// 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

View File

@ -627,18 +627,6 @@ func (api *APIBuilder) StaticContent(reqPath string, cType string, content []byt
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
// 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"
@ -647,8 +635,25 @@ func (api *APIBuilder) StaticEmbeddedHandler(vdir string, assetFn func(name stri
//
// 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 {
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)
// if subdomain,
// 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`.
_, 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 != "/" {
h = StripPrefix(fullpath, h)
@ -745,16 +751,17 @@ func (api *APIBuilder) Favicon(favPath string, requestPath ...string) *Route {
//
// Returns the GET *Route.
func (api *APIBuilder) StaticWeb(requestPath string, systemPath string) *Route {
paramName := "file"
fullpath := joinPath(api.relativePath, requestPath)
// if subdomain,
// here we get the full path of the path only,
// because a subdomain can have parties as well
// and we need that path to call the `StripPrefix`.
_, fullpath = splitSubdomainAndPath(fullpath)
requestPath = joinPath(fullpath, WildcardParam(paramName))
paramName := "file"
requestPath = joinPath(requestPath, WildcardParam(paramName))
h := NewStaticHandlerBuilder(systemPath).Listing(false).Build()
if fullpath != "/" {

View File

@ -21,12 +21,11 @@ import (
"github.com/kataras/iris/context"
)
// StaticEmbeddedHandler returns a Handler which can serve
// embedded into executable files.
//
// StaticEmbeddedHandler returns a Handler which can serve embedded 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
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
// 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
@ -63,6 +62,7 @@ func StaticEmbeddedHandler(vdir string, assetFn func(name string) ([]byte, error
modtime := time.Now()
h := func(ctx context.Context) {
reqPath := strings.TrimPrefix(ctx.Request().URL.Path, "/"+vdir)
// 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
if assetsGziped {
// this will add the "Vary" : "Accept-Encoding"
// and "Content-Encoding": "gzip"
// headers.
context.AddGzipHeaders(ctx.ResponseWriter())
}
if err != nil {
continue
}
ctx.ContentType(cType)
if _, err := ctx.WriteWithExpiration(buf, modtime); err != nil {
ctx.StatusCode(http.StatusInternalServerError)
@ -93,7 +101,6 @@ func StaticEmbeddedHandler(vdir string, assetFn func(name string) ([]byte, error
// not found or error
ctx.NotFound()
}
return h
@ -140,6 +147,7 @@ type fsHandler struct {
// user options, only directory is required.
directory http.Dir
listDirectories bool
gzip bool
// these are init on the Build() call
filesystem http.FileSystem
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
// Defaults to false
// Gzip if enable is true then gzip compression is enabled for this static directory.
//
// Defaults to false.
func (w *fsHandler) Gzip(enable bool) StaticHandlerBuilder {
w.begin = append(w.begin, func(ctx context.Context) {
ctx.Gzip(true)
ctx.Next()
})
w.gzip = enable
return w
}
// Listing turn on/off the 'show files and directories'.
// Defaults to false
//
// Defaults to false.
func (w *fsHandler) Listing(listDirectoriesOnOff bool) StaticHandlerBuilder {
w.listDirectories = listDirectoriesOnOff
return w
@ -243,9 +250,15 @@ func (w *fsHandler) Build() context.Handler {
// Note the request.url.path is changed but request.RequestURI is not
// 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,
w.filesystem,
path.Clean(upath),
@ -272,15 +285,10 @@ func (w *fsHandler) Build() context.Handler {
return
}
// go to the next middleware
// go to the next middleware, if any.
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
})
@ -294,10 +302,10 @@ func (w *fsHandler) Build() context.Handler {
// replying with an HTTP 404 not found error.
//
// Usage:
// fileserver := iris.StaticHandler("./static_files", false, false)
// fileserver := Party#StaticHandler("./static_files", false, false)
// 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 {
if prefix == "" {
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
// and the binary data inside "f".
detectOrWriteContentType(ctx, d.Name(), f)
// detectOrWriteContentType(ctx, d.Name(), f)
return "", http.StatusOK
}

View File

@ -73,7 +73,7 @@ func joinPath(path1 string, path2 string) string {
// cleanPath applies the following rules
// iteratively until no further processing can be done:
//
// 1. Replace multiple slashes with a single slash.
// 1. Replace multiple slashes with a single slash.
// 2. Replace '\' with '/'
// 3. Replace "\\" with '/'
// 4. Ignore anything inside '{' and '}'
@ -87,7 +87,7 @@ func cleanPath(s string) string {
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] == '/' {
s = s[:lidx]
}

View File

@ -9,6 +9,8 @@ func TestCleanPath(t *testing.T) {
path string
expected string
}{
{"/",
"/"},
{"noslashPrefix",
"/noslashPrefix"},
{"slashSuffix/",

2
doc.go
View File

@ -35,7 +35,7 @@ Source code and other details for the project are available at GitHub:
Current Version
10.3.0
10.4.0
Installation

12
iris.go
View File

@ -346,6 +346,18 @@ var (
//
// Examples: https://github.com/kataras/iris/tree/master/_examples/file-server
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
// using gzip compression, if client supports.
//