Behind a reverse proxy
Resolve the real client IP when Deno sits behind nginx, Caddy, or a cloud load balancer.
Default behavior
Without options, req.ip is the TCP peer address from Deno’s serve info. Header values cannot override it.
Trusted proxy
import { HttpServer } from "jsr:@webtools/expressapi";
const server = new HttpServer({ trustProxy: true });
server.get("/whoami", (req, res) =>
res.json({
ip: req.ip,
// first hop of x-forwarded-for when trustProxy is true
}));
if (import.meta.main) server.listen(5050);With trustProxy: true, ExpressAPI reads the first entry of x-forwarded-for (trimmed). If the header is absent, it falls back to the TCP address (or null in tests without serve info).
Example nginx snippet
location / {
proxy_pass http://127.0.0.1:5050;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}API details: Advanced, HttpServer.