Add support for HTTP rewrites (#1062)

This adds a new configuration option for the HTTP client to replace URI prefixes when making outbound calls.

Follows the design of https://github.com/apple/pkl-evolution/pull/17
This commit is contained in:
Daniel Chao
2025-07-16 15:53:31 -07:00
committed by GitHub
parent fea031a138
commit 99020bb79d
27 changed files with 607 additions and 47 deletions

View File

@@ -109,10 +109,61 @@ externalModuleReaders: Mapping<String, ExternalReader>?
@Since { version = "0.27.0" }
externalResourceReaders: Mapping<String, ExternalReader>?
const local hostnameRegex = Regex(#"https?://([^/?#]*)"#)
const local hasNonEmptyHostname = (it: String) ->
let (hostname = hostnameRegex.findMatchesIn(it).getOrNull(0)?.groups?.getOrNull(1)?.value)
hostname != null && hostname.length > 0
/// A key or value in [Http.rewrites].
@Since { version = "0.29.0" }
typealias HttpRewrite = String(
startsWith(Regex("https?://")),
endsWith("/"),
hasNonEmptyHostname
)
/// Settings that control how Pkl talks to HTTP(S) servers.
class Http {
/// Configuration of the HTTP proxy to use.
proxy: Proxy?
/// Replace outbound requests from one URL with another URL.
///
/// Each key describes the prefix of a request, and each value describes the replacement prefix.
///
/// This can be useful for setting up mirroring of packages, which are fetched over HTTPS.
//
/// In the case of multiple matches, the longest prefix is is used.
///
/// The URL hostname is case-insensitive.
///
/// A replacement only happens once when resolving URLs.
/// Therefore, the first replacement is the final URL that is used for the outbound request.
///
/// In the following example, an original request for `https://pkg.pkl-lang.org/my/pkg@1.0.0` is
/// replaced with `https://my.internal.mirror/my/pkg@1.0.0`.
///
/// This does not affect `3XX` status code redirect following.
///
/// Example:
///
/// ```
/// rewrites {
/// ["https://pkg.pkl-lang.org/"] = "https://my.internal.mirror/"
/// }
/// ```
///
/// Rewrite targets must satisfy the following:
///
/// * It starts with either `http://`, or `https://`.
/// * It ends with `/`.
/// * It has a non-empty hostname.
///
/// An rewrite target should also not contain a query string or fragment component
/// (not schematically enforced).
@Since { version = "0.29.0" }
rewrites: Mapping<HttpRewrite, HttpRewrite>?
}
/// Settings that control how Pkl talks to HTTP proxies.