A focused builder for HTTP/HTTPS URLs, powered by the url crate.
http-url does not reimplement URL parsing. Parsing, percent-encoding,
IDNA normalization and relative-reference resolution are all delegated to
url (the WHATWG URL Standard implementation). What this crate adds on top
is:
- a fluent
HttpUrlBuilderfor assembling URLs programmatically, - an
HttpUrlvalue type that enforces the "scheme ishttporhttps" invariant, with a typedSchemeaccessor.
Component access (host, path, query, fragment, …) is provided directly by
url::Url via HttpUrl::as_url; this crate does not re-wrap those
getters.
- Fluent HTTP/HTTPS URL builder
HttpUrlas a typed, scheme-restricted newtype overurl::Urlno_std+allocsupport
[dependencies]
http-url = "0.2"use http_url::{HttpUrl, Scheme};
// Build
let http_url = HttpUrl::builder()
.scheme(Scheme::Https)
.host("api.example.com")
.add_path_segment("v1")
.add_path_segment("users")
.add_query_parameter("id", "42")
.build()
.unwrap();
assert_eq!(http_url.to_string(), "https://api.example.com/v1/users?id=42");
// Parse (delegated to the `url` crate). Only http/https are accepted.
let http_url = HttpUrl::parse("https://user:pass@example.com:8080/path/to?a=1&b=2#frag").unwrap();
assert_eq!(http_url.scheme(), "https");
// Reach the full url::Url API for component access.
let url = http_url.as_url();
assert_eq!(url.username(), "user");
assert_eq!(url.password(), Some("pass"));
assert_eq!(url.host_str(), Some("example.com"));
assert_eq!(url.port(), Some(8080));
assert_eq!(url.path(), "/path/to");
assert_eq!(url.query(), Some("a=1&b=2"));
assert_eq!(url.fragment(), Some("frag"));HttpUrl::builder()
.scheme(Scheme::Https) // Scheme::Http | Scheme::Https
.username("user") // optional
.password("pass") // optional
.host("example.com") // domain, IPv4, or [IPv6]
.port(8080) // optional, uses scheme default otherwise
.remove_port() // revert to scheme default
.add_path_segment("api") // decoded segment (auto-encoded)
.add_path_segment("v1")
.add_path_segments(&["a", "b"]) // multiple segments at once
.set_path("/a/b/c") // replace entire path (decoded)
.add_query_parameter("key", "val") // decoded form
.remove_query_parameter("key") // remove all with this name
.clear_query_parameters() // remove all
.fragment("section") // decoded fragment
.remove_fragment() // clear fragment
.build_url() // -> url::Url
.unwrap();
// or .build() -> HttpUrlAll components are stored in decoded form on the builder and handed to
url::Url on build() / build_url(), which performs percent-encoding and
normalization.
A builder can be started from a parsed URL — a string, an url::Url, or an
existing HttpUrl — and then modified:
use http_url::{HttpUrl, HttpUrlBuilder};
// From a string
let url = HttpUrlBuilder::parse("https://example.com/a/b?x=1")
.unwrap()
.add_path_segment("c")
.add_query_parameter("y", "2")
.build()
.unwrap();
assert_eq!(url.to_string(), "https://example.com/a/b/c?x=1&y=2");
// From an existing HttpUrl
let url = HttpUrl::parse("https://example.com/a/b?x=1").unwrap();
let url2 = url.new_builder()
.add_path_segment("c")
.build()
.unwrap();
assert_eq!(url2.to_string(), "https://example.com/a/b/c?x=1");url is a required dependency, and HttpUrl is a thin newtype over
url::Url. Use the conversion methods to move between the two:
use http_url::HttpUrl;
// url::Url → HttpUrl (fallible, only http/https)
let u = url::Url::parse("https://example.com/path").unwrap();
let http_url = HttpUrl::try_from(u.clone()).unwrap();
assert_eq!(http_url.as_url(), &u);
// HttpUrl → url::Url (infallible, move)
let url: url::Url = http_url.into();
assert_eq!(url, u);| Feature | Default | Description |
|---|---|---|
std |
✅ | Enables std::error::Error impl via thiserror |
The crate works without std, requiring only alloc:
[dependencies]
http-url = { version = "0.2", default-features = false }The underlying url crate is itself no_std + alloc compatible.
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.