Change the new ctx.Compres to ctx.CompressWriter and iris.Compress and iris.CompressReader as one iris.Compression

Update the README example

(master development branch)


Former-commit-id: fb67858fe5be5662b5816df41020c28ff9a8c6f6
This commit is contained in:
Gerasimos (Makis) Maropoulos 2020-07-20 13:36:39 +03:00
parent beb67dc495
commit d697426cb6
15 changed files with 141 additions and 48 deletions

View File

@ -448,7 +448,7 @@ New Package-level Variables:
- `iris.DirListRichOptions` to pass on `iris.DirListRich` method.
- `iris.DirListRich` to override the default look and feel if the `DirOptions.ShowList` was set to true, can be passed to `DirOptions.DirList` field.
- `DirOptions.PushTargets` for http/2 push on index [*](https://github.com/kataras/iris/tree/master/_examples/file-server/http2push/main.go).
- `iris.Compress` and `iris.CompressReader` middleware to compress responses and decode compressed request data respectfully.
- `iris.Compression` middleware to compress responses and decode compressed request data respectfully.
- `iris.B, KB, MB, GB, TB, PB, EB` for byte units.
- `TLSNoRedirect` to disable automatic "http://" to "https://" redirections (see below)
- `CookieAllowReclaim`, `CookieAllowSubdomains`, `CookieSameSite`, `CookieSecure` and `CookieEncoding` to bring previously sessions-only features to all cookies in the request.
@ -456,7 +456,7 @@ New Package-level Variables:
New Context Methods:
- `Context.SetErr(error)` and `Context.GetErr() error` helpers
- `Context.Compress(bool) error` and `Context.CompressReader(bool) error`
- `Context.CompressWriter(bool) error` and `Context.CompressReader(bool) error`
- `Context.Clone() Context` returns a copy of the Context.
- `Context.IsCanceled() bool` reports whether the request has been canceled by the client.
- `Context.IsSSL() bool` reports whether the request is under HTTPS SSL (New `Configuration.SSLProxyHeaders` and `HostProxyHeaders` fields too).
@ -487,10 +487,9 @@ New Context Methods:
Breaking Changes:
- `ctx.Gzip(boolean)` replaced with `ctx.Compress(boolean) error`.
- `ctx.Gzip(boolean)` replaced with `ctx.CompressWriter(boolean) error`.
- `ctx.GzipReader(boolean) error` replaced with `ctx.CompressReader(boolean) error`.
- `iris.Gzip` replaced with `iris.Compress` (middleware).
- `iris.GzipReader` replaced with `iris.CompressReader` (middleware).
- `iris.Gzip` and `iris.GzipReader` replaced with `iris.Compression` (middleware).
- `ctx.ClientSupportsGzip() bool` replaced with `ctx.ClientSupportsEncoding("gzip", "br" ...) bool`.
- `ctx.GzipResponseWriter()` is **removed**.
- `Party.HandleDir` now returns a list of `[]*Route` (GET and HEAD) instead of GET only.
@ -502,7 +501,7 @@ Breaking Changes:
- `sessions#Config.Encode` and `Decode` are removed in favor of (the existing) `Encoding` field.
- `versioning.GetVersion` now returns an empty string if version wasn't found.
- Change the MIME type of `Javascript .js` and `JSONP` as the HTML specification now recommends to `"text/javascript"` instead of the obselete `"application/javascript"`. This change was pushed to the `Go` language itself as well. See <https://go-review.googlesource.com/c/go/+/186927/>.
- Remove the last input argument of `enableGzipCompression` in `Context.ServeContent`, `ServeFile` methods. This was deprecated a few versions ago. A middleware (`app.Use(iris.Compress)`) or a prior call to `Context.Compress(true)` will enable compression. Also these two methods and `Context.SendFile` one now support `Content-Range` and `Accept-Ranges` correctly out of the box (`net/http` had a bug, which is now fixed).
- Remove the last input argument of `enableGzipCompression` in `Context.ServeContent`, `ServeFile` methods. This was deprecated a few versions ago. A middleware (`app.Use(iris.CompressWriter)`) or a prior call to `Context.CompressWriter(true)` will enable compression. Also these two methods and `Context.SendFile` one now support `Content-Range` and `Accept-Ranges` correctly out of the box (`net/http` had a bug, which is now fixed).
- `Context.ServeContent` no longer returns an error, see `ServeContentWithRate`, `ServeFileWithRate` and `SendFileWithRate` new methods too.
- `route.Trace() string` changed to `route.Trace(w io.Writer)`, to achieve the same result just pass a `bytes.Buffer`
- `var mvc.AutoBinding` removed as the default behavior now resolves such dependencies automatically (see [[FEATURE REQUEST] MVC serving gRPC-compatible controller](https://github.com/kataras/iris/issues/1449)).

105
README.md
View File

@ -26,9 +26,6 @@ Learn what [others saying about Iris](https://iris-go.com/testimonials/) and **[
## 📖 Learning Iris
<details>
<summary>Quick start</summary>
```sh
# https://github.com/kataras/iris/wiki/Installation
$ go get github.com/kataras/iris/v12@master
@ -42,18 +39,110 @@ package main
import "github.com/kataras/iris/v12"
func main() {
app := iris.New()
app.Get("/", index)
app.Listen(":8080")
app := iris.New()
booksAPI := app.Party("/books")
{
booksAPI.Use(iris.Compression)
// GET: http://localhost:8080/books
booksAPI.Get("/", list)
// POST: http://localhost:8080/books
booksAPI.Post("/", create)
}
app.Listen(":8080")
}
func index(ctx iris.Context) {
ctx.HTML("<h1>Hello, World!</h1>")
// Book example.
type Book struct {
Title string `json:"title"`
}
func list(ctx iris.Context) {
books := []Book{
{"Mastering Concurrency in Go"},
{"Go Design Patterns"},
{"Black Hat Go"},
}
ctx.JSON(books)
// TIP: negotiate the response between server's prioritizes
// and client's requirements, instead of ctx.JSON:
// ctx.Negotiation().JSON().MsgPack().Protobuf()
// ctx.Negotiate(books)
}
func create(ctx iris.Context) {
var b Book
err := ctx.ReadJSON(&b)
// TIP: use ctx.ReadBody(&b) to bind
// any type of incoming data instead.
if err != nil {
ctx.StopWithProblem(iris.StatusBadRequest, iris.NewProblem().
Title("Book creation failure").DetailErr(err))
// TIP: use ctx.StopWithError(code, err) when only
// plain text responses are expected on errors.
return
}
println("Received Book: " + b.Title)
ctx.StatusCode(iris.StatusCreated)
}
```
**Run** your Iris web server:
```sh
$ go run main.go
> Now listening on: http://localhost:8080
> Application started. Press CTRL+C to shut down.
```
**List** Books:
```sh
$ curl --header 'Accept-Encoding:gzip' http://localhost:8080/books
[
{
"title": "Mastering Concurrency in Go"
},
{
"title": "Go Design Patterns"
},
{
"title": "Black Hat Go"
}
]
```
**Create** a new Book:
```sh
$ curl -i -X POST \
--header 'Content-Encoding:gzip' \
--header 'Content-Type:application/json' \
--data "{\"title\":\"Writing An Interpreter In Go\"}" \
http://localhost:8080/books
> HTTP/1.1 201 Created
```
That's how an **error** response looks like:
```sh
$ curl -X POST --data "{\"title\" \"not valid one\"}" \
http://localhost:8080/books
> HTTP/1.1 400 Bad Request
{
"status": 400,
"title": "Book creation failure"
"detail": "invalid character '\"' after object key",
}
```
</details>

View File

@ -11,7 +11,7 @@ func main() {
func newApp() *iris.Application {
app := iris.New()
// HERE and you are ready to GO:
app.Use(iris.Compress, iris.CompressReader)
app.Use(iris.Compression)
app.Get("/", send)
app.Post("/", receive)
@ -41,7 +41,7 @@ func receive(ctx iris.Context) {
/* Manually:
func enableCompression(ctx iris.Context) {
// Enable writing using compression (deflate, gzip, brotli, snappy, s2):
err := ctx.Compress(true)
err := ctx.CompressWriter(true)
if err != nil {
ctx.Application().Logger().Debugf("writer: %v", err)
// if you REQUIRE server to SEND compressed data then `return` here.

View File

@ -35,8 +35,10 @@ func TestHandlerUsingNetHTTP(t *testing.T) {
ctx.WriteString("Hello, World!")
}
// A shortcut for net/http/httptest.NewRecorder/NewRequest.
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/", nil)
httptest.Do(w, r, handler)
if expected, got := "Hello, World!", w.Body.String(); expected != got {
t.Fatalf("expected body: %s but got: %s", expected, got)

View File

@ -17,7 +17,7 @@ func main() {
app := iris.New()
app.Get("/users", func(ctx iris.Context) {
ctx.Compress(true)
ctx.CompressWriter(true)
ctx.ContentType("text/html")
userList := []string{

View File

@ -14,7 +14,7 @@ func main() {
// - {{ current }}
app.RegisterView(iris.HTML("./templates", ".html"))
app.Get("/", func(ctx iris.Context) {
ctx.Compress(true) // enable compression based on Accept-Encoding (e.g. "gzip").
ctx.CompressWriter(true) // enable compression based on Accept-Encoding (e.g. "gzip").
ctx.ViewData("Name", "iris") // the .Name inside the ./templates/hi.html.
ctx.View("hi.html") // render the template with the file name relative to the './templates'.
})

View File

@ -8,7 +8,7 @@ import (
// ExecuteTemplate renders a "tmpl" partial template to the `Context.ResponseWriter`.
func ExecuteTemplate(ctx iris.Context, tmpl templates.Partial) {
ctx.Compress(true)
ctx.CompressWriter(true)
ctx.ContentType("text/html")
templates.WriteTemplate(ctx, tmpl)
}

View File

@ -16,7 +16,7 @@ func main() {
// TIP: append .Reload(true) to reload the templates on each request.
app.Get("/", func(ctx iris.Context) {
ctx.Compress(true)
ctx.CompressWriter(true)
ctx.ViewData("", mypage{"My Page title", "Hello world!"})
ctx.View("mypage.html")
// Note that: you can pass "layout" : "otherLayout.html" to bypass the config's Layout property

View File

@ -17,7 +17,7 @@ func main() {
app.HandleDir("/", "./client")
app.Get("/", func(ctx iris.Context) {
// ctx.Compress(true)
// ctx.CompressWriter(true)
ctx.ServeFile("./client/hello.html")
})

View File

@ -200,20 +200,10 @@ var (
)
var (
// Compress is a middleware which enables writing
// using compression, if client supports.
Compress = func(ctx Context) {
ctx.Compress(true)
ctx.Next()
}
// CompressReader is a middleware which enables decompression,
// when client sends compressed data.
//
// Similar to: func(ctx iris.Context) {
// ctx.CompressReader(true)
// ctx.Next()
// }
CompressReader = func(ctx Context) {
// Compression is a middleware which enables
// writing and reading using the best offered compression.
Compression = func(ctx Context) {
ctx.CompressWriter(true)
ctx.CompressReader(true)
ctx.Next()
}

View File

@ -2238,8 +2238,9 @@ func (ctx *Context) StreamWriter(writer func(w io.Writer) error) error {
// ClientSupportsEncoding reports whether the
// client expects one of the given "encodings" compression.
//
// Note, instead of `Compress` method, this one just reports back the first valid encoding it sees,
// Note, this method just reports back the first valid encoding it sees,
// meaning that request accept-encoding offers don't matter here.
// See `CompressWriter` too.
func (ctx *Context) ClientSupportsEncoding(encodings ...string) bool {
if len(encodings) == 0 {
return false
@ -2258,20 +2259,20 @@ func (ctx *Context) ClientSupportsEncoding(encodings ...string) bool {
return false
}
// Compress enables or disables the compress response writer.
// CompressWriter enables or disables the compress response writer.
// if the client expects a valid compression algorithm then this
// will change the response writer to a compress writer instead.
// All future write and rich write methods will respect this option.
// Usage:
// app.Use(func(ctx iris.Context){
// err := ctx.Compress(true)
// err := ctx.CompressWriter(true)
// ctx.Next()
// })
// The recommendation is to compress data as much as possible and therefore to use this field,
// but some types of resources, such as jpeg images, are already compressed.
// Sometimes, using additional compression doesn't reduce payload size and
// can even make the payload longer.
func (ctx *Context) Compress(enable bool) error {
func (ctx *Context) CompressWriter(enable bool) error {
cw, ok := ctx.writer.(*CompressResponseWriter)
if enable {
if ok {
@ -2592,7 +2593,7 @@ var (
)
// WriteJSON marshals the given interface object and writes the JSON response to the 'writer'.
// Ignores StatusCode, Compress, StreamingJSON options.
// Ignores StatusCode and StreamingJSON options.
func WriteJSON(writer io.Writer, v interface{}, options JSON, optimize bool) (int, error) {
var (
result []byte
@ -3176,7 +3177,7 @@ func (ctx *Context) Negotiate(v interface{}) (int, error) {
}
if encoding != "" {
ctx.Compress(true)
ctx.CompressWriter(true)
}
ctx.contentTypeOnce(contentType, charset)
@ -3679,7 +3680,8 @@ func (n *NegotiationAcceptBuilder) EncodingGzip() *NegotiationAcceptBuilder {
// ServeContent uses it to handle requests using If-Match, If-None-Match, or If-Range.
//
// Note that *os.File implements the io.ReadSeeker interface.
// Note that compression can be registered through `ctx.Compress(true)` or `app.Use(iris.Compress)`.
// Note that compression can be registered
// through `ctx.CompressWriter(true)` or `app.Use(iris.Compression)`.
func (ctx *Context) ServeContent(content io.ReadSeeker, filename string, modtime time.Time) {
ctx.ServeContentWithRate(content, filename, modtime, 0, 0)
}
@ -3730,7 +3732,8 @@ func (ctx *Context) ServeContentWithRate(content io.ReadSeeker, filename string,
//
// Use it when you want to serve assets like css and javascript files.
// If client should confirm and save the file use the `SendFile` instead.
// Note that compression can be registered through `ctx.Compress(true)` or `app.Use(iris.Compress)`.
// Note that compression can be registered
// through `ctx.CompressWriter(true)` or `app.Use(iris.Compression)`.
func (ctx *Context) ServeFile(filename string) error {
return ctx.ServeFileWithRate(filename, 0, 0)
}
@ -3769,7 +3772,8 @@ func (ctx *Context) ServeFileWithRate(filename string, limit float64, burst int)
}
// SendFile sends a file as an attachment, that is downloaded and saved locally from client.
// Note that compression can be registered through `ctx.Compress(true)` or `app.Use(iris.Compress)`.
// Note that compression can be registered
// through `ctx.CompressWriter(true)` or `app.Use(iris.Compression)`.
// Use `ServeFile` if a file should be served as a page asset instead.
func (ctx *Context) SendFile(src string, destName string) error {
return ctx.SendFileWithRate(src, destName, 0, 0)

View File

@ -170,6 +170,15 @@ func (p Problem) Detail(detail string) Problem {
return p.Key("detail", detail)
}
// DetailErr calls `Detail(err.Error())`.
func (p Problem) DetailErr(err error) Problem {
if err == nil {
return p
}
return p.Key("detail", err.Error())
}
// Instance sets the problem's instance field.
// A URI reference that identifies the specific
// occurrence of the problem. It may or may not yield further

View File

@ -573,7 +573,7 @@ func FileServer(directory string, opts ...DirOptions) context.Handler {
ctx.ResponseWriter().Header().Set(context.ContentDispositionHeaderKey, "attachment;filename="+destName)
}
ctx.Compress(options.Compress)
ctx.CompressWriter(options.Compress)
// If limit is 0 then same as ServeContent.
ctx.ServeContentWithRate(f, info.Name(), info.ModTime(), options.Attachments.Limit, options.Attachments.Burst)

View File

@ -159,11 +159,12 @@ var (
func Do(w http.ResponseWriter, r *http.Request, handler iris.Handler, irisConfigurators ...iris.Configurator) {
app := new(iris.Application)
app.Configure(iris.WithConfiguration(iris.DefaultConfiguration()), iris.WithLogLevel("disable"))
app.Configure(irisConfigurators...)
app.HTTPErrorHandler = router.NewDefaultHandler(app.ConfigurationReadOnly(), app.Logger())
app.ContextPool = context.New(func() interface{} {
return context.NewContext(app)
})
app.Configure(irisConfigurators...)
ctx := app.ContextPool.Acquire(w, r)
handler(ctx)

View File

@ -111,8 +111,7 @@ func Default() *Application {
app := New()
app.Use(recover.New())
app.Use(requestLogger.New())
app.Use(Compress)
app.Use(CompressReader)
app.Use(Compression)
app.defaultMode = true