Skip to content

Commit

Permalink
Merge pull request indigo-web#134 from flrdv/v0.16.0
Browse files Browse the repository at this point in the history
V0.16.0
  • Loading branch information
flrdv authored Apr 21, 2024
2 parents c113b3e + b87e4f0 commit 0b08aa8
Show file tree
Hide file tree
Showing 92 changed files with 2,099 additions and 1,158 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<img src="indigo.svg" alt="This is just a logo" title="What are you looking for?"/>
<p align="center">
<img src="https://gist.githubusercontent.com/flrdv/08395567a602992be0c72f445589cb90/raw/248c01ff18936b36629e520b2164ef6d78f0f57f/indigo-logo.svg" alt="This is just a logo" title="What are you looking for?" width="40%" height="40%"/>
</p>

Indigo is a web-framework, designed to be readable, handy, yet performant (blazingly fast I would even say)

Expand Down
153 changes: 79 additions & 74 deletions settings/settings.go → config/config.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package settings
package config

import (
"github.com/indigo-web/indigo/http"
"math"
"time"

Expand All @@ -12,13 +11,15 @@ var DefaultHeaders = map[string]string{
"Accept-Encodings": "identity",
}

type OnDisconnectCallback func(request *http.Request) *http.Response

type (
HeadersNumber struct {
Default, Maximal int
}

HeadersKeysSpace struct {
Default, Maximal int
}

HeadersValuesSpace struct {
Default, Maximal int
}
Expand All @@ -33,6 +34,13 @@ type (
)

type (
URL struct {
// MaxLength is a size for buffer that'll be allocated once and will be kept
// until client disconnect
BufferSize URLBufferSize
Query Query
}

Headers struct {
// Number is responsible for headers map size.
// Default value is an initial size of allocated headers map.
Expand All @@ -42,6 +50,10 @@ type (
MaxKeyLength int
// MaxValueLength is responsible for maximal header value length restriction.
MaxValueLength int
// KeySpace is responsible for limitation of how much space can headers' keys
// consume. Default value is how many bytes to pre-allocate, and maximal is
// how many bytes can be stored maximally
KeySpace HeadersKeysSpace
// HeadersValuesSpace is responsible for a maximal space in bytes available for
// keeping header values in memory.
// Default value is initial space allocated when client connects.
Expand All @@ -54,21 +66,9 @@ type (
// Default headers are those, which will be rendered on each response unless they were
// not overridden by user
Default map[string]string
}

URL struct {
// MaxLength is a size for buffer that'll be allocated once and will be kept
// until client disconnect
BufferSize URLBufferSize
Query Query
}

TCP struct {
// ReadBufferSize is a size of buffer in bytes which will be used to read from
// socket
ReadBufferSize int
// ReadTimeout is a duration after which client will be automatically disconnected
ReadTimeout time.Duration
// CookiesPreAllocate defines the size of keyvalue.Storage, which is used to store cookies
// once on demand. Therefore, it's going to be allocated only if used
CookiesPreAllocate int
}

Body struct {
Expand All @@ -88,41 +88,29 @@ type (
ResponseBuffSize int
// FileBuffSize defines the size of the read buffer when reading a file
FileBuffSize int
// OnDisconnect is a function, that'll be called on client's disconnection
OnDisconnect OnDisconnectCallback
}

TCP struct {
// ReadBufferSize is a size of buffer in bytes which will be used to read from
// socket
ReadBufferSize int
// ReadTimeout is a duration after which client will be automatically disconnected
ReadTimeout time.Duration
}
)

type Settings struct {
Headers Headers
type Config struct {
URL URL
TCP TCP
Headers Headers
Body Body
HTTP HTTP
TCP TCP
}

// Default returns default settings. Those are initially well-balanced, however maximal defaults
// Default returns default config. Those are initially well-balanced, however maximal defaults
// are pretty permitting
func Default() Settings {
return Settings{
Headers: Headers{
Number: HeadersNumber{
Default: 10,
Maximal: 50,
},
MaxKeyLength: 100, // basically 100 bytes
MaxValueLength: 8 * 1024, // 8 kilobytes (just like nginx)
ValueSpace: HeadersValuesSpace{
// for simple requests without many heavy-weighted headers must be enough
// to avoid a relatively big amount of re-allocations
Default: 1 * 1024, // allocate 1kb buffer by default
Maximal: 8 * 1024, // however allow at most 8kb of headers
},
// this may be an issue, if there are more custom encodings than this. However,
// such cases are considered to be too rare
MaxEncodingTokens: 15,
Default: DefaultHeaders,
},
func Default() Config {
return Config{
URL: URL{
BufferSize: URLBufferSize{
// allocate 2kb buffer by default for storing URI (including query and protocol)
Expand All @@ -136,9 +124,28 @@ func Default() Settings {
PreAlloc: 10,
},
},
TCP: TCP{
ReadBufferSize: 4 * 1024,
ReadTimeout: 90 * time.Second,
Headers: Headers{
Number: HeadersNumber{
Default: 10,
Maximal: 50,
},
MaxKeyLength: 100, // basically 100 bytes
MaxValueLength: 8 * 1024, // 8 kilobytes (just like nginx)
KeySpace: HeadersKeysSpace{
Default: 1 * 1024,
Maximal: 4 * 1024,
},
ValueSpace: HeadersValuesSpace{
// for simple requests without many heavy-weighted headers must be enough
// to avoid a relatively big amount of re-allocations
// this may be an issue, if there are more custom encodings than this. However,
// such cases are considered to be too rare
Default: 1 * 1024, // allocate 1kb buffer by default
Maximal: 8 * 1024, // however allow at most 8kb of headers
},
MaxEncodingTokens: 15,
Default: DefaultHeaders,
CookiesPreAllocate: 5,
},
Body: Body{
MaxSize: 512 * 1024 * 1024, // 512 megabytes
Expand All @@ -150,43 +157,46 @@ func Default() Settings {
HTTP: HTTP{
ResponseBuffSize: 1024,
FileBuffSize: 64 * 1024, // 64kb read buffer for files is pretty much sufficient
OnDisconnect: nil,
},
TCP: TCP{
ReadBufferSize: 4 * 1024,
ReadTimeout: 90 * time.Second,
},
}
}

// Fill fills zero-values from partially-filled Settings instance with default ones
func Fill(src Settings) (new Settings) {
// Fill fills zero-values from partially-filled Config instance with default ones
func Fill(src Config) (new Config) {
defaults := Default()

return Settings{
return Config{
URL: URL{
BufferSize: URLBufferSize{
Default: numOr(src.URL.BufferSize.Default, defaults.URL.BufferSize.Default),
Maximal: numOr(src.URL.BufferSize.Maximal, defaults.URL.BufferSize.Maximal),
},
Query: Query{
PreAlloc: numOr(src.URL.Query.PreAlloc, defaults.URL.Query.PreAlloc),
},
},
Headers: Headers{
Number: HeadersNumber{
Default: numOr(src.Headers.Number.Default, defaults.Headers.Number.Default),
Maximal: numOr(src.Headers.Number.Maximal, defaults.Headers.Number.Maximal),
},
MaxKeyLength: numOr(src.Headers.MaxKeyLength, defaults.Headers.MaxKeyLength),
MaxValueLength: numOr(src.Headers.MaxValueLength, defaults.Headers.MaxValueLength),
KeySpace: HeadersKeysSpace{
Default: numOr(src.Headers.KeySpace.Default, defaults.Headers.KeySpace.Default),
Maximal: numOr(src.Headers.KeySpace.Maximal, defaults.Headers.KeySpace.Maximal),
},
ValueSpace: HeadersValuesSpace{
Default: numOr(src.Headers.ValueSpace.Default, defaults.Headers.ValueSpace.Default),
Maximal: numOr(src.Headers.ValueSpace.Maximal, defaults.Headers.ValueSpace.Maximal),
},
MaxEncodingTokens: numOr(src.Headers.MaxEncodingTokens, defaults.Headers.MaxEncodingTokens),
Default: mapOr(src.Headers.Default, defaults.Headers.Default),
},
URL: URL{
BufferSize: URLBufferSize{
Default: numOr(src.URL.BufferSize.Default, defaults.URL.BufferSize.Default),
Maximal: numOr(src.URL.BufferSize.Maximal, defaults.URL.BufferSize.Maximal),
},
Query: Query{
PreAlloc: numOr(src.URL.Query.PreAlloc, defaults.URL.Query.PreAlloc),
},
},
TCP: TCP{
ReadBufferSize: numOr(src.TCP.ReadBufferSize, defaults.TCP.ReadBufferSize),
ReadTimeout: numOr(src.TCP.ReadTimeout, defaults.TCP.ReadTimeout),
},
Body: Body{
MaxSize: numOr(src.Body.MaxSize, defaults.Body.MaxSize),
MaxChunkSize: numOr(src.Body.MaxChunkSize, defaults.Body.MaxChunkSize),
Expand All @@ -195,7 +205,10 @@ func Fill(src Settings) (new Settings) {
HTTP: HTTP{
ResponseBuffSize: numOr(src.HTTP.ResponseBuffSize, defaults.HTTP.ResponseBuffSize),
FileBuffSize: numOr(src.HTTP.FileBuffSize, defaults.HTTP.FileBuffSize),
OnDisconnect: nilOr[OnDisconnectCallback](src.HTTP.OnDisconnect, defaults.HTTP.OnDisconnect),
},
TCP: TCP{
ReadBufferSize: numOr(src.TCP.ReadBufferSize, defaults.TCP.ReadBufferSize),
ReadTimeout: numOr(src.TCP.ReadTimeout, defaults.TCP.ReadTimeout),
},
}
}
Expand All @@ -215,11 +228,3 @@ func mapOr[K comparable, V any](custom, defaultVal map[K]V) map[K]V {

return custom
}

func nilOr[T any](custom, defaultVal any) T {
if custom == nil {
return defaultVal.(T)
}

return custom.(T)
}
15 changes: 9 additions & 6 deletions examples/combined/combined.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package main

import (
"github.com/indigo-web/indigo/config"
"github.com/indigo-web/indigo/router/inbuilt/middleware"
"github.com/indigo-web/indigo/settings"
"log"
"strconv"
"time"
Expand All @@ -14,7 +14,10 @@ import (
"github.com/indigo-web/indigo/router/inbuilt"
)

const addr = ":8080"
const (
addr = ":8080"
httpsAddr = ":8443"
)

func IndexSay(request *http.Request) *http.Response {
if request.Headers.Value("talking") != "allowed" {
Expand Down Expand Up @@ -59,14 +62,14 @@ func Stressful(request *http.Request) *http.Response {
}

func main() {
s := settings.Default()
s := config.Default()
s.TCP.ReadTimeout = time.Hour

app := indigo.New(addr).
Tune(s).
AutoHTTPS(8443).
NotifyOnStart(func() {
log.Println("initialized")
AutoHTTPS(httpsAddr).
OnBind(func(addr string) {
log.Printf("running on %s\n", addr)
})

r := inbuilt.New().
Expand Down
7 changes: 5 additions & 2 deletions examples/connhijack/connhijack.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ func main() {
r := inbuilt.New()
r.Get("/", MyHandler)

app := indigo.New(addr)
log.Println("Listening on", addr)
app := indigo.New(addr).
OnBind(func(addr string) {
log.Printf("running on %s\n", addr)
})

log.Fatal(app.Serve(r))
}
7 changes: 5 additions & 2 deletions examples/dynroute/dynroute.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ func main() {

r.Get("/hello/{world-name}", MyDynamicHandler)

app := indigo.New(addr)
log.Println("Listening on", addr)
app := indigo.New(addr).
OnBind(func(addr string) {
log.Printf("running on %s\n", addr)
})

log.Fatal(app.Serve(r))
}
10 changes: 7 additions & 3 deletions examples/helloworld/helloworld.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,18 @@ func MyHandler(request *http.Request) *http.Response {
return request.Respond().
Code(status.OK).
Header("Hello", "world").
String("<h1>How are you doing?</h1>")
String("<h1>Hello, world!</h1>")
}

func main() {
myRouter := inbuilt.New()
myRouter.Get("/", MyHandler)

app := indigo.New(addr)
log.Println("Listening on", addr)
app := indigo.New(addr).
AutoHTTPS(":8443").
OnBind(func(addr string) {
log.Printf("running on %s\n", addr)
})

log.Fatal(app.Serve(myRouter))
}
7 changes: 5 additions & 2 deletions examples/helloworld_norouter/helloworld.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ func main() {
r := simple.New(MyHandler, func(request *http.Request) *http.Response {
return http.Error(request, request.Env.Error)
})
app := indigo.New(addr)
log.Println("Listening on", addr)
app := indigo.New(addr).
OnBind(func(addr string) {
log.Printf("running on %s\n", addr)
})

log.Fatal(app.Serve(r))
}
7 changes: 5 additions & 2 deletions examples/middlewares/middlewares.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ func main() {
v1.Use(SecondMiddleware)
v1.Get("/hello", MyBeautifulHandler)

app := indigo.New(addr)
log.Println("listening on", addr)
app := indigo.New(addr).
OnBind(func(addr string) {
log.Printf("running on %s\n", addr)
})

log.Fatal(app.Serve(r))
}
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ require (
github.com/indigo-web/iter v0.1.0
github.com/indigo-web/utils v0.6.2
github.com/json-iterator/go v1.1.12
github.com/stretchr/testify v1.8.4
golang.org/x/crypto v0.19.0
github.com/stretchr/testify v1.9.0
golang.org/x/crypto v0.21.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/net v0.21.0 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit 0b08aa8

Please sign in to comment.