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
|
|
|
|
}
|
|
|
|
|