Skip to content

Instantly share code, notes, and snippets.

@caiofilipini
Created November 15, 2019 21:08
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save caiofilipini/b85ad9f8db89eac9a6e9496e788c54da to your computer and use it in GitHub Desktop.
Save caiofilipini/b85ad9f8db89eac9a6e9496e788c54da to your computer and use it in GitHub Desktop.
Go (golang) HTTP server with a simple connection limiter (max conn)
package main
import (
"context"
"flag"
"log"
"net"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"golang.org/x/net/netutil"
)
const (
defaultBindAddr = ":8080"
// defaultMaxConn is the default number of max connections the
// server will handle. 0 means no limits will be set, so the
// server will be bound by system resources.
defaultMaxConn = 0
)
func main() {
var (
bindAddr string
maxConn uint64
)
flag.StringVar(&bindAddr, "b", defaultBindAddr, "TCP address the server will bind to")
flag.Uint64Var(&maxConn, "c", defaultMaxConn, "maximum number of client connections the server will accept, 0 means unlimited")
flag.Parse()
router := http.NewServeMux()
router.HandleFunc("/", handleRequest)
srv := http.Server{
ReadHeaderTimeout: time.Second * 5,
ReadTimeout: time.Second * 10,
Handler: router,
}
listener, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatal(err)
}
if maxConn > 0 {
listener = netutil.LimitListener(listener, int(maxConn))
log.Printf("max connections set to %d\n", maxConn)
}
defer listener.Close()
log.Printf("listening on %s\n", listener.Addr().String())
go func() {
if err := srv.Serve(listener); err != nil && err != http.ErrServerClosed {
log.Fatal(err)
}
}()
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
<-c
log.Printf("interrupted, shutting down")
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Printf("graceful shutdown failed: %v\n", err)
}
}
func handleRequest(w http.ResponseWriter, r *http.Request) {
log.Printf("got request from %s\n", r.RemoteAddr)
w.WriteHeader(http.StatusOK)
w.Write([]byte("you got it"))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment