Skip to content

Commit 2469413

Browse files
authored
Merge pull request #144 from flrdv/master
v0.17.3-rc1
2 parents 804e0f3 + a458752 commit 2469413

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+1909
-1348
lines changed

config/config.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ type (
7272
// any request with body (each call to request's body will result in status.ErrBodyTooLarge).
7373
// In order to disable the setting, use the math.MaxUInt64 value.
7474
MaxSize uint64
75-
//// DecodingBufferSize is a size of a buffer, used to store decoded request's body
76-
//DecodingBufferSize int
75+
// Form is either application/x-www-form-urlencoded or multipart/form-data. Due to their common
76+
// nature, they are easy to be generalized.
7777
Form BodyForm
7878
}
7979

@@ -96,6 +96,10 @@ type (
9696
// 2) If a stream is unsized (1) and the previous write used more than ~98.44% of its
9797
// capacity (2), the capacity doubles.
9898
WriteBufferSize NETWriteBufferSize
99+
// SmallBody limits how big must a response body be in order to be compressed, if the
100+
// auto compression option is enabled. This setting doesn't affect enforced compression
101+
// options and unsized streams.
102+
SmallBody int64
99103
}
100104
)
101105

@@ -158,6 +162,7 @@ func Default() *Config {
158162
Default: 2 * 1024,
159163
Maximal: 64 * 1024,
160164
},
165+
SmallBody: 4 * 1024,
161166
},
162167
}
163168
}

