myip/main.go

119 lines
2.2 KiB
Go
Raw Normal View History

2023-09-25 21:05:15 +02:00
package main
import (
"encoding/json"
2024-04-03 23:49:07 +02:00
"errors"
2023-09-25 21:05:15 +02:00
"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)
2023-09-25 21:09:33 +02:00
return
2023-09-25 21:05:15 +02:00
}
var Type ResponseType
Type = ResponseType(r.URL.Query().Get("t"))
if !Type.IsValid() {
// Using defualt
Type = DEFAULT
}
log.Printf("Type: %v\n", Type)
2024-04-03 23:49:07 +02:00
ip, err := determineRealIP(r)
if err != nil {
log.Println(err.Error())
w.WriteHeader(http.StatusInternalServerError)
}
2023-09-25 21:05:15 +02:00
2024-04-03 23:49:07 +02:00
err = writeFormattedIP(w, Type, ip)
2023-09-25 21:05:15 +02:00
if err != nil {
log.Println(err.Error())
w.WriteHeader(http.StatusInternalServerError)
}
}
2024-04-03 23:49:07 +02:00
func determineRealIP(r *http.Request) (string, error) {
2023-09-25 21:05:15 +02:00
ip := r.RemoteAddr
xRealIP := r.Header.Get("X-Real-IP")
if xRealIP != "" {
ip = xRealIP
}
ipPort, err := netip.ParseAddrPort(ip)
if err != nil {
2024-04-03 23:49:07 +02:00
return "", err
2023-09-25 21:05:15 +02:00
}
2024-04-03 23:49:07 +02:00
if !ipPort.IsValid() {
return "", errors.New("Zero IP")
2023-09-25 21:05:15 +02:00
}
2024-04-03 23:49:07 +02:00
ip = ipPort.Addr().String()
return ip, nil
2023-09-25 21:05:15 +02:00
}
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
}