Перейти к содержимому
Топаз6.0 · До релиза
Загрузка →

Поиск в документации

Спецификация 6.0

Выберите результат стрелками и нажмите Enter, чтобы открыть его.

Введите имя API, номер диагностики, правило или тему проекта.

    Библиотека

    std.url

    Parse URLs and inspect URL components.

    API этого модуля

    7 API

    ИмяМодуль
    URL.fragment →std.url →
    URL.host →std.url →
    URL.parse →std.url →
    URL.path →std.url →
    URL.query →std.url →
    URL.scheme →std.url →
    URL.toString →std.url →

    Module

    Ссылка

    URL.parse constructs immutable absolute URLs. Read serialized components or inspect decoded query fields, then use toString to serialize the complete URL.

    Structured URLs preserve component boundaries and use one parsing model for links and general resource identifiers.

    Availability

    Ссылка

    Import std.url in language mode 5.21. The current compiler selects std/url.tpz for this language mode. Availability in other released editions and inclusion in each installed distribution are Pending.

    Exported types

    Ссылка

    export type URL = URL

    Type members keep the compiler-owned type name shown in their declarations. Importing a module does not create a new type identity.

    Public API

    Ссылка

    URL.fragment →

    URL.host →

    URL.parse →

    URL.path →

    URL.query →

    URL.scheme →

    URL.toString →

    Pending contracts

    Ссылка

    Parse and serialize absolute URLs

    Ссылка
    Правилоtopaz.stdlib.contract.url-parse.rule

    Parse and serialize absolute URLs

    URL.parse takes a string and applies the WHATWG URL parser with UTF-8 input and no base URL. A successful parse returns Ok containing an immutable URL. Relative references need a base and therefore return Err.

    A parser failure returns Err containing a nonempty string. Missing or invalid schemes, invalid hosts, and ports outside 0 through 65535 fail. Error wording is explanatory text and has no fixed spelling.

    URL preprocessing removes leading and trailing code points from U+0000 through U+0020. It then removes U+0009, U+000A, and U+000D throughout the input. Other characters are processed by the URL parser. A validation warning that permits parsing does not become an Err.

    Schemes use lowercase. Special-scheme domain hosts use ASCII domain serialization. Default ports disappear and hierarchical dot segments are removed. Opaque paths retain their distinct path interpretation.

    The default ports are 21 for ftp, 80 for http and ws, and 443 for https and wss. Other valid ports survive serialization as decimal integers. The file scheme has no port.

    URL.toString serializes every stored component. It preserves user information, nondefault ports, query order, and explicit empty query and fragment delimiters. Existing percent escapes retain their spelling. Newly escaped characters use percent-encoded UTF-8 bytes with uppercase hexadecimal digits.

    Parsing the serialization produces the same serialization and component values. Reading a URL does not modify it. Parsing evaluates its argument once before validation and performs no network or filesystem operation.

    Причина

    A single established parser gives URL text one interpretation. Parsing without a hidden base makes acceptance independent of the working directory and browser location. Stable serialization keeps resource identifiers reusable in text and typeset links.

    Normalize the scheme, host, port, and path

    Ссылка
    main.tpzNormalize the scheme, host, port, and pathОткрыть песочницу →
    1. import std.url { URL }
    2. import std.io
    3. match (URL.parse("HTTPS://Example.COM:443/a/./b/../c?x=1#part")) {
    4. case Ok(value) => io.writeLine(value.toString())
    5. case Err(_) => io.writeLine("parse failed")
    6. }
    Ожидаемый выводКод завершения 0
    https://example.com/a/c?x=1#part
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. https://example.com/a/c?x=1#part

    Handle invalid absolute URL text as data

    Ссылка
    main.tpzHandle invalid absolute URL text as dataОткрыть песочницу →
    1. import std.url { URL }
    2. import std.io
    3. for text in (["", "../guide", "1bad:x", "https://", "https://example.com:wrong"]) {
    4. match (URL.parse(text)) {
    5. case Err(message) => io.writeLine("{message != ""}")
    6. case Ok(_) => io.writeLine("accepted")
    7. }
    8. }
    Ожидаемый выводКод завершения 0
    true
    true
    true
    true
    true
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. true
    2. true
    3. true
    4. true
    5. true

    Check both port boundaries and the first invalid port

    Ссылка
    main.tpzCheck both port boundaries and the first invalid portОткрыть песочницу →
    1. import std.url { URL }
    2. import std.io
    3. for text in (["https://example.com:0", "https://example.com:65535", "https://example.com:65536"]) {
    4. match (URL.parse(text)) {
    5. case Ok(value) => io.writeLine(value.toString())
    6. case Err(_) => io.writeLine("invalid port")
    7. }
    8. }
    Ожидаемый выводКод завершения 0
    https://example.com:0/
    https://example.com:65535/
    invalid port
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. https://example.com:0/
    2. https://example.com:65535/
    3. invalid port

    Apply URL preprocessing and escape a path space

    Ссылка
    main.tpzApply URL preprocessing and escape a path spaceОткрыть песочницу →
    1. import std.url { URL }
    2. import std.io
    3. match (URL.parse(" \thttps://EXAMPLE.com/a b\n")) {
    4. case Ok(value) => io.writeLine(value.toString())
    5. case Err(_) => io.writeLine("parse failed")
    6. }
    Ожидаемый выводКод завершения 0
    https://example.com/a%20b
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. https://example.com/a%20b

    Preserve serialized escapes and empty components through parsing

    Ссылка
    main.tpzPreserve serialized escapes and empty components through parsingОткрыть песочницу →
    1. import std.url { URL }
    2. import std.io
    3. for text in (["https://example.com/a%2fb?x=%2b#p%2fq", "https://example.com/?#"]) {
    4. match (URL.parse(text)) {
    5. case Ok(value) => {
    6. io.writeLine(value.toString())
    7. match (URL.parse(value.toString())) {
    8. case Ok(again) => io.writeLine(again.toString())
    9. case Err(_) => io.writeLine("second parse failed")
    10. }
    11. }
    12. case Err(_) => io.writeLine("first parse failed")
    13. }
    14. }
    Ожидаемый выводКод завершения 0
    https://example.com/a%2fb?x=%2b#p%2fq
    https://example.com/a%2fb?x=%2b#p%2fq
    https://example.com/?#
    https://example.com/?#
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. https://example.com/a%2fb?x=%2b#p%2fq
    2. https://example.com/a%2fb?x=%2b#p%2fq
    3. https://example.com/?#
    4. https://example.com/?#

    Evaluate the input once before reporting a parse error

    Ссылка
    main.tpzEvaluate the input once before reporting a parse errorОткрыть песочницу →
    1. import std.url { URL }
    2. import std.io
    3. function inputText() -> string {
    4. io.writeLine("input")
    5. return "../chapter"
    6. }
    7. match (URL.parse(inputText())) {
    8. case Err(_) => io.writeLine("invalid URL")
    9. case Ok(_) => io.writeLine("accepted")
    10. }
    Ожидаемый выводКод завершения 0
    input
    invalid URL
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. input
    2. invalid URL

    Reject a forbidden domain character

    Ссылка
    main.tpzReject a forbidden domain characterОткрыть песочницу →
    1. import std.url { URL }
    2. import std.io
    3. match (URL.parse("https://exa[mple.com/")) {
    4. case Err(_) => io.writeLine("invalid host")
    5. case Ok(_) => io.writeLine("accepted")
    6. }
    Ожидаемый выводКод завершения 0
    invalid host
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. invalid host

    Read serialized URL components and their absence

    Ссылка
    Правилоtopaz.stdlib.contract.url-components.rule

    Read serialized URL components and their absence

    URL.scheme returns the lowercase scheme without its delimiter. URL.host returns Some containing the serialized host without user information or a port. IPv6 hosts include their square brackets.

    A URL whose host is absent returns None() from URL.host. A present empty host returns Some containing an empty string. A local file URL can have that empty host.

    URL.path returns the serialized path without the query or fragment. A hierarchical path retains its leading slash. An opaque path has no implied slash. Percent escapes stay encoded so an escaped slash remains path data.

    URL.fragment returns None() when there is no fragment delimiter. An explicit empty fragment returns Some containing an empty string. A present fragment excludes its delimiter and retains percent encoding.

    Scheme, host, path, and fragment inspection cannot fail after construction. Each receiver is evaluated once. The returned strings are immutable and inspection has no external effects.

    Read URL.query for decoded query fields. URL.path and URL.fragment do not apply query decoding. In particular, a plus sign in those components remains a plus sign.

    Причина

    Component access must preserve delimiters as data and distinguish absence from an empty component. Encoded path and fragment values can be placed back into a URL without turning an escaped separator into structure.

    Read encoded URL components without decoding delimiters

    Ссылка
    main.tpzRead encoded URL components without decoding delimitersОткрыть песочницу →
    1. import std.url { URL }
    2. import std.io
    3. match (URL.parse("HTTPS://EXAMPLE.COM:8443/a%2Fb?q=a+b#x%20y")) {
    4. case Ok(value) => {
    5. io.writeLine(value.scheme())
    6. match (value.host()) {
    7. case Some(host) => io.writeLine(host)
    8. case None() => io.writeLine("no host")
    9. }
    10. io.writeLine(value.path())
    11. match (value.fragment()) {
    12. case Some(fragment) => io.writeLine(fragment)
    13. case None() => io.writeLine("no fragment")
    14. }
    15. io.writeLine(value.toString())
    16. }
    17. case Err(_) => io.writeLine("parse failed")
    18. }
    Ожидаемый выводКод завершения 0
    https
    example.com
    /a%2Fb
    x%20y
    https://example.com:8443/a%2Fb?q=a+b#x%20y
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. https
    2. example.com
    3. /a%2Fb
    4. x%20y
    5. https://example.com:8443/a%2Fb?q=a+b#x%20y

    Distinguish an absent fragment from an empty fragment

    Ссылка
    main.tpzDistinguish an absent fragment from an empty fragmentОткрыть песочницу →
    1. import std.url { URL }
    2. import std.io
    3. for text in (["mailto:reader@example.com", "mailto:reader@example.com#"]) {
    4. match (URL.parse(text)) {
    5. case Ok(value) => {
    6. io.writeLine(value.scheme())
    7. match (value.host()) {
    8. case None() => io.writeLine("no host")
    9. case Some(host) => io.writeLine("host={host}")
    10. }
    11. io.writeLine(value.path())
    12. match (value.fragment()) {
    13. case None() => io.writeLine("no fragment")
    14. case Some(fragment) => io.writeLine("fragment={fragment}")
    15. }
    16. io.writeLine("{value.query().length}")
    17. }
    18. case Err(_) => io.writeLine("parse failed")
    19. }
    20. }
    Ожидаемый выводКод завершения 0
    mailto
    no host
    reader@example.com
    no fragment
    0
    mailto
    no host
    reader@example.com
    fragment=
    0
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. mailto
    2. no host
    3. reader@example.com
    4. no fragment
    5. 0
    6. mailto
    7. no host
    8. reader@example.com
    9. fragment=
    10. 0

    Read IPv6 and file hosts without losing authority data

    Ссылка
    main.tpzRead IPv6 and file hosts without losing authority dataОткрыть песочницу →
    1. import std.url { URL }
    2. import std.io
    3. for text in (["https://u:p@[2001:DB8::1]:443/", "file:///tmp/a"]) {
    4. match (URL.parse(text)) {
    5. case Ok(value) => {
    6. match (value.host()) {
    7. case Some(host) => io.writeLine("host={host}")
    8. case None() => io.writeLine("no host")
    9. }
    10. io.writeLine(value.toString())
    11. }
    12. case Err(_) => io.writeLine("parse failed")
    13. }
    14. }
    Ожидаемый выводКод завершения 0
    host=[2001:db8::1]
    https://u:p@[2001:db8::1]/
    host=
    file:///tmp/a
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. host=[2001:db8::1]
    2. https://u:p@[2001:db8::1]/
    3. host=
    4. file:///tmp/a

    Serialize a Unicode domain, path, and fragment

    Ссылка
    main.tpzSerialize a Unicode domain, path, and fragmentОткрыть песочницу →
    1. import std.url { URL }
    2. import std.io
    3. match (URL.parse("https://bücher.example/한#α")) {
    4. case Ok(value) => {
    5. match (value.host()) {
    6. case Some(host) => io.writeLine(host)
    7. case None() => io.writeLine("no host")
    8. }
    9. io.writeLine(value.path())
    10. match (value.fragment()) {
    11. case Some(fragment) => io.writeLine(fragment)
    12. case None() => io.writeLine("no fragment")
    13. }
    14. io.writeLine(value.toString())
    15. }
    16. case Err(_) => io.writeLine("parse failed")
    17. }
    Ожидаемый выводКод завершения 0
    xn--bcher-kva.example
    /%ED%95%9C
    %CE%B1
    https://xn--bcher-kva.example/%ED%95%9C#%CE%B1
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. xn--bcher-kva.example
    2. /%ED%95%9C
    3. %CE%B1
    4. https://xn--bcher-kva.example/%ED%95%9C#%CE%B1

    Decode query fields into an independent map

    Ссылка
    Правилоtopaz.stdlib.contract.url-query.rule

    Decode query fields into an independent map

    URL.query returns a new Map from decoded names to arrays of decoded values. A missing query and an empty query both produce an empty map.

    Query decoding follows application/x-www-form-urlencoded parsing. Ampersands separate fields. Empty fields between separators are skipped. The first equals sign separates each name from its value. A field without that sign has an empty value.

    An explicit empty name is retained. A plus sign decodes to an ASCII space. Valid percent escapes decode to bytes and those bytes decode as UTF-8. Malformed percent escapes remain literal text and invalid UTF-8 sequences use the replacement character.

    Repeated names are grouped after decoding. Values retain encounter order. Map keys retain the order in which their decoded names first appear. No sorting, deduplication, or comma splitting occurs.

    The returned Map and its value arrays follow collection value semantics. URL.toString preserves the stored serialized query rather than serializing this map.

    Reading a query evaluates its receiver once and performs no external operation. A constructed URL can always produce its query map. Query decoding does not return a diagnostic or a Result error.

    Причина

    Query syntax has its own escaping rules and permits repeated names. Grouped arrays preserve every value while immutable URLs keep query inspection from silently rewriting a link.

    Decode repeated query fields and preserve their value order

    Ссылка
    main.tpzDecode repeated query fields and preserve their value orderОткрыть песочницу →
    1. import std.url { URL }
    2. import std.io
    3. match (URL.parse("https://example.com/?q=a+b&q=%ED%95%9C&empty&x=a=b&=blank")) {
    4. case Ok(value) => {
    5. let fields = value.query()
    6. for name in (["q", "empty", "x", ""]) {
    7. match (fields.get(name)) {
    8. case Some(values) => {
    9. for item in (values) {
    10. io.writeLine("{name}={item}")
    11. }
    12. }
    13. case None() => io.writeLine("missing")
    14. }
    15. }
    16. }
    17. case Err(_) => io.writeLine("parse failed")
    18. }
    Ожидаемый выводКод завершения 0
    q=a b
    q=한
    empty=
    x=a=b
    =blank
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. q=a b
    2. q=한
    3. empty=
    4. x=a=b
    5. =blank

    Skip empty separators while retaining an explicit empty field

    Ссылка
    main.tpzSkip empty separators while retaining an explicit empty fieldОткрыть песочницу →
    1. import std.url { URL }
    2. import std.io
    3. for text in (["https://example.com/", "https://example.com/?", "https://example.com/?&&a=1&&", "https://example.com/?="]) {
    4. match (URL.parse(text)) {
    5. case Ok(value) => {
    6. let fields = value.query()
    7. let hasEmptyName = fields.containsKey("")
    8. io.writeLine("{fields.length}:{hasEmptyName}")
    9. }
    10. case Err(_) => io.writeLine("parse failed")
    11. }
    12. }
    Ожидаемый выводКод завершения 0
    0:false
    0:false
    1:false
    1:true
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 0:false
    2. 0:false
    3. 1:false
    4. 1:true

    Keep malformed percent escapes as query data

    Ссылка
    main.tpzKeep malformed percent escapes as query dataОткрыть песочницу →
    1. import std.url { URL }
    2. import std.io
    3. for text in (["https://example.com/?x=%", "https://example.com/?x=%GG"]) {
    4. match (URL.parse(text)) {
    5. case Ok(value) => {
    6. match (value.query().get("x")) {
    7. case Some(values) => io.writeLine(values[0])
    8. case None() => io.writeLine("missing")
    9. }
    10. }
    11. case Err(_) => io.writeLine("parse failed")
    12. }
    13. }
    Ожидаемый выводКод завершения 0
    %
    %GG
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. %
    2. %GG

    Replace an invalid decoded UTF-8 byte in a query field

    Ссылка
    main.tpzReplace an invalid decoded UTF-8 byte in a query fieldОткрыть песочницу →
    1. import std.url { URL }
    2. import std.io
    3. match (URL.parse("https://example.com/?x=%ff")) {
    4. case Ok(value) => {
    5. match (value.query().get("x")) {
    6. case Some(values) => io.writeLine(values[0])
    7. case None() => io.writeLine("missing")
    8. }
    9. io.writeLine(value.toString())
    10. }
    11. case Err(_) => io.writeLine("parse failed")
    12. }
    Ожидаемый выводКод завершения 0
    �
    https://example.com/?x=%ff
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. �
    2. https://example.com/?x=%ff

    Mutate a query snapshot without changing its URL

    Ссылка
    main.tpzMutate a query snapshot without changing its URLОткрыть песочницу →
    1. import std.url { URL }
    2. import std.io
    3. match (URL.parse("https://example.com/?k=first")) {
    4. case Ok(value) => {
    5. let mut snapshot = value.query()
    6. snapshot.insert("k", ["changed", "again"])
    7. snapshot.insert("extra", ["local"])
    8. let reread = value.query()
    9. io.writeLine("{reread.length}")
    10. match (reread.get("k")) {
    11. case Some(values) => {
    12. for item in (values) {
    13. io.writeLine(item)
    14. }
    15. }
    16. case None() => io.writeLine("missing")
    17. }
    18. io.writeLine(value.toString())
    19. }
    20. case Err(_) => io.writeLine("parse failed")
    21. }
    Ожидаемый выводКод завершения 0
    1
    first
    https://example.com/?k=first
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 1
    2. first
    3. https://example.com/?k=first

    Меню

    Загрузка →