From e1a9246b1a86d93e0e321f2069626378e4f952ef Mon Sep 17 00:00:00 2001 From: HeshamTB Date: Mon, 25 Sep 2023 22:05:15 +0300 Subject: [PATCH] init --- go.mod | 3 ++ go.sum | 0 main.go | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..c971ff8 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module gitea.hbanafa.com/hesham/myip + +go 1.21.1 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e69de29 diff --git a/main.go b/main.go new file mode 100644 index 0000000..4e31255 --- /dev/null +++ b/main.go @@ -0,0 +1,118 @@ +package main + +import ( + "encoding/json" + "log" + "net/http" + "net/netip" +) + +// @title My IP +// @version 0.1 +// @description Get the requseters Real IP, based on HTTP Requests +func main() { + handler := http.NewServeMux() + handler.HandleFunc("/", handleRoot) + + log.Fatal(http.ListenAndServe(":8080", handler)) +} + +type ResponseType string + +const ( + TEXT ResponseType = "TEXT" + JSON ResponseType = "JSON" + DEFAULT ResponseType = TEXT +) + +func (r *ResponseType) IsValid() bool { + + // This is pretty ugly + // TODO: Comapre with ignore-case + if *r == TEXT { + return true + } + + if *r == JSON { + return true + } + + return false +} + +func handleRoot(w http.ResponseWriter, r *http.Request) { + + if r.Method != "GET" { + w.WriteHeader(http.StatusBadRequest) + } + var Type ResponseType + Type = ResponseType(r.URL.Query().Get("t")) + + if !Type.IsValid() { + // Using defualt + Type = DEFAULT + } + + log.Printf("Type: %v\n", Type) + ip := determineRealIP(r) + + w.WriteHeader(http.StatusOK) + err := writeFormattedIP(w, Type, ip) + if err != nil { + log.Println(err.Error()) + w.WriteHeader(http.StatusInternalServerError) + } +} + +func determineRealIP(r *http.Request) string { + ip := r.RemoteAddr + + xRealIP := r.Header.Get("X-Real-IP") + if xRealIP != "" { + ip = xRealIP + } + + ipPort, err := netip.ParseAddrPort(ip) + if err != nil { + log.Println("Error while parsing AddrPort:", err.Error()) + } + + ipAddrPort := ipPort.Addr().String() + if ipAddrPort == "invalid IP" { + ipAddr, err := netip.ParseAddr(ip) + if err != nil { + // Last resort + log.Println("Error while parsing Addr:", err.Error()) + return ip + } + ip = ipAddr.String() + } + + return ip +} + +func writeFormattedIP(w http.ResponseWriter, Type ResponseType, ip string) error { + if Type == TEXT { + _, err := w.Write([]byte(ip)) + if err != nil { + return err + } + return nil + } + + if Type == JSON { + // TODO: Use MarshalIndent + jsonResponse, err := json.Marshal(map[string]string{"ip": ip}) + if err != nil { + return err + } + _, err = w.Write(jsonResponse) + if err != nil { + return err + } + } + + return nil +} + +