HellPot/http/router.go

125 lines
2.8 KiB
Go
Raw Normal View History

2021-09-15 15:05:27 +00:00
package http
import (
2021-09-15 16:52:18 +00:00
"bufio"
2021-09-15 16:13:16 +00:00
"fmt"
2021-09-22 06:47:32 +00:00
"runtime"
2021-09-15 15:05:27 +00:00
"time"
"github.com/fasthttp/router"
2021-09-15 16:13:16 +00:00
"github.com/rs/zerolog"
2021-09-15 15:05:27 +00:00
"github.com/valyala/fasthttp"
"github.com/yunginnanet/HellPot/config"
"github.com/yunginnanet/HellPot/heffalump"
)
var log *zerolog.Logger
2021-09-15 16:13:16 +00:00
2021-09-15 15:05:27 +00:00
func getRealRemote(ctx *fasthttp.RequestCtx) string {
xrealip := string(ctx.Request.Header.Peek("X-Real-IP"))
if len(xrealip) > 0 {
return xrealip
}
return ctx.RemoteIP().String()
}
2021-09-15 16:52:18 +00:00
func hellPot(ctx *fasthttp.RequestCtx) {
2021-09-15 15:05:27 +00:00
remoteAddr := getRealRemote(ctx)
slog := log.With().
2021-09-15 16:52:18 +00:00
Str("USERAGENT", string(ctx.UserAgent())).
2021-09-15 15:05:27 +00:00
Str("REMOTE_ADDR", remoteAddr).
Interface("URL", string(ctx.RequestURI())).Logger()
2021-09-15 16:52:18 +00:00
slog.Info().Msg("NEW")
2021-09-15 15:05:27 +00:00
s := time.Now()
2021-09-15 16:52:18 +00:00
var n int64
ctx.SetBodyStreamWriter(func(bw *bufio.Writer) {
2021-09-15 17:33:48 +00:00
var err error
var wn int64
for {
wn, err = heffalump.DefaultHeffalump.WriteHell(bw)
n += wn
if err != nil {
slog.Debug().Err(err).Msg("END_ON_ERR")
break
}
}
2021-09-15 16:52:18 +00:00
2021-09-15 17:33:48 +00:00
slog.Info().
Int64("BYTES", n).
Dur("DURATION", time.Since(s)).
Msg("FINISH")
})
2021-09-15 15:05:27 +00:00
}
2021-09-15 16:52:18 +00:00
func getSrv(r *router.Router) fasthttp.Server {
2021-09-15 16:13:16 +00:00
if !config.RestrictConcurrency {
config.MaxWorkers = fasthttp.DefaultConcurrency
}
log = config.GetLogger()
2021-09-15 16:52:18 +00:00
return fasthttp.Server{
2021-09-15 16:13:16 +00:00
// User defined server name
// Likely not useful if behind a reverse proxy without additional configuration of the proxy server.
Name: config.FakeServerName,
/*
2021-09-15 16:52:18 +00:00
from fasthttp docs: "By default request read timeout is unlimited."
My thinking here is avoiding some sort of weird oversized GET query just in case.
2021-09-15 16:13:16 +00:00
*/
2021-09-15 17:33:48 +00:00
ReadTimeout: 5 * time.Second,
2021-09-15 16:13:16 +00:00
MaxRequestBodySize: 1 * 1024 * 1024,
// Help curb abuse of HellPot (we've always needed this badly)
2021-09-15 17:33:48 +00:00
MaxConnsPerIP: 10,
2021-09-15 16:13:16 +00:00
MaxRequestsPerConn: 2,
2021-09-15 17:33:48 +00:00
Concurrency: config.MaxWorkers,
2021-09-15 16:13:16 +00:00
// only accept GET requests
GetOnly: true,
2021-09-15 16:52:18 +00:00
// we don't care if a request ends up being handled by a different handler (in fact it probably will)
2021-09-15 16:13:16 +00:00
KeepHijackedConns: true,
CloseOnShutdown: true,
// No need to keepalive, our response is a sort of keep-alive ;)
DisableKeepalive: true,
Handler: r.Handler,
Logger: log,
2021-09-15 16:13:16 +00:00
}
2021-09-15 16:52:18 +00:00
}
// Serve starts our HTTP server and request router
func Serve() error {
log = config.GetLogger()
l := config.HTTPBind + ":" + config.HTTPPort
2021-09-15 16:52:18 +00:00
r := router.New()
r.GET("/robots.txt", robotsTXT)
for _, p := range config.Paths {
r.GET(fmt.Sprintf("/%s", p), hellPot)
}
2021-09-15 16:13:16 +00:00
2021-09-15 16:52:18 +00:00
srv := getSrv(r)
2021-09-15 17:33:48 +00:00
2021-09-22 06:47:32 +00:00
if !config.UseUnixSocket || runtime.GOOS == "windows" {
2021-09-15 16:13:16 +00:00
log.Info().Str("caller", l).Msg("Listening and serving HTTP...")
return srv.ListenAndServe(l)
}
if len(config.UnixSocketPath) < 1 {
log.Fatal().Msg("unix_socket_path configuration directive appears to be empty")
}
log.Info().Str("caller", config.UnixSocketPath).Msg("Listening and serving HTTP...")
return listenOnUnixSocket(config.UnixSocketPath, r)
2021-09-15 15:05:27 +00:00
}