Repository navigation
AdaUrl
public ref partial struct AdaUrl : IDisposable
A parsed URL. It has two parts: static methods that parse, answer and free inside one call, and an instance for reading several properties or changing the URL.
Being a ref struct, an instance cannot be stored in a field, captured by a lambda, or used
across await. Use AdaUrlHandle for that.
None of these need disposing, and none allocate with UTF-8 input.
| Method | Returns |
|---|---|
CanParse(ReadOnlySpan<byte> utf8) |
true if the input is a valid URL |
CanParse(ReadOnlySpan<byte> utf8, ReadOnlySpan<byte> baseUrl) |
true if the input resolves against the base |
CanParse(ReadOnlySpan<char> input) |
Same, from UTF-16 |
TryNormalize(ReadOnlySpan<byte> utf8, Span<byte> destination, out int written) |
The normalised URL |
TryGetHostname(ReadOnlySpan<byte> utf8, Span<byte> destination, out int written) |
The hostname, in ASCII |
TryGetOrigin(ReadOnlySpan<byte> utf8, Span<byte> destination, out int written) |
The origin |
The Try methods return false when the input is invalid or the buffer is too small.
AdaUrl.CanParse("https://example.com/"u8); // true
AdaUrl.CanParse("not a url"u8); // false
AdaUrl.CanParse("/docs"u8, "https://example.com"u8); // true
Span<byte> buffer = stackalloc byte[256];
AdaUrl.TryNormalize("HTTPS://Example.COM/a/../b"u8, buffer, out int written);
// https://example.com/b
AdaUrl.TryGetHostname("https://user@Bücher.example:8080/x"u8, buffer, out written);
// xn--bcher-kva.example
AdaUrl.TryGetOrigin("https://example.com:8443/a?b"u8, buffer, out written);
// https://example.com:8443TryGetHostname is the one to use for an allow list. It returns the hostname after IDNA, so
compare it against ASCII entries.
| Method | On invalid input |
|---|---|
TryParse(ReadOnlySpan<byte> utf8, out AdaUrl url) |
Returns false
|
TryParse(ReadOnlySpan<byte> utf8, ReadOnlySpan<byte> baseUrl, out AdaUrl url) |
Returns false
|
TryParse(ReadOnlySpan<char> input, out AdaUrl url) |
Returns false, also for a lone surrogate |
Parse(ReadOnlySpan<byte> utf8) |
Throws FormatException
|
Parse(ReadOnlySpan<char> input) |
Throws FormatException
|
using var url = AdaUrl.Parse("https://user:pass@example.com:8443/a/b?q=1#frag"u8);
if (AdaUrl.TryParse("../c?x=1"u8, "https://example.com/a/b/"u8, out AdaUrl resolved))
{
using (resolved)
{
// resolved.Href is https://example.com/a/c?x=1
}
}Every text property returns a borrowed ReadOnlySpan<byte>. See the rules on Home. Values
below are for https://user:pass@example.com:8443/a/b?q=1#frag.
| Property | Value | Notes |
|---|---|---|
Href |
https://user:pass@example.com:8443/a/b?q=1#frag |
The whole URL, serialised |
Protocol |
https: |
Includes the colon |
Username |
user |
|
Password |
pass |
|
Host |
example.com:8443 |
Includes the port |
Hostname |
example.com |
Without the port |
Port |
8443 |
Empty when it is the scheme's default |
Pathname |
/a/b |
|
Search |
?q=1 |
Includes ? when not empty |
Hash |
#frag |
Includes # when not empty |
HostType |
AdaHostType.Domain |
Domain, IPv4 or IPv6, see AdaUrlComponents
|
SchemeType |
AdaSchemeType.Https |
See AdaUrlComponents |
Components |
AdaUrlComponents | Byte offsets into Href
|
IsValid |
true |
false for a default or disposed instance |
http://example.com/ has an empty Port and HasPort is false, because 80 is the default.
| Property |
true when |
|---|---|
HasCredentials |
A username or password is present |
HasHostname |
A hostname is present |
HasEmptyHostname |
A hostname is present and empty, as in file:///C:/tmp/a.txt
|
HasPort |
An explicit, non default port is present |
HasPassword |
A password is present |
HasNonEmptyUsername |
The username is not empty |
HasNonEmptyPassword |
The password is not empty |
HasSearch |
A query is present |
HasHash |
A fragment is present |
TryGetOrigin(Span<byte> destination, out int written) writes the origin, for example
https://example.com:8443. Returns false when the buffer is too small.
Setters follow the WHATWG setter rules. Any setter invalidates spans read earlier from the same instance.
| Method | Returns false when |
|---|---|
TrySetHref(ReadOnlySpan<byte>) |
The value is not a valid URL. The URL is unchanged. |
TrySetProtocol(ReadOnlySpan<byte>) |
The scheme is rejected |
TrySetUsername(ReadOnlySpan<byte>) |
The URL cannot have credentials |
TrySetPassword(ReadOnlySpan<byte>) |
The URL cannot have credentials |
TrySetHost(ReadOnlySpan<byte>) |
The host is rejected. Sets the port too if the value has one. |
TrySetHostname(ReadOnlySpan<byte>) |
The hostname is rejected. The port is kept. |
TrySetPort(ReadOnlySpan<byte>) |
The port is not a number in range |
TrySetPathname(ReadOnlySpan<byte>) |
The path is rejected |
| Method | Effect |
|---|---|
SetSearch(ReadOnlySpan<byte>) |
Replaces the query. A leading ? is optional. |
SetHash(ReadOnlySpan<byte>) |
Replaces the fragment. A leading # is optional. |
ClearSearch() |
Removes the query |
ClearHash() |
Removes the fragment |
ClearPort() |
Removes the port |
using var url = AdaUrl.Parse("https://example.com/path?a=1#top"u8);
url.TrySetHostname("example.org"u8); // https://example.org/path?a=1#top
url.TrySetHost("example.net:8080"u8); // https://example.net:8080/path?a=1#top
url.TrySetPort("abc"u8); // false, URL unchanged
url.TrySetProtocol("http"u8); // http://example.net:8080/path?a=1#top
url.SetSearch("b=2"u8); // http://example.net:8080/path?b=2#top
url.ClearPort(); // http://example.net/path?b=2#topTrySetHref re-parses into the instance you already have, which skips a native allocation per
URL. It matters most on Windows. See
performance.
using var url = AdaUrl.Parse(urls[0]);
foreach (byte[] next in urls)
{
if (!url.TrySetHref(next)) continue;
Consume(url.Hostname);
}Dispose() frees the native URL. Calling it twice is safe.
Ada.Url
API reference
Links