mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-23 01:57:55 +08:00
Merge abb9d470f2a8d475c58bf0c1c8f69822ffe86d01 into 3f27866f806536be319b3e342001dd4e0fb81691
This commit is contained in:
commit
b30b1d9ee2
24
README.md
24
README.md
@ -58,6 +58,7 @@ Gin is a web framework written in Go (Golang). It features a martini-like API wi
|
||||
- [Bind form-data request with custom struct](#bind-form-data-request-with-custom-struct)
|
||||
- [Try to bind body into different structs](#try-to-bind-body-into-different-structs)
|
||||
- [http2 server push](#http2-server-push)
|
||||
- [Support limiting the number of accepted requests using netutil.LimitListener](#RunLimited)
|
||||
- [Testing](#testing)
|
||||
- [Users](#users)
|
||||
|
||||
@ -1835,6 +1836,29 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### RunLimited
|
||||
|
||||
Limit the number of accepted requests via [netutils.LimitListener](https://godoc.org/golang.org/x/net/netutil)
|
||||
|
||||
|
||||
[embedmd]:# (examples/run-limited/main.go go)
|
||||
```go
|
||||
package main
|
||||
|
||||
import "github.com/gin-gonic/gin"
|
||||
|
||||
const maxConnections = 10
|
||||
func main() {
|
||||
r := gin.Default()
|
||||
r.GET("/ping", func(c *gin.Context) {
|
||||
c.JSON(200, gin.H{
|
||||
"message": "pong",
|
||||
})
|
||||
})
|
||||
r.RunLimited(maxConnections, ":80") // listen and serve on 0.0.0.0:8080
|
||||
}
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
The `net/http/httptest` package is preferable way for HTTP testing.
|
||||
|
14
examples/run-limited/main.go
Normal file
14
examples/run-limited/main.go
Normal file
@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import "github.com/gin-gonic/gin"
|
||||
|
||||
const maxConnections = 10
|
||||
func main() {
|
||||
r := gin.Default()
|
||||
r.GET("/ping", func(c *gin.Context) {
|
||||
c.JSON(200, gin.H{
|
||||
"message": "pong",
|
||||
})
|
||||
})
|
||||
r.RunLimited(maxConnections, ":80") // listen and serve on 0.0.0.0:8080
|
||||
}
|
38
gin.go
38
gin.go
@ -10,8 +10,10 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin/render"
|
||||
"golang.org/x/net/netutil"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -288,6 +290,42 @@ func (engine *Engine) Run(addr ...string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// RunLimited - use netuil.LimitListener to limit the number of inbound accepts
|
||||
func (engine *GalapagosEngine) RunLimited(limit int, addr ...string) (err error) {
|
||||
defer func() { debugPrintError(err) }()
|
||||
|
||||
address := resolveAddress(addr)
|
||||
debugPrint("Listening and serving HTTP on %s\n", address)
|
||||
|
||||
// err = http.ListenAndServe(address, engine)
|
||||
|
||||
srv := &http.Server{Addr: address, Handler: engine}
|
||||
address = srv.Addr
|
||||
if address == "" {
|
||||
address = ":http"
|
||||
}
|
||||
ln, err := net.Listen("tcp", address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lnLimited := netutil.LimitListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, limit)
|
||||
return srv.Serve(lnLimited)
|
||||
}
|
||||
|
||||
type tcpKeepAliveListener struct {
|
||||
*net.TCPListener
|
||||
}
|
||||
|
||||
func (ln tcpKeepAliveListener) Accept() (net.Conn, error) {
|
||||
tc, err := ln.AcceptTCP()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tc.SetKeepAlive(true)
|
||||
tc.SetKeepAlivePeriod(3 * time.Minute)
|
||||
return tc, nil
|
||||
}
|
||||
|
||||
// RunTLS attaches the router to a http.Server and starts listening and serving HTTPS (secure) requests.
|
||||
// It is a shortcut for http.ListenAndServeTLS(addr, certFile, keyFile, router)
|
||||
// Note: this method will block the calling goroutine indefinitely unless an error happens.
|
||||
|
Loading…
x
Reference in New Issue
Block a user