mirror of
https://github.com/kataras/iris.git
synced 2025-12-17 18:07:01 +00:00
(#1554) Add support for all common compressions (write and read)
- Remove the context.Context interface and export the *context, the iris.Context now points to the pointer\nSupport compression and rate limiting in the FileServer\nBit of code organisation Former-commit-id: ad1c61bf968059510c6be9e7f2cceec7da70ba17
This commit is contained in:
112
_examples/compression/client-using-iris/main.go
Normal file
112
_examples/compression/client-using-iris/main.go
Normal file
@@ -0,0 +1,112 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/kataras/iris/v12/context"
|
||||
)
|
||||
|
||||
const baseURL = "http://localhost:8080"
|
||||
|
||||
// Available options:
|
||||
// - "gzip",
|
||||
// - "deflate",
|
||||
// - "br" (for brotli),
|
||||
// - "snappy" and
|
||||
// - "s2"
|
||||
const encoding = context.BROTLI
|
||||
|
||||
var client = http.DefaultClient
|
||||
|
||||
func main() {
|
||||
fmt.Printf("Running client example on: %s\n", baseURL)
|
||||
|
||||
getExample()
|
||||
postExample()
|
||||
}
|
||||
|
||||
func getExample() {
|
||||
endpoint := baseURL + "/"
|
||||
req, err := http.NewRequest(http.MethodGet, endpoint, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Required to receive server's compressed data.
|
||||
req.Header.Set("Accept-Encoding", encoding)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// decompress server's compressed reply.
|
||||
cr, err := context.NewCompressReader(resp.Body, encoding)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer cr.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(cr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Received from server: %s", string(body))
|
||||
}
|
||||
|
||||
type payload struct {
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
func postExample() {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
// Compress client's data.
|
||||
cw, err := context.NewCompressWriter(buf, encoding, -1)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
json.NewEncoder(cw).Encode(payload{Username: "Edward"})
|
||||
|
||||
// `Close` or `Flush` required before `NewRequest` call.
|
||||
cw.Close()
|
||||
|
||||
endpoint := baseURL + "/"
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, endpoint, buf)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
// Required to send gzip compressed data to the server.
|
||||
req.Header.Set("Content-Encoding", encoding)
|
||||
// Required to receive server's compressed data.
|
||||
req.Header.Set("Accept-Encoding", encoding)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Decompress server's compressed reply.
|
||||
cr, err := context.NewCompressReader(resp.Body, encoding)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer cr.Close() // Closes the request body too.
|
||||
|
||||
body, err := ioutil.ReadAll(cr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Server replied with: %s", string(body))
|
||||
}
|
||||
102
_examples/compression/client/main.go
Normal file
102
_examples/compression/client/main.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var client = http.DefaultClient
|
||||
|
||||
const baseURL = "http://localhost:8080"
|
||||
|
||||
func main() {
|
||||
fmt.Printf("Running client example on: %s\n", baseURL)
|
||||
|
||||
getExample()
|
||||
postExample()
|
||||
}
|
||||
|
||||
func getExample() {
|
||||
endpoint := baseURL + "/"
|
||||
req, err := http.NewRequest(http.MethodGet, endpoint, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Required to receive server's compressed data.
|
||||
req.Header.Set("Accept-Encoding", "gzip")
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// decompress server's compressed reply.
|
||||
r, err := gzip.NewReader(resp.Body)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Received from server: %s", string(body))
|
||||
}
|
||||
|
||||
type payload struct {
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
func postExample() {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
// Compress client's data.
|
||||
w := gzip.NewWriter(buf)
|
||||
|
||||
b, err := json.Marshal(payload{Username: "Edward"})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Write(b)
|
||||
w.Close()
|
||||
|
||||
endpoint := baseURL + "/"
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, endpoint, buf)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
// Required to send gzip compressed data to the server.
|
||||
req.Header.Set("Content-Encoding", "gzip")
|
||||
// Required to receive server's compressed data.
|
||||
req.Header.Set("Accept-Encoding", "gzip")
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Decompress server's compressed reply.
|
||||
r, err := gzip.NewReader(resp.Body)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Server replied with: %s", string(body))
|
||||
}
|
||||
64
_examples/compression/main.go
Normal file
64
_examples/compression/main.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package main
|
||||
|
||||
import "github.com/kataras/iris/v12"
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
app.Logger().SetLevel("debug")
|
||||
app.Listen(":8080")
|
||||
}
|
||||
|
||||
func newApp() *iris.Application {
|
||||
app := iris.New()
|
||||
// HERE and you are ready to GO:
|
||||
app.Use(iris.Compress, iris.CompressReader)
|
||||
|
||||
app.Get("/", send)
|
||||
app.Post("/", receive)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
type payload struct {
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
func send(ctx iris.Context) {
|
||||
ctx.JSON(payload{
|
||||
Username: "Makis",
|
||||
})
|
||||
}
|
||||
|
||||
func receive(ctx iris.Context) {
|
||||
var p payload
|
||||
if err := ctx.ReadJSON(&p); err != nil {
|
||||
ctx.Application().Logger().Debugf("ReadJSON: %v", err)
|
||||
}
|
||||
|
||||
ctx.WriteString(p.Username)
|
||||
}
|
||||
|
||||
/* Manually:
|
||||
func enableCompression(ctx iris.Context) {
|
||||
// Enable writing using compression (deflate, gzip, brotli, snappy, s2):
|
||||
err := ctx.Compress(true)
|
||||
if err != nil {
|
||||
ctx.Application().Logger().Debugf("writer: %v", err)
|
||||
// if you REQUIRE server to SEND compressed data then `return` here.
|
||||
// return
|
||||
}
|
||||
|
||||
// Enable reading and binding request's compressed data:
|
||||
err = ctx.CompressReader(true)
|
||||
if err != nil &&
|
||||
// on GET we don't expect writing with gzip from client
|
||||
ctx.Method() != iris.MethodGet {
|
||||
ctx.Application().Logger().Debugf("reader: %v", err)
|
||||
// if you REQUIRE server to RECEIVE only
|
||||
// compressed data then `return` here.
|
||||
// return
|
||||
}
|
||||
|
||||
ctx.Next()
|
||||
}
|
||||
*/
|
||||
41
_examples/compression/main_test.go
Normal file
41
_examples/compression/main_test.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/kataras/iris/v12/context"
|
||||
"github.com/kataras/iris/v12/httptest"
|
||||
)
|
||||
|
||||
func TestCompression(t *testing.T) {
|
||||
app := newApp()
|
||||
e := httptest.New(t, app)
|
||||
|
||||
var expectedReply = payload{Username: "Makis"}
|
||||
body := e.GET("/").WithHeader(context.AcceptEncodingHeaderKey, context.GZIP).Expect().
|
||||
Status(httptest.StatusOK).
|
||||
ContentEncoding(context.GZIP).
|
||||
ContentType(context.ContentJSONHeaderValue).Body().Raw()
|
||||
|
||||
// Note that .Expect() consumes the response body
|
||||
// and stores it to unexported "contents" field
|
||||
// therefore, we retrieve it as string and put it to a new buffer.
|
||||
r := strings.NewReader(body)
|
||||
cr, err := context.NewCompressReader(r, context.GZIP)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer cr.Close()
|
||||
|
||||
var got payload
|
||||
if err = json.NewDecoder(cr).Decode(&got); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expectedReply, got) {
|
||||
t.Fatalf("expected %#+v but got %#+v", expectedReply, got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user