aboutsummaryrefslogtreecommitdiffstats
path: root/main.go
diff options
context:
space:
mode:
authorterminaldweller <devi@terminaldweller.com>2025-05-01 20:58:00 +0000
committerterminaldweller <devi@terminaldweller.com>2025-05-01 20:58:00 +0000
commit981f0f0d988a663bfa92ed2a5bfa0c1b2495f48d (patch)
treeed0964289dc9ebbefda1343bc3ab3f240abc80f8 /main.go
parentadded the proxy protocol to the server (diff)
downloadicanhazallips-981f0f0d988a663bfa92ed2a5bfa0c1b2495f48d.tar.gz
icanhazallips-981f0f0d988a663bfa92ed2a5bfa0c1b2495f48d.zip
added the proxy protocol to the servernew
Diffstat (limited to 'main.go')
-rw-r--r--main.go183
1 files changed, 183 insertions, 0 deletions
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..48222bf
--- /dev/null
+++ b/main.go
@@ -0,0 +1,183 @@
+// https://gist.github.com/miguelmota/7b765edff00dc676215d6174f3f30216
+package main
+
+import (
+ "errors"
+ "log"
+ "net"
+ "net/http"
+ "os"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/pires/go-proxyproto"
+)
+
+const (
+ defaultTimeOut = 10.
+)
+
+var (
+ errMalformedAdr = errors.New("malformed address")
+ errIPNotFound = errors.New("ip not found")
+ errBadFloatValue = errors.New("bad float value")
+ errBadConfig = errors.New("bad config")
+)
+
+func getDefaultOptions() map[string]float64 {
+ return map[string]float64{
+ "APP_CONTEXT_TIMEOUT": defaultTimeOut,
+ "APP_READ_HEADER_TIMEOUT": defaultTimeOut,
+ "APP_READ_TIMEOUT": defaultTimeOut,
+ "APP_WRITE_TIMEOUT": defaultTimeOut,
+ "APP_IDLE_TIMEOUT": defaultTimeOut,
+ }
+}
+
+func getIP(request *http.Request) (string, error) {
+ ips := request.Header.Get("X-Forwarded-For")
+ splitIps := strings.Split(ips, ",")
+
+ log.Println(request.RemoteAddr)
+
+ if len(splitIps) > 0 {
+ netIP := net.ParseIP(splitIps[len(splitIps)-1])
+ if netIP != nil {
+ return netIP.String(), nil
+ }
+ }
+
+ ip, _, err := net.SplitHostPort(request.RemoteAddr)
+ if err != nil {
+ return "", errMalformedAdr
+ }
+
+ if netIP := net.ParseIP(ip); netIP != nil {
+ ip := netIP.String()
+ if ip == "::1" {
+ return "127.0.0.1", nil
+ }
+
+ return ip, nil
+ }
+
+ return "", errIPNotFound
+}
+
+func ipHandler(writer http.ResponseWriter, request *http.Request) {
+ ipAddr, err := getIP(request)
+ if err != nil {
+ writer.WriteHeader(http.StatusInternalServerError)
+
+ return
+ }
+
+ writer.WriteHeader(http.StatusOK)
+
+ writtenLen, err := writer.Write([]byte(ipAddr))
+ if err != nil || writtenLen != len(ipAddr) {
+ writer.WriteHeader(http.StatusInternalServerError)
+
+ return
+ }
+}
+
+type Config struct {
+ Addr string
+ ContextTimeOut float64
+ ReadHeaderTimeout float64
+ ReadTimeout float64
+ WriteTimeout float64
+ IdleTimeout float64
+}
+
+func getConfigValue(envVarName string) (float64, error) {
+ defaultOptions := getDefaultOptions()
+
+ paramEnv := os.Getenv(envVarName)
+ if paramEnv != "" {
+ param, err := strconv.ParseFloat(paramEnv, 64)
+ if err != nil {
+ return defaultOptions[envVarName], errBadFloatValue
+ }
+
+ return param, nil
+ }
+
+ return defaultOptions[envVarName], nil
+}
+
+func getConfig() (Config, error) {
+ var config Config
+
+ var err error
+
+ appAddrEnv := os.Getenv("APP_ADDR")
+ if appAddrEnv != "" {
+ config.Addr = appAddrEnv
+ } else {
+ config.Addr = ":8080"
+ }
+
+ config.ContextTimeOut, err = getConfigValue("APP_CONTEXT_TIMEOUT")
+ if err != nil {
+ log.Println(err.Error())
+ }
+
+ config.ReadHeaderTimeout, err = getConfigValue("APP_READ_HEADER_TIMEOUT")
+ if err != nil {
+ log.Println(err.Error())
+ }
+
+ config.ReadTimeout, err = getConfigValue("APP_READ_TIMEOUT")
+ if err != nil {
+ log.Println(err.Error())
+ }
+
+ config.WriteTimeout, err = getConfigValue("APP_WRITE_TIMEOUT")
+ if err != nil {
+ log.Println(err.Error())
+ }
+
+ config.IdleTimeout, err = getConfigValue("APP_IDLE_TIMEOUT")
+ if err != nil {
+ log.Println(err.Error())
+ }
+
+ return config, err
+}
+
+func main() {
+ log.SetOutput(os.Stdout)
+ http.HandleFunc("/", ipHandler)
+
+ config, err := getConfig()
+ if err != nil {
+ log.Fatal(errBadConfig)
+ }
+
+ server := http.Server{
+ Addr: config.Addr,
+ ReadHeaderTimeout: time.Duration(config.ReadHeaderTimeout) * time.Second,
+ ReadTimeout: time.Duration(config.ReadTimeout) * time.Second,
+ WriteTimeout: time.Duration(config.WriteTimeout) * time.Second,
+ IdleTimeout: time.Duration(config.IdleTimeout) * time.Second,
+ TLSNextProto: nil,
+ ErrorLog: nil,
+ Handler: nil,
+ }
+
+ ln, err := net.Listen("tcp", config.Addr)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ proxyListener := &proxyproto.Listener{
+ Listener: ln,
+ ReadHeaderTimeout: time.Duration(config.ReadHeaderTimeout) * time.Second,
+ }
+ defer proxyListener.Close()
+
+ log.Fatal(server.Serve(proxyListener))
+}