examples/compression/compression.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func Shout(r *http.Request) *http.Response {
2323

2424
func main() {
2525
app := indigo.New(":8080").
26-
Codec(codec.NewGZIP()).
26+
Codec(codec.Suit()...).
2727
OnBind(func(addr string) {
2828
fmt.Println("Listening on", addr)
2929
})

examples/demo/demo.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func main() {
6262
app := indigo.New(":8080").
6363
TLS(":8443", indigo.LocalCert()).
6464
Tune(s).
65-
Codec(codec.NewGZIP()).
65+
Codec(codec.Suit()...).
6666
OnBind(func(addr string) {
6767
log.Printf("running on %s\n", addr)
6868
})
@@ -71,10 +71,14 @@ func main() {
7171
Use(middleware.LogRequests()).
7272
Alias("/", "/static/index.html", method.GET).
7373
Alias("/favicon.ico", "/static/favicon.ico", method.GET).
74-
Static("/static", "examples/demo/static")
74+
Static("/static", "examples/demo/static", middleware.Autocompress)
7575

7676
r.Get("/stress", Stressful, middleware.Recover)
7777

78+
r.Post("/echo", func(request *http.Request) *http.Response {
79+
return http.Stream(request, request.Body)
80+
})
81+
7882
r.Resource("/").
7983
Post(IndexSay)
8084

http/body.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ type Body struct {
3232
form form.Form
3333
}
3434

35-
// TODO: body entity can be passed by value (?)
36-
3735
func NewBody(src Fetcher) *Body {
3836
return &Body{
3937
Fetcher: src,
@@ -79,7 +77,7 @@ func (b *Body) Bytes() ([]byte, error) {
7977
}
8078

8179
newSize := int(b.request.cfg.Body.Form.BufferPrealloc)
82-
if !b.request.Encoding.Chunked {
80+
if !b.request.Chunked {
8381
newSize = min(b.request.ContentLength, int(b.request.cfg.Body.MaxSize))
8482
}
8583

@@ -178,6 +176,14 @@ func (b *Body) Form() (f form.Form, err error) {
178176
}
179177
}
180178

179+
func (b *Body) Len() int {
180+
if b.request.Chunked {
181+
return -1
182+
}
183+
184+
return b.request.ContentLength
185+
}
186+
181187
// Discard sinkholes the rest of the body. Should not be used unless you know what you're doing.
182188
func (b *Body) Discard() error {
183189
for b.error == nil {

http/codec/adapter.go

Lines changed: 0 additions & 37 deletions
This file was deleted.

http/codec/base.go

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package codec
2+
3+
import (
4+
"io"
5+
6+
"github.com/indigo-web/indigo/http"
7+
)
8+
9+
var _ Codec = baseCodec{}
10+
11+
type instantiator = func() Instance
12+
13+
type baseCodec struct {
14+
token string
15+
newInst instantiator
16+
}
17+
18+
func newBaseCodec(token string, newInst instantiator) baseCodec {
19+
return baseCodec{
20+
token: token,
21+
newInst: newInst,
22+
}
23+
}
24+
25+
func (b baseCodec) Token() string {
26+
return b.token
27+
}
28+
29+
func (b baseCodec) New() Instance {
30+
return b.newInst()
31+
}
32+
33+
var _ Instance = new(baseInstance)
34+
35+
type (
36+
decoderResetter = func(io.Reader, *readerAdapter) error
37+
38+
writeResetter interface {
39+
io.WriteCloser
40+
Reset(dst io.Writer)
41+
}
42+
)
43+
44+
type baseInstance struct {
45+
reset decoderResetter
46+
adapter *readerAdapter
47+
w writeResetter // compressor
48+
r io.Reader // decompressor
49+
dst io.Closer
50+
buff []byte
51+
}
52+
53+
func newBaseInstance(encoder writeResetter, decoder io.Reader, reset decoderResetter) instantiator {
54+
return func() Instance {
55+
return &baseInstance{
56+
reset: reset,
57+
adapter: newAdapter(),
58+
w: encoder,
59+
r: decoder,
60+
}
61+
}
62+
}
63+
64+
func (b *baseInstance) ResetCompressor(w io.Writer) {
65+
b.w.Reset(w)
66+
b.dst = nil
67+
68+
if c, ok := w.(io.Closer); ok {
69+
b.dst = c
70+
}
71+
}
72+
73+
func (b *baseInstance) Write(p []byte) (n int, err error) {
74+
return b.w.Write(p)
75+
}
76+
77+
func (b *baseInstance) Close() error {
78+
if err := b.w.Close(); err != nil {
79+
return err
80+
}
81+
82+
if b.dst != nil {
83+
return b.dst.Close()
84+
}
85+
86+
return nil
87+
}
88+
89+
func (b *baseInstance) ResetDecompressor(source http.Fetcher, bufferSize int) error {
90+
if cap(b.buff) < bufferSize {
91+
b.buff = make([]byte, bufferSize)
92+
}
93+
94+
b.adapter.Reset(source)
95+
96+
return b.reset(b.r, b.adapter)
97+
}
98+
99+
func (b *baseInstance) Fetch() ([]byte, error) {
100+
n, err := b.r.Read(b.buff)
101+
return b.buff[:n], err
102+
}
103+
104+
func genericResetter(r io.Reader, adapter *readerAdapter) error {
105+
type resetter interface {
106+
Reset(r io.Reader) error
107+
}
108+
109+
if reset, ok := r.(resetter); ok {
110+
return reset.Reset(adapter)
111+
}
112+
113+
return nil
114+
}
115+
116+
type readerAdapter struct {
117+
fetcher http.Fetcher
118+
err error
119+
data []byte
120+
}
121+
122+
func newAdapter() *readerAdapter {
123+
return new(readerAdapter)
124+
}
125+
126+
func (r *readerAdapter) Read(b []byte) (n int, err error) {
127+
if len(r.data) == 0 {
128+
if r.err != nil {
129+
return 0, r.err
130+
}
131+
132+
r.data, r.err = r.fetcher.Fetch()
133+
}
134+
135+
n = copy(b, r.data)
136+
r.data = r.data[n:]
137+
if len(r.data) == 0 {
138+
err = r.err
139+
}
140+
141+
return n, err
142+
}
143+
144+
func (r *readerAdapter) Reset(fetcher http.Fetcher) {
145+
*r = readerAdapter{fetcher: fetcher}
146+
}

http/codec/codec.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ type Compressor interface {
2323
}
2424

2525
type Decompressor interface {
26-
ResetDecompressor(source http.Fetcher) error
2726
http.Fetcher
27+
ResetDecompressor(source http.Fetcher, bufferSize int) error
28+
}
29+
30+
// Suit is a collection of out-of-the-box supported codecs. It contains:
31+
// - gzip
32+
// - deflate
33+
// - zstd
34+
func Suit() []Codec {
35+
return []Codec{NewGZIP(), NewDeflate(), NewZSTD()}
2836
}

http/codec/deflate.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,21 @@
11
package codec
2+
3+
import (
4+
"io"
5+
6+
"github.com/klauspost/compress/flate"
7+
)
8+
9+
func NewDeflate() Codec {
10+
writer, err := flate.NewWriter(nil, 5)
11+
if err != nil {
12+
panic(err)
13+
}
14+
15+
reader := flate.NewReader(nil)
16+
instantiator := newBaseInstance(writer, reader, func(r io.Reader, a *readerAdapter) error {
17+
return r.(flate.Resetter).Reset(a, nil)
18+
})
19+
20+
return newBaseCodec("deflate", instantiator)
21+
}

http/codec/deflate_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package codec
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestFlate(t *testing.T) {
8+
testCodec(t, NewDeflate().New())
9+
}

0 commit comments

Comments
 (0)