diff --git a/0if.go b/0if.go new file mode 100644 index 0000000..ddb3a3e --- /dev/null +++ b/0if.go @@ -0,0 +1,33 @@ +package main + +import ( + "encoding/json" + "net/http" + "os" +) + +func GetIP(r *http.Request) string { + forwarded := r.Header.Get("X-FORWARDED-FOR") + if forwarded != "" { + return forwarded + } + return r.RemoteAddr +} + +func main() { + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(GetIP(r))) + }) + + http.HandleFunc("/json", func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", "application/json") + resp, _ := json.Marshal(map[string]string{ + "ip": GetIP(r), + }) + w.Write(resp) + }) + + listen := ":8000" + os.Stdout.Write([]byte("Listening on " + listen)) + http.ListenAndServe(listen, nil) +} diff --git a/Dockerfile b/Dockerfile index 15cf9e6..e18a458 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,15 @@ -FROM python:3.7-alpine +FROM golang:1.17-alpine AS build + +WORKDIR /code + +COPY 0if.go /code +RUN go build ./0if.go + +FROM alpine:latest AS final MAINTAINER Yehuda Deutsch -RUN echo 'manylinux1_compatible = True' > /usr/local/lib/python3.7/_manylinux.py -RUN apk add --virtual .build-deps gcc musl-dev \ - && pip install sanic \ - && rm -Rf ~/.cache \ - && apk --purge del .build-deps - WORKDIR /code -COPY app.py /code/ +COPY --from=build /code/0if /code/0if -CMD ["python", "app.py"] +CMD ["/code/0if"] diff --git a/app.py b/app.py deleted file mode 100644 index 9ff2c4a..0000000 --- a/app.py +++ /dev/null @@ -1,67 +0,0 @@ -from ipaddress import ip_address -from sanic import Sanic -from sanic.response import text, json -from sanic.views import HTTPMethodView - - -class GetClientIpMixin: - def get_client_ip(self, request): - possible_ip = request.ip - - for header_name in ('x-real-ip', 'x-forwarded-for'): - candidate_ip = None - header_value = request.headers.get(header_name) - if not header_value: - continue - for ip in header_value.split(',')[::-1]: - try: - candidate_ip = ip_address(ip.strip()) - except ValueError: - continue - if candidate_ip.is_global: - break - if candidate_ip: - possible_ip = candidate_ip - break - - return str(possible_ip) - - -class MainView(HTTPMethodView, GetClientIpMixin): - def get(self, request): - return text(self.get_client_ip(request)) - - -class JsonView(HTTPMethodView, GetClientIpMixin): - def get(self, request): - return json({'ip_address': self.get_client_ip(request)}) - - -class Application(object): - app = Sanic() - - def __init__(self, args): - self.args = args - self.app.add_route(MainView.as_view(), '/') - self.app.add_route(JsonView.as_view(), '/json') - - def run(self): - self.app.run(host=self.args.interface, port=self.args.port) - - -if __name__ == '__main__': - import os - from argparse import ArgumentParser - - default_host = os.environ.get('APP_HOST', '0.0.0.0') - default_port = int(os.environ.get('APP_PORT', 8080)) - default_trusted = os.environ.get('TRUSTED_PROXIES') or None - - parser = ArgumentParser('app.py') - parser.add_argument('--interface', '-i', type=str, help='Interface to listen on', default=default_host) - parser.add_argument('--port', '-p', type=int, help='Port to listen on', default=default_port) - parser.add_argument('--proxies', type=str, help='A list of trusted proxies, comma separated. you can use CIDRs.', default=default_trusted) - args = parser.parse_args() - - zero_if = Application(args) - zero_if.run()