redline
← arena

Absolute, according to whom

PrincipalJavaScriptHTTP clientMined
MINED FROM REAL HISTORYaxios/axiosMIT

The code below is the file exactly as it stood in axios/axios. The defect was introduced on 2015-11-22, reviewed, merged, and fixed on 2024-08-13 in commit 07a661a2 — after 3187 days in the tree.

The commit was written by a human contributor to axios/axios, not by an agent. The ticket and the description on the next two panels are ours — a reconstruction of the case the original change made, so you meet it the way its reviewer did. The code, the defect and the dates are untouched.

HTTP-88the ticket

Let a per-request URL override the configured baseURL

Callers configure a `baseURL` once on the client. A few call sites need to hit a different host for a single request — an upload endpoint on a CDN, a health check on an internal service — and today the base is always prepended.

Add a helper that decides whether a requested URL is already absolute. If it is, use it as given; otherwise join it to the base. Follow RFC 3986 for what counts as a scheme.

the case the change madereconstructed by us

Added `isAbsoluteURL` and wired it into `buildFullPath`, so the base is only applied to relative URLs.

The regex follows RFC 3986 §3.1: a scheme is a letter followed by letters, digits, `+`, `-` or `.`, terminated by `:`. I made the scheme group optional so protocol-relative URLs — `//cdn.example.com/asset.png`, what the URL spec calls a network-path reference — are treated as absolute too. They are: a protocol-relative URL resolves against the current scheme rather than against our base path, so prepending `baseURL` to one would produce a URL pointing nowhere.

Case-insensitive, because RFC 3986 says schemes are case-insensitive. `combineURLs` is unchanged.

Our reconstruction of the argument the real change made, not a quotation of it. Fluent, specific, and not evidence of anything — which is the point.

lib/helpers/isAbsoluteURL.js15 lines
1'use strict';
2
3/**
4 * Determines whether the specified URL is absolute
5 *
6 * @param {string} url The URL to test
7 *
8 * @returns {boolean} True if the specified URL is absolute, otherwise false
9 */
10export default function isAbsoluteURL(url) {
11 // A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
12 // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
13 // by any combination of letters, digits, plus, period, or hyphen.
14 return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url);
15}
lib/helpers/combineURLs.js15 lines
1'use strict';
2
3/**
4 * Creates a new URL by combining the specified URLs
5 *
6 * @param {string} baseURL The base URL
7 * @param {string} relativeURL The relative URL
8 *
9 * @returns {string} The combined URL
10 */
11export default function combineURLs(baseURL, relativeURL) {
12 return relativeURL
13 ? baseURL.replace(/\/?\/$/, '') + '/' + relativeURL.replace(/^\/+/, '')
14 : baseURL;
15}
lib/core/buildFullPath.js21 lines
1'use strict';
2
3import isAbsoluteURL from '../helpers/isAbsoluteURL.js';
4import combineURLs from '../helpers/combineURLs.js';
5
6/**
7 * Creates a new URL by combining the baseURL with the requestedURL,
8 * only when the requestedURL is not already an absolute URL.
9 * If the requestURL is absolute, this function returns the requestedURL untouched.
10 *
11 * @param {string} baseURL The base URL
12 * @param {string} requestedURL Absolute or relative URL to combine
13 *
14 * @returns {string} The combined full path
15 */
16export default function buildFullPath(baseURL, requestedURL) {
17 if (baseURL && !isAbsoluteURL(requestedURL)) {
18 return combineURLs(baseURL, requestedURL);
19 }
20 return requestedURL;
21}