Reconstruct Original HTTP Request URL
The `original-url` package provides a utility function to reconstruct the full, original URL of an HTTP request by intelligently parsing various standard and de-facto standard HTTP headers. It accounts for potential modifications made by proxies, load balancers, and other intermediaries by examining headers like `Host`, `Forwarded`, `X-Forwarded-Proto`, `X-Forwarded-Host`, `X-Forwarded-Port`, and others. If the protocol cannot be determined from headers, it leverages the TLS connection's `encrypted` flag. The module returns a URL object compatible with Node.js's native `url.parse` output, including a `full` property for the complete URL string. The current stable version is 1.2.3, published over 6 years ago, indicating a very mature or slow-moving project that is likely in maintenance mode rather than active development. Its primary differentiator is its comprehensive handling of various proxy-related headers to accurately determine the client-facing URL.
Common errors
-
TypeError: originalUrl is not a function
cause Attempting to use `import { originalUrl } from 'original-url'` in an ES module environment when the package primarily provides a default export.fixChange the import statement to `import originalUrl from 'original-url';` for ES modules, or `const originalUrl = require('original-url');` for CommonJS. -
Original URL could not be determined
cause The request object (`req`) passed to `originalUrl` does not contain sufficient headers (e.g., `Host`, `Forwarded`, `X-Forwarded-*`) or an `encrypted` flag to reconstruct a full URL. This often happens for basic `localhost` requests without explicit headers or for requests where proxy headers are missing or malformed.fixEnsure that the incoming HTTP request includes at least a `Host` header. If behind a proxy, confirm that the proxy correctly forwards or sets `Forwarded` or `X-Forwarded-*` headers. For HTTPS, verify that the TLS connection sets the `req.socket.encrypted` flag correctly or `X-Forwarded-Proto: https` is present. -
ReferenceError: require is not defined in ES module scope
cause Attempting to use `const originalUrl = require('original-url');` in an ES module (`.mjs` file or `type: "module"` in `package.json`) in Node.js.fixSwitch to ES module import syntax: `import originalUrl from 'original-url';`. If you need to use CommonJS modules within an ES module, consider dynamic `import()` or review Node.js's interoperability documentation.
Warnings
- gotcha The package's latest version (1.2.3) was published over 6 years ago. While its core functionality remains relevant for parsing common proxy headers, it may not incorporate newer HTTP standards, header variations, or security considerations related to URL parsing and proxy handling. Always validate the output, especially in security-sensitive contexts.
- gotcha The library relies on `http.IncomingMessage` objects, common in Node.js server environments (e.g., `http`, `express`). It is not intended for client-side (browser) environments or environments where the `req` object is not a standard Node.js `IncomingMessage` instance.
- gotcha In serverless or containerized environments (e.g., AWS Lambda, Kubernetes behind a load balancer), the request object might already be pre-processed or wrapped by the platform's runtime. This can alter how headers are presented or which ones are available, potentially leading to `original-url` not accurately determining the URL.
- gotcha The `Forwarded` header (RFC 7239) can contain complex syntax, including multiple fields and quoted strings. While `original-url` attempts to parse it, malformed or non-standard `Forwarded` headers could lead to incorrect URL reconstruction. Similarly, `X-Forwarded-Host` and other `X-` headers might be spoofed by malicious clients if not properly secured by upstream proxies.
Install
-
npm install original-url -
yarn add original-url -
pnpm add original-url
Imports
- originalUrl
import { originalUrl } from 'original-url';import originalUrl from 'original-url';
- originalUrl (CommonJS)
const originalUrl = require('original-url'); - URL Object Structure
const url = originalUrl(req).url; // 'url' property might not exist, use 'full'
const url = originalUrl(req); console.log(url.protocol, url.host, url.pathname, url.query, url.full);
Quickstart
import http from 'http';
import originalUrl from 'original-url';
const server = http.createServer(function (req, res) {
const url = originalUrl(req);
if (url.full) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(`Original URL: ${url.full}\nProtocol: ${url.protocol}\nHost: ${url.host || 'N/A'}\nPath: ${url.pathname || 'N/A'}\nQuery: ${url.query || 'N/A'}\n`);
} else {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Original URL could not be determined. Check request headers.\n');
}
});
server.listen(1337, () => {
console.log('Server listening on http://localhost:1337');
console.log('Try with: curl localhost:1337');
console.log("Or with proxy headers: curl -H 'Forwarded: proto=https; host=example.com; for="10.0.0.1:1234"' localhost:1337/sub/path?key=value");
});