mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 10:41:03 +01:00
Option for Socket Sharding as requested at #1544
Former-commit-id: 0384baf593012377a94344d647ca41121294285a
This commit is contained in:
parent
836e641229
commit
7f9e664b90
|
@ -371,6 +371,8 @@ Other Improvements:
|
||||||
|
|
||||||
![DBUG routes](https://iris-go.com/images/v12.2.0-dbug2.png?v=0)
|
![DBUG routes](https://iris-go.com/images/v12.2.0-dbug2.png?v=0)
|
||||||
|
|
||||||
|
- Socket Sharding as requested at [#1544](https://github.com/kataras/iris/issues/1544). New `iris.WithSocketSharding` Configurator and `SocketSharding bool` setting.
|
||||||
|
|
||||||
- Versioned Controllers feature through the new `mvc.Version` option. See [_examples/mvc/versioned-controller](https://github.com/kataras/iris/blob/master/_examples/mvc/versioned-controller/main.go).
|
- Versioned Controllers feature through the new `mvc.Version` option. See [_examples/mvc/versioned-controller](https://github.com/kataras/iris/blob/master/_examples/mvc/versioned-controller/main.go).
|
||||||
|
|
||||||
- Fix [#1539](https://github.com/kataras/iris/issues/1539).
|
- Fix [#1539](https://github.com/kataras/iris/issues/1539).
|
||||||
|
|
|
@ -15,11 +15,11 @@
|
||||||
* [UNIX socket file](http-server/listen-unix/main.go)
|
* [UNIX socket file](http-server/listen-unix/main.go)
|
||||||
* [TLS](http-server/listen-tls/main.go)
|
* [TLS](http-server/listen-tls/main.go)
|
||||||
* [Letsencrypt (Automatic Certifications)](http-server/listen-letsencrypt/main.go)
|
* [Letsencrypt (Automatic Certifications)](http-server/listen-letsencrypt/main.go)
|
||||||
|
* [Socket Sharding (SO_REUSEPORT)](http-server/socket-sharding/main.go)
|
||||||
* [Graceful Shutdown](http-server/graceful-shutdown/default-notifier/main.go)
|
* [Graceful Shutdown](http-server/graceful-shutdown/default-notifier/main.go)
|
||||||
* [Notify on shutdown](http-server/notify-on-shutdown/main.go)
|
* [Notify on shutdown](http-server/notify-on-shutdown/main.go)
|
||||||
* Custom TCP Listener
|
* Custom TCP Listener
|
||||||
* [Common net.Listener](http-server/custom-listener/main.go)
|
* [Common net.Listener](http-server/custom-listener/main.go)
|
||||||
* [SO_REUSEPORT for unix systems](http-server/custom-listener/unix-reuseport/main.go)
|
|
||||||
* Custom HTTP Server
|
* Custom HTTP Server
|
||||||
* [Pass a custom Server](http-server/custom-httpserver/easy-way/main.go)
|
* [Pass a custom Server](http-server/custom-httpserver/easy-way/main.go)
|
||||||
* [Use Iris as a single http.Handler](http-server/custom-httpserver/std-way/main.go)
|
* [Use Iris as a single http.Handler](http-server/custom-httpserver/std-way/main.go)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/kataras/iris/v12/_examples/bootstrap/bootstrap"
|
"github.com/kataras/iris/v12/_examples/bootstrapper/bootstrap"
|
||||||
"github.com/kataras/iris/v12/_examples/bootstrap/middleware/identity"
|
"github.com/kataras/iris/v12/_examples/bootstrapper/middleware/identity"
|
||||||
"github.com/kataras/iris/v12/_examples/bootstrap/routes"
|
"github.com/kataras/iris/v12/_examples/bootstrapper/routes"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newApp() *bootstrap.Bootstrapper {
|
func newApp() *bootstrap.Bootstrapper {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/kataras/iris/v12"
|
"github.com/kataras/iris/v12"
|
||||||
|
|
||||||
"github.com/kataras/iris/v12/_examples/bootstrap/bootstrap"
|
"github.com/kataras/iris/v12/_examples/bootstrapper/bootstrap"
|
||||||
)
|
)
|
||||||
|
|
||||||
// New returns a new handler which adds some headers and view data
|
// New returns a new handler which adds some headers and view data
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package routes
|
package routes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/kataras/iris/v12/_examples/bootstrap/bootstrap"
|
"github.com/kataras/iris/v12/_examples/bootstrapper/bootstrap"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Configure registers the necessary routes to the app.
|
// Configure registers the necessary routes to the app.
|
||||||
|
|
|
@ -11,7 +11,8 @@ we use the `iris.Addr` which is an `iris.Runner` type
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Listening on tcp with network address 0.0.0.0:8080
|
// Listening on tcp with network address 0.0.0.0:8080
|
||||||
app.Listen(":8080")
|
// app.Listen(":8080") it's a shortcut of:
|
||||||
|
app.Run(iris.Addr(":8080"))
|
||||||
```
|
```
|
||||||
|
|
||||||
Sometimes you have created a standard net/http server somewhere else in your app and want to use that to serve the Iris web app
|
Sometimes you have created a standard net/http server somewhere else in your app and want to use that to serve the Iris web app
|
||||||
|
@ -66,53 +67,6 @@ func main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
UNIX and BSD hosts can take advantage of the reuse port feature
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
// Package tcplisten provides customizable TCP net.Listener with various
|
|
||||||
// performance-related options:
|
|
||||||
//
|
|
||||||
// - SO_REUSEPORT. This option allows linear scaling server performance
|
|
||||||
// on multi-CPU servers.
|
|
||||||
// See https://www.nginx.com/blog/socket-sharding-nginx-release-1-9-1/ for details.
|
|
||||||
//
|
|
||||||
// - TCP_DEFER_ACCEPT. This option expects the server reads from the accepted
|
|
||||||
// connection before writing to them.
|
|
||||||
//
|
|
||||||
// - TCP_FASTOPEN. See https://lwn.net/Articles/508865/ for details.
|
|
||||||
"github.com/valyala/tcplisten"
|
|
||||||
|
|
||||||
"github.com/kataras/iris/v12"
|
|
||||||
)
|
|
||||||
|
|
||||||
// go get github.com/valyala/tcplisten
|
|
||||||
// go run main.go
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
app := iris.New()
|
|
||||||
|
|
||||||
app.Get("/", func(ctx iris.Context) {
|
|
||||||
ctx.HTML("<h1>Hello World!</h1>")
|
|
||||||
})
|
|
||||||
|
|
||||||
listenerCfg := tcplisten.Config{
|
|
||||||
ReusePort: true,
|
|
||||||
DeferAccept: true,
|
|
||||||
FastOpen: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
l, err := listenerCfg.NewListener("tcp", ":8080")
|
|
||||||
if err != nil {
|
|
||||||
app.Logger().Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Run(iris.Listener(l))
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### HTTP/2 and Secure
|
### HTTP/2 and Secure
|
||||||
|
|
||||||
If you have signed file keys you can use the `iris.TLS` to serve `https` based on those certification keys
|
If you have signed file keys you can use the `iris.TLS` to serve `https` based on those certification keys
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
// +build linux darwin dragonfly freebsd netbsd openbsd rumprun
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
// Package tcplisten provides customizable TCP net.Listener with various
|
|
||||||
// performance-related options:
|
|
||||||
//
|
|
||||||
// - SO_REUSEPORT. This option allows linear scaling server performance
|
|
||||||
// on multi-CPU servers.
|
|
||||||
// See https://www.nginx.com/blog/socket-sharding-nginx-release-1-9-1/ for details.
|
|
||||||
//
|
|
||||||
// - TCP_DEFER_ACCEPT. This option expects the server reads from the accepted
|
|
||||||
// connection before writing to them.
|
|
||||||
//
|
|
||||||
// - TCP_FASTOPEN. See https://lwn.net/Articles/508865/ for details.
|
|
||||||
"github.com/valyala/tcplisten"
|
|
||||||
|
|
||||||
"github.com/kataras/iris/v12"
|
|
||||||
)
|
|
||||||
|
|
||||||
// You can run the same app as many times as you want.
|
|
||||||
func main() {
|
|
||||||
app := iris.New()
|
|
||||||
|
|
||||||
app.Get("/", func(ctx iris.Context) {
|
|
||||||
ctx.HTML("<b>Hello World!</b>")
|
|
||||||
})
|
|
||||||
|
|
||||||
listenerCfg := tcplisten.Config{
|
|
||||||
ReusePort: true,
|
|
||||||
DeferAccept: true,
|
|
||||||
FastOpen: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
l, err := listenerCfg.NewListener("tcp4", ":8080")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Run(iris.Listener(l))
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
// +build windows
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
panic("windows operating system does not support this feature")
|
|
||||||
}
|
|
|
@ -18,10 +18,10 @@ func main() {
|
||||||
// Start the server (HTTPS) on port 443,
|
// Start the server (HTTPS) on port 443,
|
||||||
// and a secondary of (HTTP) on port :80 which redirects requests to their HTTPS version.
|
// and a secondary of (HTTP) on port :80 which redirects requests to their HTTPS version.
|
||||||
// This is a blocking func.
|
// This is a blocking func.
|
||||||
app.Run(iris.TLS("127.0.0.1:443", "mycert.cert", "mykey.key"))
|
app.Run(iris.TLS("127.0.0.1:443", "mycert.crt", "mykey.key"))
|
||||||
|
|
||||||
// Note: to disable automatic "http://" to "https://" redirections pass the `iris.TLSNoRedirect`
|
// Note: to disable automatic "http://" to "https://" redirections pass the `iris.TLSNoRedirect`
|
||||||
// host configurator to TLS or AutoTLS functions, e.g:
|
// host configurator to TLS or AutoTLS functions, e.g:
|
||||||
//
|
//
|
||||||
// app.Run(iris.TLS("127.0.0.1:443", "mycert.cert", "mykey.key", iris.TLSNoRedirect))
|
// app.Run(iris.TLS("127.0.0.1:443", "mycert.crt", "mykey.key", iris.TLSNoRedirect))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDAzCCAeugAwIBAgIJAPDsxtKV4v3uMA0GCSqGSIb3DQEBBQUAMBgxFjAUBgNV
|
|
||||||
BAMMDTEyNy4wLjAuMTo0NDMwHhcNMTYwNjI5MTMxMjU4WhcNMjYwNjI3MTMxMjU4
|
|
||||||
WjAYMRYwFAYDVQQDDA0xMjcuMC4wLjE6NDQzMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
|
||||||
AQ8AMIIBCgKCAQEA0KtAOHKrcbLwWJXgRX7XSFyu4HHHpSty4bliv8ET4sLJpbZH
|
|
||||||
XeVX05Foex7PnrurDP6e+0H5TgqqcpQM17/ZlFcyKrJcHSCgV0ZDB3Sb8RLQSLns
|
|
||||||
8a+MOSbn1WZ7TkC7d/cWlKmasQRHQ2V/cWlGooyKNEPoGaEz8MbY0wn2spyIJwsB
|
|
||||||
dciERC6317VTXbiZdoD8QbAsT+tBvEHM2m2A7B7PQmHNehtyFNbSV5uZNodvv1uv
|
|
||||||
ZTnDa6IqpjFLb1b2HNFgwmaVPmmkLuy1l9PN+o6/DUnXKKBrfPAx4JOlqTKEQpWs
|
|
||||||
pnfacTE3sWkkmOSSFltAXfkXIJFKdS/hy5J/KQIDAQABo1AwTjAdBgNVHQ4EFgQU
|
|
||||||
zr1df/c9+NyTpmyiQO8g3a8NswYwHwYDVR0jBBgwFoAUzr1df/c9+NyTpmyiQO8g
|
|
||||||
3a8NswYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEACG5shtMSDgCd
|
|
||||||
MNjOF+YmD+PX3Wy9J9zehgaDJ1K1oDvBbQFl7EOJl8lRMWITSws22Wxwh8UXVibL
|
|
||||||
sscKBp14dR3e7DdbwCVIX/JyrJyOaCfy2nNBdf1B06jYFsIHvP3vtBAb9bPNOTBQ
|
|
||||||
QE0Ztu9kCqgsmu0//sHuBEeA3d3E7wvDhlqRSxTLcLtgC1NSgkFvBw0JvwgpkX6s
|
|
||||||
M5WpSBZwZv8qpplxhFfqNy8Uf+xrpSW0pGfkHumehkQGC6/Ry7raganS0aHhDPK9
|
|
||||||
Z1bEJ2com1bFFAQsm9yIXrRVMGGCtihB2Au0Q4jpEjUbzWYM+ItZyvRAGRM6Qex6
|
|
||||||
s/jogMeRsw==
|
|
||||||
-----END CERTIFICATE-----
|
|
31
_examples/http-server/listen-tls/mycert.crt
Normal file
31
_examples/http-server/listen-tls/mycert.crt
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
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
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -1,27 +1,52 @@
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
-----BEGIN PRIVATE KEY-----
|
||||||
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
|
||||||
-----END RSA PRIVATE KEY-----
|
L5xsBUsxDDY13cD1bLKRmFcyMFM8y7wMZmo7H/WfVmyoPKQaC43pTcmIXH0Jr2Ws
|
||||||
|
Wsfh18mhjtamaOPEFx5K0x4d0PI8tW5ouiUUkVIDaue27XfS969qEChv768/44eX
|
||||||
|
WeqcekaG9jv2noMClt79rYd3Lne9HkgY6IT9FT+JqXfu+KYwuQKCAQEA6gYzUsGB
|
||||||
|
9GQO8DE8AYn7JwNOtg1X4zKakXiGxH+nuZb7wJjAeGdYqTHySxPBXg0A2nDwoyz5
|
||||||
|
4sAdLAr3FZoIvTzo7M5KIKFDzfyDmQDavhroH1mBAEiqKGNniP+RND3nWBBqDK1R
|
||||||
|
qcqbhI3Kj5Ycany6a4nP+hZRBIyT9sfJ0S0YruSY8IGXgDwhlJrZ7bsWMZylrgD/
|
||||||
|
1qnPL0KqVBY8YR8msRj88h72IlD5o0kwvisOIvyhA0YgwGBb6lg7A+DifiF03ZlS
|
||||||
|
2yELbIkKDVr+p3jC7MBh4B+OJY68AMl6wVjAaDM1AZnpjKE5YmZg5+Ks5823zILo
|
||||||
|
PrSB9hn0+DIPYQKCAQEAh9x+JuNmzhHa/dkiHNl8hpadHYQD7gUWwZ4P1/bQAv0a
|
||||||
|
xU2MvmDPRXxFYDv/SqlnI1NRmhq3YiDM5SLv7SyQJt4al4IAcsaHvTFgqaSuw3hU
|
||||||
|
YVR9uAYqwE7w6OPn3r4o3Xfoz05Ru4FP//1nfucZ9vVv4rC/4nGWuJcHRM+9PLy1
|
||||||
|
KnztfVR0VlL7QPrwRnW99kS4nnqn3K4khiTAlF73cAyCLsuXmydoqGIzDtMzv68G
|
||||||
|
XRpo82NvHmoccevcj/2w3T2XYECWvAEjsrEdQ8xiKBwLIAcWYEOUIUCcumiyKBKs
|
||||||
|
IwzkioI/U8AeuO0lobfdZ1n6i2sCuZA4mNxIQseWmQKCAQEA5YkfXdQeuq5JWJ1x
|
||||||
|
1bCYfjNoSHfd9CH2KSimRqVOxWGpm8Y3QeFbvNgYZjsCNlVauOZ9oA7FKfp0onY+
|
||||||
|
0xk56SKM83eCjW6fKrK6AKAt7LhHZDhNpxGek+6r5luE+FCfUGkJG1YD+x2WW/UW
|
||||||
|
8K6zQF8GGeQZ8Zlh7axUlIBxGpG43BGrUHpLNqPD7BXWGq6dnhufBYRFay8y34/r
|
||||||
|
sH3+yuPa92ki7/geQppZwCZRgLSKMRbIdoWaKhZZEQlpGOzCOiRmk9OGyRcoNVRU
|
||||||
|
X7UYgPqZdc1cMo/AxGWzULJNjMaYMZvIKcHkqOKZfkIcWlSictn7pMPhN1+k+NWM
|
||||||
|
yMORAQKCAQAyXl02h/c2ihx6cjKlnNeDr2ZfzkoiAvFuKaoAR+KVvb9F9X7ZgKSi
|
||||||
|
wudZyelTglIVCYXeRmG09uX3rNGCzFrweRwgn6x/8DnN5pMRJVZOXFdgR+V9uKep
|
||||||
|
K6F7DYbPyggvLOAsezB+09i9lwxM+XdA2whVpL5NFR1rGfFglnE1EQHcEvNONkcv
|
||||||
|
0h8x9cNSptJyRDLiTIKI9EhonuzwzkGpvjULQE8MLbT8PbjoLFINcE9ZWhwtyw0V
|
||||||
|
XO32KE8iLKt3KzHz9CfTRCI3M7DwD752AC6zRr8ZS/HXzs+5WTkdVVEtRC7Abd3y
|
||||||
|
W2TzuSMYNDu876twbTVQJED3mwOAQ3J7
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
|
|
|
@ -15,5 +15,3 @@ func main() {
|
||||||
|
|
||||||
app.Run(iris.Listener(l))
|
app.Run(iris.Listener(l))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look "custom-listener/unix-reuseport" too.
|
|
||||||
|
|
21
_examples/http-server/socket-sharding/main.go
Normal file
21
_examples/http-server/socket-sharding/main.go
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/kataras/iris/v12"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
startup := time.Now()
|
||||||
|
|
||||||
|
app := iris.New()
|
||||||
|
app.Get("/", func(ctx iris.Context) {
|
||||||
|
s := startup.Format(ctx.Application().ConfigurationReadOnly().GetTimeFormat())
|
||||||
|
ctx.Writef("This server started at: %s\n", s)
|
||||||
|
})
|
||||||
|
|
||||||
|
// This option allows linear scaling server performance on multi-CPU servers.
|
||||||
|
// See https://www.nginx.com/blog/socket-sharding-nginx-release-1-9-1/ for details.
|
||||||
|
app.Listen(":8080", iris.WithSocketSharding)
|
||||||
|
}
|
|
@ -192,6 +192,13 @@ func WithLogLevel(level string) Configurator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithSocketSharding sets the `Configuration.SocketSharding` field to true.
|
||||||
|
func WithSocketSharding(app *Application) {
|
||||||
|
// Note(@kataras): It could be a host Configurator but it's an application setting in order
|
||||||
|
// to configure it through yaml/toml files as well.
|
||||||
|
app.config.SocketSharding = true
|
||||||
|
}
|
||||||
|
|
||||||
// WithoutServerError will cause to ignore the matched "errors"
|
// WithoutServerError will cause to ignore the matched "errors"
|
||||||
// from the main application's `Run/Listen` function.
|
// from the main application's `Run/Listen` function.
|
||||||
//
|
//
|
||||||
|
@ -805,10 +812,22 @@ type Configuration struct {
|
||||||
// * "debug"
|
// * "debug"
|
||||||
LogLevel string `json:"logLevel" yaml:"LogLevel" toml:"LogLevel" env:"LOG_LEVEL"`
|
LogLevel string `json:"logLevel" yaml:"LogLevel" toml:"LogLevel" env:"LOG_LEVEL"`
|
||||||
|
|
||||||
|
// SocketSharding enables SO_REUSEPORT (or SO_REUSEADDR for windows)
|
||||||
|
// on all registered Hosts.
|
||||||
|
// This option allows linear scaling server performance on multi-CPU servers.
|
||||||
|
//
|
||||||
|
// Please read the following:
|
||||||
|
// 1. https://stackoverflow.com/a/14388707
|
||||||
|
// 2. https://stackoverflow.com/a/59692868
|
||||||
|
// 3. https://www.nginx.com/blog/socket-sharding-nginx-release-1-9-1/
|
||||||
|
// 4. (BOOK) Learning HTTP/2: A Practical Guide for Beginners:
|
||||||
|
// Page 37, To Shard or Not to Shard?
|
||||||
|
//
|
||||||
|
// Defaults to false.
|
||||||
|
SocketSharding bool `json:"socketSharding" yaml:"SocketSharding" toml:"SocketSharding" env:"SOCKET_SHARDING"`
|
||||||
// Tunneling can be optionally set to enable ngrok http(s) tunneling for this Iris app instance.
|
// Tunneling can be optionally set to enable ngrok http(s) tunneling for this Iris app instance.
|
||||||
// See the `WithTunneling` Configurator too.
|
// See the `WithTunneling` Configurator too.
|
||||||
Tunneling TunnelingConfiguration `json:"tunneling,omitempty" yaml:"Tunneling" toml:"Tunneling"`
|
Tunneling TunnelingConfiguration `json:"tunneling,omitempty" yaml:"Tunneling" toml:"Tunneling"`
|
||||||
|
|
||||||
// IgnoreServerErrors will cause to ignore the matched "errors"
|
// IgnoreServerErrors will cause to ignore the matched "errors"
|
||||||
// from the main application's `Run` function.
|
// from the main application's `Run` function.
|
||||||
// This is a slice of string, not a slice of error
|
// This is a slice of string, not a slice of error
|
||||||
|
@ -1046,6 +1065,11 @@ func (c Configuration) GetLogLevel() string {
|
||||||
return c.vhost
|
return c.vhost
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSocketSharding returns the SocketSharding field.
|
||||||
|
func (c Configuration) GetSocketSharding() bool {
|
||||||
|
return c.SocketSharding
|
||||||
|
}
|
||||||
|
|
||||||
// GetDisablePathCorrection returns the DisablePathCorrection field.
|
// GetDisablePathCorrection returns the DisablePathCorrection field.
|
||||||
func (c Configuration) GetDisablePathCorrection() bool {
|
func (c Configuration) GetDisablePathCorrection() bool {
|
||||||
return c.DisablePathCorrection
|
return c.DisablePathCorrection
|
||||||
|
@ -1182,6 +1206,10 @@ func WithConfiguration(c Configuration) Configurator {
|
||||||
main.LogLevel = v
|
main.LogLevel = v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v := c.SocketSharding; v {
|
||||||
|
main.SocketSharding = v
|
||||||
|
}
|
||||||
|
|
||||||
if c.Tunneling.isEnabled() {
|
if c.Tunneling.isEnabled() {
|
||||||
main.Tunneling = c.Tunneling
|
main.Tunneling = c.Tunneling
|
||||||
}
|
}
|
||||||
|
@ -1320,6 +1348,7 @@ func WithConfiguration(c Configuration) Configurator {
|
||||||
func DefaultConfiguration() Configuration {
|
func DefaultConfiguration() Configuration {
|
||||||
return Configuration{
|
return Configuration{
|
||||||
LogLevel: "info",
|
LogLevel: "info",
|
||||||
|
SocketSharding: false,
|
||||||
DisableStartupLog: false,
|
DisableStartupLog: false,
|
||||||
DisableInterruptHandler: false,
|
DisableInterruptHandler: false,
|
||||||
DisablePathCorrection: false,
|
DisablePathCorrection: false,
|
||||||
|
|
|
@ -12,6 +12,8 @@ type ConfigurationReadOnly interface {
|
||||||
GetVHost() string
|
GetVHost() string
|
||||||
// GetLogLevel returns the LogLevel field.
|
// GetLogLevel returns the LogLevel field.
|
||||||
GetLogLevel() string
|
GetLogLevel() string
|
||||||
|
// GetSocketSharding returns the SocketSharding field.
|
||||||
|
GetSocketSharding() bool
|
||||||
// GetDisablePathCorrection returns the DisablePathCorrection field
|
// GetDisablePathCorrection returns the DisablePathCorrection field
|
||||||
GetDisablePathCorrection() bool
|
GetDisablePathCorrection() bool
|
||||||
// GetDisablePathCorrectionRedirection returns the DisablePathCorrectionRedirection field.
|
// GetDisablePathCorrectionRedirection returns the DisablePathCorrectionRedirection field.
|
||||||
|
|
|
@ -13,9 +13,9 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/crypto/acme/autocert"
|
|
||||||
|
|
||||||
"github.com/kataras/iris/v12/core/netutil"
|
"github.com/kataras/iris/v12/core/netutil"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/acme/autocert"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Configurator provides an easy way to modify
|
// Configurator provides an easy way to modify
|
||||||
|
@ -48,6 +48,9 @@ type Supervisor struct {
|
||||||
// Defaults to empty.
|
// Defaults to empty.
|
||||||
IgnoredErrors []string
|
IgnoredErrors []string
|
||||||
onErr []func(error)
|
onErr []func(error)
|
||||||
|
|
||||||
|
// See `iris.Configuration.SocketSharding`.
|
||||||
|
SocketSharding bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new host supervisor
|
// New returns a new host supervisor
|
||||||
|
@ -124,8 +127,8 @@ func (su *Supervisor) newListener() (net.Listener, error) {
|
||||||
// restarts we may want for the server.
|
// restarts we may want for the server.
|
||||||
//
|
//
|
||||||
// User still be able to call .Serve instead.
|
// User still be able to call .Serve instead.
|
||||||
// l, err := netutil.TCPKeepAlive(su.Server.Addr)
|
// l, err := netutil.TCPKeepAlive(su.Server.Addr, su.SocketReuse)
|
||||||
l, err := netutil.TCP(su.Server.Addr)
|
l, err := netutil.TCP(su.Server.Addr, su.SocketSharding)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -367,7 +370,13 @@ func (su *Supervisor) runTLS(getCertificate func(*tls.ClientHelloInfo) (*tls.Cer
|
||||||
defer cancel()
|
defer cancel()
|
||||||
http1RedirectServer.Shutdown(ctx)
|
http1RedirectServer.Shutdown(ctx)
|
||||||
})
|
})
|
||||||
go http1RedirectServer.ListenAndServe()
|
|
||||||
|
ln, err := netutil.TCP(":http", su.SocketSharding)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
go http1RedirectServer.Serve(ln)
|
||||||
}
|
}
|
||||||
|
|
||||||
if su.Server.TLSConfig == nil {
|
if su.Server.TLSConfig == nil {
|
||||||
|
@ -401,7 +410,12 @@ func (su *Supervisor) runTLS(getCertificate func(*tls.ClientHelloInfo) (*tls.Cer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return su.supervise(func() error { return su.Server.ListenAndServeTLS("", "") })
|
ln, err := netutil.TCP(su.Server.Addr, su.SocketSharding)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return su.supervise(func() error { return su.Server.ServeTLS(ln, "", "") })
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterOnShutdown registers a function to call on Shutdown.
|
// RegisterOnShutdown registers a function to call on Shutdown.
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package netutil
|
package netutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -38,16 +39,17 @@ func (l tcpKeepAliveListener) Accept() (net.Conn, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TCP returns a new tcp(ipv6 if supported by network) and an error on failure.
|
// TCP returns a new tcp(ipv6 if supported by network) and an error on failure.
|
||||||
func TCP(addr string) (net.Listener, error) {
|
func TCP(addr string, reuse bool) (net.Listener, error) {
|
||||||
l, err := net.Listen("tcp", addr)
|
var cfg net.ListenConfig
|
||||||
if err != nil {
|
if reuse {
|
||||||
return nil, err
|
cfg.Control = control
|
||||||
}
|
}
|
||||||
return l, nil
|
|
||||||
|
return cfg.Listen(context.Background(), "tcp", addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TCPKeepAlive returns a new tcp keep alive Listener and an error on failure.
|
// TCPKeepAlive returns a new tcp keep alive Listener and an error on failure.
|
||||||
func TCPKeepAlive(addr string) (ln net.Listener, err error) {
|
func TCPKeepAlive(addr string, reuse bool) (ln net.Listener, err error) {
|
||||||
// if strings.HasPrefix(addr, "127.0.0.1") {
|
// if strings.HasPrefix(addr, "127.0.0.1") {
|
||||||
// // it's ipv4, use ipv4 tcp listener instead of the default ipv6. Don't.
|
// // it's ipv4, use ipv4 tcp listener instead of the default ipv6. Don't.
|
||||||
// ln, err = net.Listen("tcp4", addr)
|
// ln, err = net.Listen("tcp4", addr)
|
||||||
|
@ -55,7 +57,7 @@ func TCPKeepAlive(addr string) (ln net.Listener, err error) {
|
||||||
// ln, err = TCP(addr)
|
// ln, err = TCP(addr)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
ln, err = TCP(addr)
|
ln, err = TCP(addr, reuse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -110,19 +112,20 @@ func CERT(addr string, cert tls.Certificate) (net.Listener, error) {
|
||||||
// LETSENCRYPT returns a new Automatic TLS Listener using letsencrypt.org service
|
// LETSENCRYPT returns a new Automatic TLS Listener using letsencrypt.org service
|
||||||
// receives three parameters,
|
// receives three parameters,
|
||||||
// the first is the host of the server,
|
// the first is the host of the server,
|
||||||
// second can be the server name(domain) or empty if skip verification is the expected behavior (not recommended)
|
// second one should declare if the underline tcp listener can be binded more than once,
|
||||||
// and the third is optionally, the cache directory, if you skip it then the cache directory is "./certcache"
|
// third can be the server name(domain) or empty if skip verification is the expected behavior (not recommended),
|
||||||
|
// and the forth is optionally, the cache directory, if you skip it then the cache directory is "./certcache"
|
||||||
// if you want to disable cache directory then simple give it a value of empty string ""
|
// if you want to disable cache directory then simple give it a value of empty string ""
|
||||||
//
|
//
|
||||||
// does NOT supports localhost domains for testing.
|
// does NOT supports localhost domains for testing.
|
||||||
//
|
//
|
||||||
// this is the recommended function to use when you're ready for production state.
|
// this is the recommended function to use when you're ready for production state.
|
||||||
func LETSENCRYPT(addr string, serverName string, cacheDirOptional ...string) (net.Listener, error) {
|
func LETSENCRYPT(addr string, reuse bool, serverName string, cacheDirOptional ...string) (net.Listener, error) {
|
||||||
if portIdx := strings.IndexByte(addr, ':'); portIdx == -1 {
|
if portIdx := strings.IndexByte(addr, ':'); portIdx == -1 {
|
||||||
addr += ":443"
|
addr += ":443"
|
||||||
}
|
}
|
||||||
|
|
||||||
l, err := TCP(addr)
|
l, err := TCP(addr, reuse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
25
core/netutil/tcp_soreuse_control_unix.go
Normal file
25
core/netutil/tcp_soreuse_control_unix.go
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// +build !windows,!wasm
|
||||||
|
|
||||||
|
package netutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func control(network, address string, c syscall.RawConn) (err error) {
|
||||||
|
c.Control(func(fd uintptr) {
|
||||||
|
err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
9
core/netutil/tcp_soreuse_control_wasm.go
Normal file
9
core/netutil/tcp_soreuse_control_wasm.go
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// +build wasm
|
||||||
|
|
||||||
|
package netutil
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
func control(network, address string, c syscall.RawConn) error {
|
||||||
|
return nil
|
||||||
|
}
|
13
core/netutil/tcp_soreuse_control_windows.go
Normal file
13
core/netutil/tcp_soreuse_control_windows.go
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package netutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
func control(network, address string, c syscall.RawConn) (err error) {
|
||||||
|
return c.Control(func(fd uintptr) {
|
||||||
|
err = windows.SetsockoptInt(windows.Handle(fd), windows.SOL_SOCKET, windows.SO_REUSEADDR, 1)
|
||||||
|
})
|
||||||
|
}
|
1
go.mod
1
go.mod
|
@ -34,6 +34,7 @@ require (
|
||||||
go.etcd.io/bbolt v1.3.5
|
go.etcd.io/bbolt v1.3.5
|
||||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
|
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
|
||||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9
|
golang.org/x/net v0.0.0-20200602114024-627f9648deb9
|
||||||
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd
|
||||||
golang.org/x/text v0.3.3
|
golang.org/x/text v0.3.3
|
||||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1
|
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1
|
||||||
google.golang.org/protobuf v1.24.0
|
google.golang.org/protobuf v1.24.0
|
||||||
|
|
4
iris.go
4
iris.go
|
@ -1107,6 +1107,10 @@ func (app *Application) Run(serve Runner, withOrWithout ...Configurator) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.ConfigureHost(func(host *Supervisor) {
|
||||||
|
host.SocketSharding = app.config.SocketSharding
|
||||||
|
})
|
||||||
|
|
||||||
app.tryStartTunneling()
|
app.tryStartTunneling()
|
||||||
|
|
||||||
if len(app.Hosts) > 0 {
|
if len(app.Hosts) > 0 {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user