data URI(scheme: String, userinfo: String?, host: String?, port: Int?, path: String, query: String?, fragment: String?)

URIs: require "uri". A URI is a reference split as RFC 3986's generic syntax splits it (appendix B), with reference resolution (§5.2) and the percent-encodings of a component and of a form.

require "uri"
u = URI.parse("https://example.com:8443/a/b?x=1#top")
u.host                          # => "example.com"
u.port                          # => 8443
u.path                          # => "/a/b"
u.resolve("../c").to_s          # => "https://example.com:8443/c"
URI.encode_component("a b/c")   # => "a%20b%2Fc"

The parts are kept as they were written (percent-encoded, in their case): there is no normalization, no IDNA, and nothing scheme-specific beyond the default ports.

<std:uri>:18

Constants

SPLIT: Regexp

RFC 3986 appendix B. :nodoc:

<std:uri>:38

Class methods

def self.parse(text: String) -> URI

text split into its parts. Raises ArgumentError when it does not parse: a scheme that is not a letter followed by letters, digits, +, - and ., a port that is not digits (up to 65535), or an IPv6 literal's brackets unbalanced or holding something else (a colon in a host is an IPv6 address's, in brackets). Anything else is taken as it is.

URI.parse("http://[::1]:8080/").host     # => "::1"
URI.parse("/a?b").query                  # => "b"
URI.parse("mailto:a@example.com").path   # => "a@example.com"
URI.parse("1http://x")                   # raises ArgumentError

<std:uri>:55

def self.encode_component(text: String) -> String

text with every byte but the unreserved characters of RFC 3986 (letters, digits, -, ., _, ~) percent-encoded, its UTF-8 bytes in upper-case hexadecimal: one path segment, query name or value.

URI.encode_component("a b&c/é")   # => "a%20b%26c%2F%C3%A9"

<std:uri>:261

def self.decode_component(text: String) -> String

text with its percent-encoded bytes decoded (a % not followed by two hexadecimal digits is left as it is). Raises ArgumentError when the bytes are not UTF-8.

URI.decode_component("a%20b%2Fc")   # => "a b/c"
URI.decode_component("100%")        # => "100%"

<std:uri>:271

def self.encode_www_form(params: Hash[String, String | Array[String]]) -> String

params as an application/x-www-form-urlencoded text (a query or a form body): name=value pairs joined by &, a name given several values once per value, a space as +, and every byte but letters, digits, *, -, . and _ percent-encoded.

URI.encode_www_form({"q" => "a b", "tag" => ["x", "y&z"]})   # => "q=a+b&tag=x&tag=y%26z"

<std:uri>:285

def self.decode_www_form(text: String) -> Hash[String, Array[String]]

The pairs of an application/x-www-form-urlencoded text, each name with its values in order (+ decodes as a space). A name or value that does not decode to UTF-8 is kept as written.

URI.decode_www_form("q=a+b&tag=x&tag=y%26z")   # => {"q" => ["a b"], "tag" => ["x", "y&z"]}

<std:uri>:302

Methods

def scheme -> String

The scheme, as written ("https"); "" for a relative reference.

<std:uri>:20

def userinfo -> String?

The user information before @ in the authority, nil when none.

<std:uri>:22

def host -> String?

The host, nil when there is no authority; an IPv6 literal without its brackets ("::1").

<std:uri>:25

def port -> Int?

The port, nil when absent.

<std:uri>:27

def path -> String

The path, as written ("" when empty).

<std:uri>:29

def query -> String?

The query, without its ?; nil when there is none ("" for a bare ?).

<std:uri>:32

def fragment -> String?

The fragment, without its #; nil when there is none.

<std:uri>:34

def to_h -> Hash[Symbol, Object]

The fields as a Hash, by name.

<std:uri>:38

def with(*, scheme: String = …, userinfo: String? = …, host: String? = …, port: Int? = …, path: String = …, query: String? = …, fragment: String? = …) -> URI

A copy with the fields given replaced.

<std:uri>:38

def to_s -> String

The reference written back (RFC 3986 §5.3): an IPv6 host in brackets.

URI.parse("http://u@[::1]:80/p?q#f").to_s   # => "http://u@[::1]:80/p?q#f"

<std:uri>:119

def inspect -> String

#<URI http://example.com/>.

<std:uri>:143

def absolute? -> Bool

Whether it has a scheme (it is not a relative reference).

<std:uri>:146

def default_port -> Int?

The port a client uses when none is given: 80 for http and ws, 443 for https and wss, nil for another scheme.

<std:uri>:150

def origin -> String

scheme://host[:port], the scheme and host in lower case (ASCII letters only) and the port only when it is not the default one: two URLs of one origin give the same text. Raises ArgumentError without a scheme or a host.

URI.parse("HTTPS://Example.com:443/a").origin   # => "https://example.com"
URI.parse("http://[::1]:8080/").origin          # => "http://[::1]:8080"

<std:uri>:167

def resolve(reference: String) -> URI

reference resolved against this URI (RFC 3986 §5.2.2, with the dot segments removed, §5.2.4): what a link or a Location header refers to. Raises ArgumentError when this URI is not absolute or reference does not parse.

base = URI.parse("http://a/b/c/d;p?q")
base.resolve("../g").to_s    # => "http://a/b/g"
base.resolve("?y").to_s      # => "http://a/b/c/d;p?y"
base.resolve("//h/x").to_s   # => "http://h/x"

<std:uri>:198