LuaSocket
Network support for the Lua language

home · download · introduction · reference


HTTP

HTTP (Hyper Text Transfer Protocol) is the protocol used to exchange information between web-browsers and servers. The http.lua module offers support for the client side of the HTTP protocol (i.e., the facilities that would be used by a web-browser implementation). The implementation conforms to the HTTP/1.1 standard, RFC 2616.

The module exports functions that provide HTTP functionality in different levels of abstraction, from a simple get, to the generic, stream oriented request_cb.

URLs must conform to RFC 1738, that is, an URL is a string in the form:

[http://][<user>[:<password>]@]<host>[:<port>][/<path>] 

MIME headers are represented as a Lua table in the form:

headers = {
  field-1-name = field-1-value,
  field-2-name = field-2-value,
  field-3-name = field-3-value,
  ...
  field-n-name = field-n-value
}

Field names are case insensitive (as specified by the standard) and all functions work with lowercase field names. Field values are left unmodified.

Note: MIME headers are independent of order. Therefore, there is no problem in representing them in a Lua table.

socket.http.get(url)
socket.http.get{
  url = string,
  headers = header-table,
  user = string,
  password = string,
  stay = bool,
}

Performs the HTTP method GET.

The function can be called either directly with a url or with a request table. The use of a request table allows complete control over the components of the request. Values passed explicitly as fields of the request table override those given by the url. For a description of the fields, see the request function.

The function returns the response message body, the mime headers, the status code and an error message (if any). In case of failure, the function returns all information it managed to gather.

Note: The function is trivially implemented with the use of the request function.

-- connect to server "www.tecgraf.puc-rio.br" and retrieves this manual
-- file from "/luasocket/http.html"
b, h, c, e = socket.http.get("http://www.tecgraf.puc-rio.br/luasocket/http.html")

-- connect to server "www.tecgraf.puc-rio.br" and tries to retrieve
-- "~diego/auth/index.html". Fails because authentication is needed.
b, h, c, e = socket.http.get("http://www.tecgraf.puc-rio.br/~diego/auth/index.html")
-- b returns some useless page telling about the denied access, 
-- h returns authentication information
-- and c returns with value 401 (Authentication Required)

-- tries to connect to server "wrong.host" to retrieve "/"
-- and fails because the host does not exist.
b, h, c, e = socket.http.get("http://wrong.host/")
-- b, h, c are nil, and e returns with value "host not found"

socket.http.post(url, body)
socket.http.post{
   url = string,
   headers = header-table,
   body = string,
   user = string,
   password = string,
   stay = bool,
}

Same as get, except that the POST method is used and the request message body is sent along with the request.

Note: This function is also trivially implemented with the use of the request function.

socket.http.request{
  method = string,
  url = string,
  headers = header-table,
  body = string,
  user = string,
  password = string,
  stay = string,
}

Performs the generic HTTP request using.

The request uses method on url sending the request headers and request body in the request message. If authentication information is provided, the function uses the Basic Authentication Scheme (see note) to retrieve the document. User and password provided explicitly override those given by the url. The stay parameter, when set to anything but nil, prevents the function from automatically following 301 or 302 server redirect messages.

The function returns a table with all components of the response message it managed to retrieve. The response table has the following form:

response = {
  body = string,
  headers = header-table,
  status = string,
  code = number,
  error = string
}

Even when there was failure (URL not found, for example), the function may succeed retrieving a message body (a web page informing the URL was not found or some other useless page). To make sure the operation was successful, check the returned status code. For a list of the possible values and their meanings, refer to RFC 2616.

-- Requests information about a document, without downloading it.
-- Useful, for example, if you want to display a download gauge and need
-- to know the size of the document in advance
response = socket.http.request {
  method = "HEAD",
  url = "http://www.tecgraf.puc-rio.br/~diego"
}
-- Would return the following headers:
-- response.headers = {
--   date = "Tue, 18 Sep 2001 20:42:21 GMT",
--   server = "Apache/1.3.12 (Unix)  (Red Hat/Linux)",
--   ["last-modified"] = "Wed, 05 Sep 2001 06:11:20 GMT",
--   ["content-length"] = 15652,
--   ["connection"] = "close",
--   ["content-Type"] = "text/html"
-- }

Note: Some URLs are protected by their servers from anonymous download. For those URLs, the server must receive some sort of authentication along with the request or it will deny download and return status "401 Authentication Required".

The HTTP/1.1 standard defines two authentication methods: the Basic Authentication Scheme and the Digest Authentication Scheme, both explained in detail in RFC 2068.

The Basic Authentication Scheme sends <user> and <password> unencrypted to the server and is therefore considered unsafe. Unfortunately, by the time of this implementation, the wide majority of servers and browsers support the Basic Scheme only. Therefore, this is the method used by the toolkit whenever authentication is required.

-- Connect to server "www.tecgraf.puc-rio.br" and tries to retrieve
-- "~diego/auth/index.html", using the provided name and password to
-- authenticate the request
response = socket.http.request{
  url = "http://www.tecgraf.puc-rio.br/~diego/auth/index.html",
  user = "diego",
  password = "password"
}

-- Alternatively, one could fill the appropriate header and authenticate
-- the request directly.
headers = {
  authentication = "Basic " .. socket.code.base64("diego:password")
}
response = socket.http.request {
  url = "http://www.tecgraf.puc-rio.br/~diego/auth/index.html",
  headers = headers
}

socket.http.request_cb(request, response)

Performs the generic HTTP request.

The function receives two tables as parameters. The request table provides information about the request:

request = {
  method = string,
  url = string,
  headers = header-table,
  body_cb = send-callback,
  user = string,
  password = string,
  stay = string,
}

The function uses the HTTP method specified in request.method on the URL request.url, sending request.headers along with the request. The request message body is sent via the send callback request.body_cb. If authentication information is provided, the function uses the Basic Authentication Scheme (see note) to retrieve the document. Request.user and request.password override those given by the request.url. The request.stay parameter, when set to anything but nil, prevents the function from automatically following 301 or 302 server redirect messages.

The response table specifies information about the desired response:

response = {
  body_cb = receive-callback
}

The function returns the same response table as that returned by the socket.http.request function, except the response message body is returned to the receive callback given by the response.body_cb field.

Note: For more information on callbacks, please refer to Streaming with callbacks.

Note: Method names are case sensitive