diff --git a/README.org b/README.org index 8e00d69..2b83c0e 100644 --- a/README.org +++ b/README.org @@ -4,13 +4,109 @@ A self-hosted API for obtaining your public IP address. +* Live API Usage + +An implementation of the API is available at [[https://ipme.fosterhangdaan.com][ipme.fosterhangdaan.com]]. + +| URL | Response Type | Sample Output | +|-------------------------------------------------------------+---------------+-------------------------------------| +| https://ipme.fosterhangdaan.com | text | =98.207.254.136= | +| https://ipme.fosterhangdaan.com?format=json | json | ={"ip":"98.207.254.136"}= | +| https://ipme.fosterhangdaan.com?format=jsonp | jsonp | =callback({"ip":"98.207.254.136"})= | +| https://ipme.fosterhangdaan.com?format=jsonp&callback=getIp | jsonp | =getIp({"ip":"98.207.254.136"})= | + +** Examples using ~curl~ + +To get your public IP address in plain text: + +#+begin_src shell +curl --silent https://ipme.fosterhangdaan.com +#+end_src + +For a response in =json= format: + +#+begin_src shell +curl --silent https://ipme.fosterhangdaan.com?format=json +#+end_src + +* Self-hosting + +** Requirements + +- [[https://podman.io/][Podman]] or [[https://www.docker.com/][Docker]] installed +- Ports 80 and 443 opened +- A domain name pointing to the server + +For reliable IP address identification, the instance should be hosted on an external server outside of your home or local network. + +** Compose setup + +The following =compose.yaml= can be used as reference: + +#+begin_src yaml +version: "3.9" + +volumes: + caddy-data: + external: true + caddy-config: + external: true + +networks: + proxy-tier: + driver: bridge + +services: + ipme: + image: code.fosterhangdaan.com/foster/ipme:latest + container_name: ipme + restart: unless-stopped + env_file: .env.ipme + networks: + - proxy-tier + caddy: + image: docker.io/library/caddy:2-alpine + container_name: caddy + restart: unless-stopped + ports: + - "80:80" + - "443:443" + volumes: + - ./Caddyfile:/etc/caddy/Caddyfile:ro + - caddy-data:/data + - caddy-config:/config + networks: + - proxy-tier +#+end_src + +=.env.ipme= + +#+begin_src env +RUN_MODE=prod +#+end_src + +=Caddyfile= + +#+begin_src Caddyfile +# Replace this domain with your own +https://ipme.mydomain.com { + reverse_proxy ipme:8000 +} +#+end_src + +** Run the services + +Run ~podman-compose up~ to start the services. + +The API should be available at the domain you selected. For example: =https://ipme.mydomain.com=. + * Contributing -Please send patches and bug reports by email to one of the maintainers. See the *Core Maintainers* section for a list of contacts. +Please send patches and bug reports by email to one of the maintainers. See the *Core maintainers* section for a list of contacts. Refer to [[https://git-send-email.io][this guide]] if you are not familiar with sending Git patches over email. -* Core Maintainers +* Core maintainers - *Foster Hangdaan* - Website: [[https://www.fosterhangdaan.com][www.fosterhangdaan.com]] @@ -23,8 +119,6 @@ Refer to [[https://git-send-email.io][this guide]] if you are not familiar with #+attr_html: :width 200px [[https://static.fosterhangdaan.com/images/agplv3-logo.svg]] -Copyright \copy 2023 Foster Hangdaan - This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the @@ -37,3 +131,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . + +* Copyright + +Copyright \copy 2023 Foster Hangdaan diff --git a/main.ts b/main.ts index da86fd7..ded6792 100644 --- a/main.ts +++ b/main.ts @@ -30,14 +30,26 @@ const handler = (req: Request): Response => { const url = new URL(req.url); const format = url.searchParams.get("format"); - if (format === "json") { - return new Response(JSON.stringify({ ip: clientIpAddress }), { - headers: { - "content-type": "application/json", - }, - }); - } else { - return new Response(clientIpAddress); + switch(format) { + case "json": { + return new Response(JSON.stringify({ ip: clientIpAddress }), { + headers: { + "content-type": "application/json", + }, + }); + } + case "jsonp": { + const parameter = JSON.stringify({ ip: clientIpAddress }); + const callback = url.searchParams.get("callback") || "callback"; + return new Response(`${callback}(${parameter});`, { + headers: { + "content-type": "application/javascript", + }, + }); + } + default: { + return new Response(clientIpAddress); + } } } else { return new Response("Not found", { status: 404 }); diff --git a/version.ts b/version.ts index b559979..13d9f46 100644 --- a/version.ts +++ b/version.ts @@ -1,2 +1,2 @@ -const version = "0.2.0"; +const version = "0.3.0"; export default version;