LuaSocket
Network support for the Lua language

home · download · installation · introduction · reference


URL

The url namespace provides functions to parse, protect, and build URLs, as well as functions to compose absolute URLs from base and relative URLs, according to RFC 2396.

To obtain the url namespace, run:

-- loads the URL module
local url = require("socket.url")

An URL is defined by the following grammar:

<url> ::= [<scheme>:][//<authority>][/<path>][;<params>][?<query>][#<fragment>]
<authority> ::= [<userinfo>@]<host>[:<port>]
<userinfo> ::= <user>[:<password>]
<path> ::= {<segment>/}<segment>

url.absolute(base, relative)

Builds an absolute URL from a base URL and a relative URL.

Base is a string with the base URL or a parsed URL table. Relative is a string with the relative URL.

The function returns a string with the absolute URL.

Note: The rules that govern the composition are fairly complex, and are described in detail in RFC 2396. The example bellow should give an idea of what the rules are.

http://a/b/c/d;p?q

+

g:h      =  g:h
g        =  http://a/b/c/g
./g      =  http://a/b/c/g
g/       =  http://a/b/c/g/
/g       =  http://a/g
//g      =  http://g
?y       =  http://a/b/c/?y
g?y      =  http://a/b/c/g?y
#s       =  http://a/b/c/d;p?q#s
g#s      =  http://a/b/c/g#s
g?y#s    =  http://a/b/c/g?y#s
;x       =  http://a/b/c/;x
g;x      =  http://a/b/c/g;x
g;x?y#s  =  http://a/b/c/g;x?y#s
.        =  http://a/b/c/
./       =  http://a/b/c/
..       =  http://a/b/
../      =  http://a/b/
../g     =  http://a/b/g
../..    =  http://a/
../../   =  http://a/
../../g  =  http://a/g

url.build(parsed_url)

Rebuilds an URL from its parts.

Parsed_url is a table with same components returned by parse. Lower level components, if specified, take precedence over high level components of the URL grammar.

If host is not set, the host is taken from whichever single one of hostname, ipv4 or ipv6 is set (hosttype is ignored when building). It is an error to set more than one of hostname, ipv4 or ipv6 while host is absent.

The function returns a string with the built URL.

url.build_path(segments, unsafe)

Builds a <path> component from a list of <segment> parts. Before composition, any reserved characters found in a segment are escaped into their protected form, so that the resulting path is a valid URL path component.

Segments is a list of strings with the <segment> parts. If unsafe is anything but nil, reserved characters are left untouched.

The function returns a string with the built <path> component.

url.classify_host(host)

Classifies a raw <host> string into "name", "ipv4" or "ipv6". This is the same classification parse uses to fill in hosttype, exposed for callers that have a host string to classify without a full URL to parse.

Host is a host string as found in a URL's authority. Any : in host is taken as a sign of an IPv6 literal, so the enclosing [...] brackets URLs normally require for one are optional here: they are stripped when present, but classification does not depend on them.

The function returns two values: hosttype, one of "name", "ipv4" or "ipv6"; and host, the input with any enclosing [...] brackets stripped, if present.

Note: classification is done by exclusion of shape, not by validating the address. A host is "ipv4" if it merely has the shape of four dot-separated digit groups — octet ranges are not checked, so "999.1.1.1" classifies as "ipv4" — and "ipv6" if it merely contains a :, whether or not that is a well-formed IPv6 address. Anything left over is "name", whether or not it is actually a valid hostname.

-- load url module
url = require("socket.url")

print(url.classify_host("example.com"))
-- name    example.com

print(url.classify_host("192.168.1.1"))
-- ipv4    192.168.1.1

print(url.classify_host("[::1]"))
-- ipv6    ::1

print(url.classify_host("::1"))
-- ipv6    ::1

url.escape(content)

Applies the URL escaping content coding to a string Each byte is encoded as a percent character followed by the two byte hexadecimal representation of its integer value.

Content is the string to be encoded.

The function returns the encoded string.

-- load url module
url = require("socket.url")

code = url.escape("/#?;")
-- code = "%2f%23%3f%3b"

url.parse(url, default)

Parses an URL given as a string into a Lua table with its components.

Url is the URL to be parsed. If the default table is present, it is used to store the parsed fields. Only fields present in the URL are overwritten. Therefore, this table can be used to pass default values for each field.

The function returns a table with all the URL components:

parsed_url = {
  url = string,
  scheme = string,
  authority = string,
  path = string,
  params = string,
  query = string,
  fragment = string,
  userinfo = string,
  host = string,
  hosttype = string,
  hostname = string,
  ipv4 = string,
  ipv6 = string,
  port = string,
  user = string,
  password = string
}

When a host is present, hosttype is set to one of "name", "ipv4" or "ipv6", describing the syntax of host. Exactly one of hostname, ipv4 or ipv6 is then also set to the same value as host, matching hosttype — the other two are left nil. In case of an ipv6 address the brackets are stripped, both in host and ipv6. This classification is done by classify_host, by exclusion of shape rather than by validating the address (see its notes).

-- load url module
url = require("socket.url")

parsed_url = url.parse("http://www.example.com/cgilua/index.lua?a=2#there")
-- parsed_url = {
--   scheme = "http",
--   authority = "www.example.com",
--   path = "/cgilua/index.lua"
--   query = "a=2",
--   fragment = "there",
--   host = "www.puc-rio.br",
--   hosttype = "name",
--   hostname = "www.puc-rio.br",
-- }

parsed_url = url.parse("ftp://root:passwd@unsafe.org/pub/virus.exe;type=i")
-- parsed_url = {
--   scheme = "ftp",
--   authority = "root:passwd@unsafe.org",
--   path = "/pub/virus.exe",
--   params = "type=i",
--   userinfo = "root:passwd",
--   host = "unsafe.org",
--   user = "root",
--   password = "passwd",
-- }

url.parse_path(path)

Breaks a <path> URL component into all its <segment> parts.

Path is a string with the path to be parsed.

Since some characters are reserved in URLs, they must be escaped whenever present in a <path> component. Therefore, before returning a list with all the parsed segments, the function removes escaping from all of them.

url.unescape(content)

Removes the URL escaping content coding from a string.

Content is the string to be decoded.

The function returns the decoded string.