http
The http
module provides a rich library to help in building HTTP
clients and servers. The module also provides a few generic abstractions
for simple HTTP operations such as a GET request and supports basic
routing.
Examples
The example below shows making a GET request to fetch a webpage.
import http
echo http.get('http://example.com')
# <class HttpResponse instance at 0x600002adacd0>
There is a post()
and put()
alternative to the get()
method called
above and they are documented below.
For a more controlled HTTP request, you should use the HttpClient class. Below is an example of such implementation that sets the timeout for receiving response back from the server to 30 seconds.
import http
var client = http.HttpClient()
client.receive_timeout = 30000 # Optional
var res = client.send_request('http://example.com/endpoint?query=1', 'GET')
echo res.body.to_string()
Creating a server with the http
module is also a breeze.
The example below shows an implementation of an HTTP API server listening on port
3000 and simple returns the JSON of the request object itself.
import http
import json
var server = http.server(3000)
server.handle('GET', '/', @(request, response) {
response.json(request)
})
server.listen()
Not only is it super simple to create an HTTP server, it is also very easy to create a TLS/HTTPS server with few modifications.
The following code creates a TLS version of the same server we created above.
import http
import json
var server = http.tls_server(3000)
if server.load_certs('/path/to/tlscert.crt', '/path/to/tlskey.key') {
server.handle('GET', '/', @(request, response) {
response.json(request)
})
server.listen()
}
To create a TLS server, we use the tls_server()
alternative to the server()
function
and load our certificates before we start to listen for incoming connections. It's that
simple.
The http
module client does make some basic assumption as to the type of data to be
sent in request bodies and for this reason, it will (unless asked not to) automatically
convert dictionaries into JSON objects and create multipart/form-data request for you.
Natively, the http
module will automatically encode and decode requests with the
following content types:
- multipart/form-data
- application/x-www-form-urlencoded
- application/json
In the absence of any content-type in the request header or response header from a
server as the case may be, the module defaults to the application/x-www-form-urlencoded
content type.
That been said, it gives the tools required to craft any request body of your choice.
Fields
- http.CONTINUE ➝ readonly int
- 100 continue.
- http.SWITCHING_PROTOCOLS ➝ readonly int
- 101 switching protocols.
- http.PROCESSING ➝ readonly int
- 102 processing.
- http.OK ➝ readonly int
- 200 ok.
- http.CREATED ➝ readonly int
- 201 created.
- http.ACCEPTED ➝ readonly int
- 202 accepted.
- http.NON_AUTHORITATIVE_INFORMATION ➝ readonly int
- 203 non authoritative information.
- http.NO_CONTENT ➝ readonly int
- 204 no content.
- http.RESET_CONTENT ➝ readonly int
- 205 reset content.
- http.PARTIAL_CONTENT ➝ readonly int
- 206 partial content.
- http.MULTI_STATUS ➝ readonly int
- 207 multi status.
- http.ALREADY_REPORTED ➝ readonly int
- 208 already reported.
- http.IM_USED ➝ readonly int
- 226 im used.
- http.MULTIPLE_CHOICES ➝ readonly int
- 300 multiple choices.
- http.MOVED_PERMANENTLY ➝ readonly int
- 301 moved permanently.
- http.FOUND ➝ readonly int
- 302 found.
- http.SEE_OTHER ➝ readonly int
- 303 see other.
- http.NOT_MODIFIED ➝ readonly int
- 304 not modified.
- http.USE_PROXY ➝ readonly int
- 305 use proxy.
- http.TEMPORARY_REDIRECT ➝ readonly int
- 307 temporary redirect.
- http.PERMANENT_REDIRECT ➝ readonly int
- 308 permanent redirect.
- http.BAD_REQUEST ➝ readonly int
- 400 bad request.
- http.UNAUTHORIZED ➝ readonly int
- 401 unauthorized.
- http.PAYMENT_REQUIRED ➝ readonly int
- 402 payment required.
- http.FORBIDDEN ➝ readonly int
- 403 forbidden.
- http.NOT_FOUND ➝ readonly int
- 404 not found.
- http.METHOD_NOT_ALLOWED ➝ readonly int
- 405 method not allowed.
- http.NOT_ACCEPTABLE ➝ readonly int
- 406 not acceptable.
- http.PROXY_AUTHENTICATION_REQUIRED ➝ readonly int
- 407 proxy authentication required.
- http.REQUEST_TIMEOUT ➝ readonly int
- 408 request timeout.
- http.CONFLICT ➝ readonly int
- 409 conflict.
- http.GONE ➝ readonly int
- 410 gone.
- http.LENGTH_REQUIRED ➝ readonly int
- 411 length required.
- http.PRECONDITION_FAILED ➝ readonly int
- 412 precondition failed.
- http.PAYLOAD_TOO_LARGE ➝ readonly int
- 413 payload too large.
- http.REQUEST_URI_TOO_LONG ➝ readonly int
- 414 request uri too long.
- http.UNSUPPORTED_MEDIA_TYPE ➝ readonly int
- 415 unsupported media type.
- http.REQUESTED_RANGE_NOT_SATISFIABLE ➝ readonly int
- 416 requested range not satisfiable.
- http.EXPECTATION_FAILED ➝ readonly int
- 417 expectation failed.
- http.TEAPOT ➝ readonly int
- 418 teapot.
- http.MISDIRECTED_REQUEST ➝ readonly int
- 421 misdirected request.
- http.UNPROCESSABLE_ENTITY ➝ readonly int
- 422 unprocessable entity.
- http.LOCKED ➝ readonly int
- 423 locked.
- http.FAILED_DEPENDENCY ➝ readonly int
- 424 failed dependency.
- http.UPGRADE_REQUIRED ➝ readonly int
- 426 upgrade required.
- http.PRECONDITION_REQUIRED ➝ readonly int
- 428 precondition required.
- http.TOO_MANY_REQUESTS ➝ readonly int
- 429 too many requests.
- http.REQUEST_HEADER_FIELDS_TOO_LARGE ➝ readonly int
- 431 request header fields too large.
- http.CONNECTION_CLOSED_WITHOUT_RESPONSE ➝ readonly int
- 444 connection closed without response.
- http.UNAVAILABLE_FOR_LEGAL_REASONS ➝ readonly int
- 451 unavailable for legal reasons.
- http.CLIENT_CLOSED_REQUEST ➝ readonly int
- 499 client closed request.
- http.INTERNAL_SERVER_ERROR ➝ readonly int
- 500 internal server error.
- http.NOT_IMPLEMENTED ➝ readonly int
- 501 not implemented.
- http.BAD_GATEWAY ➝ readonly int
- 502 bad gateway.
- http.SERVICE_UNAVAILABLE ➝ readonly int
- 503 service unavailable.
- http.GATEWAY_TIMEOUT ➝ readonly int
- 504 gateway timeout.
- http.HTTP_VERSION_NOT_SUPPORTED ➝ readonly int
- 505 http version not supported.
- http.VARIANT_ALSO_NEGOTIATES ➝ readonly int
- 506 variant also negotiates.
- http.INSUFFICIENT_STORAGE ➝ readonly int
- 507 insufficient storage.
- http.LOOP_DETECTED ➝ readonly int
- 508 loop detected.
- http.NOT_EXTENDED ➝ readonly int
- 510 not extended.
- http.NETWORK_AUTHENTICATION_REQUIRED ➝ readonly int
- 511 network authentication required.
- http.NETWORK_CONNECT_TIMEOUT_ERROR ➝ readonly int
- 599 network connect timeout error.
- http.map ➝ readonly dictionary
- A map of status code to their string representation..
Functions
- http.set_headers(headers)
-
Sets the default request headers for the current module instance.
This function returns HttpClient in order to allow for idiomatic chaining such as:
import http echo http.set_headers({ 'Authorization': 'Bearer SomeAPIBearerToken', 'Host': 'example.com', }).get('http://example.com/current-user').body.to_string()
- @params:
- dict headers
- @returns: HttpClient
- @raises:
- Exception
- @params:
- http.get(url, headers)
-
Sends an Http GET request and returns an HttpResponse or throws one of SocketException or Exception if it fails.
- @params:
- string url
- dict? headers
- @returns: HttpResponse
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- http.post(url, data, headers)
-
Sends an Http POST request and returns an HttpResponse.
- @params:
- string url
- string|bytes|nil data
- dict? headers
- @returns: HttpResponse
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- http.put(url, data, headers)
-
Sends an Http PUT request and returns an HttpResponse.
- @params:
- string url
- string|bytes|nil data
- dict? headers
- @returns: HttpResponse
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- http.patch(url, data, headers)
-
Sends an Http PATCH request and returns an HttpResponse.
- @params:
- string url
- string|bytes|nil data
- dict? headers
- @returns: HttpResponse
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- http.delete(url, headers)
-
Sends an Http DELETE request and returns an HttpResponse.
- @params:
- string url
- dict? headers
- @returns: HttpResponse
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- http.options(url, headers)
-
Sends an Http OPTIONS request and returns an HttpResponse.
- @params:
- string url
- dict? headers
- @returns: HttpResponse
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- http.trace(url, headers)
-
Sends an Http TRACE request and returns an HttpResponse.
- @params:
- string url
- dict? headers
- @returns: HttpResponse
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- http.head(url, headers)
-
Sends an Http HEAD request and returns an HttpResponse.
- @params:
- string url
- dict? headers
- @returns: HttpResponse
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- http.client()
-
Returns the default shared client.
- @returns: HttpClient
- http.server(port, address)
-
Creates an new HttpServer instance.
- @params:
- int port
- string address
- @returns: HttpServer
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- http.tls_server(port, host)
-
Creates an new TLSServer instance.
@throws Exception, SocketException, HttpException
- @params:
- int port
- string? host
- @returns: TLSServer
- @params:
Classes
- class HttpRequest
-
Http request handler and object.
@printable, @serializable
- .request_uri ➝ string
-
The original request URL as sent in the raw request.
- .path ➝ string
-
The requested path or file. E.g. if the Request URI is
/users?sort=desc
, then the path is/users
. - .method ➝ string
-
The HTTP method of the request: GET (the default), POST, PUT, etc.
- .host ➝ string
-
The hostname derived from the
Host
header or the first instance ofX-Forwarded-Host
if set. - .ip ➝ string
-
The IP address of the remote client that initiated the request.
- .ipv6 ➝ string
-
The IPv6 address of the remote client that initiated the request.
- .headers ➝ dictionary
-
A dictionary containing the headers sent with the request.
- .queries ➝ dictionary
-
A dictionary containing the entries of the URI query string.
-
A list or dictionary containing the cookies sent with the request.
- .body ➝ dictionary
-
A dictionary containing all data submitted in the request body.
- .files ➝ dictionary
-
A dictionary containing the data of all files uploaded in the request.
- .http_version ➝ string
-
The HTTP version used for the request.
- .parse(raw_data, client)
-
Parses a raw HTTP request string into a correct HttpRequest.
- @params:
- string raw_data
- Socket|TLSSocket|nil client
- @returns: boolean
- @params:
- .send(uri, method, data, headers, options)
-
Send HTTP requests to the given uri for the given method and data (if given).
- @params:
- url uri
- string method
- string|bytes|dict|nil data
- dict? headers
- dict? options
- @params:
- .to_string()
-
Returns the request as a string.
- .to_json()
-
Returns the request as a JSON object.
- class HttpException < Exception
-
HTTP related Exceptions.
@printable
- class HttpServer
-
HTTP server.
@printable
- .host ➝ string
-
The host address to which this server will be bound. Default value is socket.IP_LOCAL (127.0.0.1)
- .port ➝ number
-
The port to which this server will be bound to on the host.
- .socket ➝ socket.Socket
-
The working Socket instance for the HttpServer.
- .reuse_address ➝ bool
-
A boolean value indicating whether to reuse socket addresses or not. Default value is
true
. - .read_timeout ➝ number
-
The timeout in milliseconds after which an attempt to read clients request data will be terminated. Default value is 2,000 (2 seconds).
- .write_timeout ➝ number
-
The timeout in milliseconds after which an attempt to write response data to clients will be terminated.
If we cannot send response to a client after the stipulated time, it will be assumed such clients have disconnected and existing connections for that client will be closed and their respective sockets will be discarded. Default value is 2,000 (2 seconds).
- .HttpServer(port, host) ➝ Constructor
-
http.HttpServer constructor
- @params:
- int port
- string? host
- @params:
- .close()
-
Stops the server.
- .on_connect(function)
-
Adds a function to be called when a new client connects.
@notes:
- Function function MUST accept at one parameter which will be passed the client Socket object.
- Multiple
on_connect()
may be set on a single instance.
- @params:
- function(1) function
- .on_disconnect(function)
-
Adds a function to be called when a new client disconnects.
@notes:
- Function function MUST accept at one parameter which will be passed the client.
- Multiple
on_disconnect()
may be set on a single instance.
- @params:
- function(1) function
- .on_receive(handler)
-
Adds a function to be called when the server receives a message from a client.
Function fn MUST accept TWO parameters. First parameter will accept the HttpRequest object and the second will accept the HttpResponse object.
@notes:
- Multiple
on_receive()
may be set on a single instance.
- @params:
- function(2) handler
- Multiple
- .on_reply(function)
-
Adds a function to be called when the server sends a reply to a client.
Function function MUST accept one parameter which will be passed the HttpResponse object.
@notes:
- Multiple
on_sent()
may be set on a single instance.
- @params:
- function(1) function
- Multiple
- .on_error(function)
-
Adds a function to be called when the server encounters an error with a client.
Function function MUST accept two parameters. The first argument will be passed the
Exception
object and the second will be passed the clientSocket
object.@notes:
- Multiple
on_error()
may be set on a single instance.
- @params:
- function(2) function
- Multiple
- .handle(method, path, handler)
-
Sets up a request handler that will be called when a request with the given method has a path that matches the one specified.
If the path ends with a
/
, it also matches all routes that starts with the path so long as there is no other path that matches the request better. The exception to this is when the path is an ordinary/
(root path) in which case it won't match any other route except for the root path.For example, if the path is declared as
/user/
, it will match the request for/user/record/1
unless another handle has been registered for/user/record
in which case the handle for/user/record
will handle the request since it is the handler for the closest path.- @params:
- string method
- string path
- function(2) handler
- @params:
- .none_handler(handler)
-
Sets up the handle to invoke when a request is not processed. That is, when it does not match a registered route and no
on_receive()
handler is set.- @params:
- function(2) handler
- @params:
- .serve_files(base_path, directory, cache_age, tag)
-
Setup the given base_path to serve static files from the given directory. If cache is set to true, and a default value is not set for tag, static file tagging will be automatically enabled.
- @params:
-
string base_path
-
string directory
-
number? cache_age = 0
-
bool? tag = false
-
- @params:
- .listen()
-
Binds to the instance port and host and starts listening for incoming connection from HTTP clients.
- class TLSServer < HttpServer
-
TLS server
@printable
- .cert_file ➝ string
-
The SSL/TLS certificate file that will be used be used by a secured server for serving requests.
- .private_key_file ➝ string
-
The SSL/TLS private key file that will be used be used by a secured server for serving requests.
- .verify_certs ➝ boolean
-
This value controls whether the client certificate should be verified or not.
- .TLSServer(port, host) ➝ Constructor
-
http.TLSServer constructor
- @params:
- int port
- string? host
- @params:
- .load_certs(cert_file, private_key_file)
-
Loads the given SSL/TLS certificate pairs for the given SSL/TLS context.
- @params:
- string|file cert_file
- string|file|nil private_key_file
- @returns: bool
- @params:
- .listen()
-
Binds to the instance port and host and starts listening for incoming connection from HTTPS clients.
- class HttpClient
-
Handles http requests.
@note This client do not currently support the compress, deflate and gzip transfer encoding.
- .user_agent ➝ string
-
The user agent of the client used to make the request. Default value —
Blade HTTP Client/1.0
. - .follow_redirect ➝ bool
-
Indicates if we receive a redirect from a server, this flag tells us whether we should follow it or not. Default value is
true
. - .verify_hostname ➝ bool
-
Indicates if the site you're connecting to uses a different host name that what they have mentioned in their server certificate's commonName (or subjectAltName) fields, connection will fail. You can skip this check by setting to true, but this will make the connection less secure.
- .verify_peer ➝ bool
-
Indicates if you want to connect to a site who isn't using a certificate that is signed by one of the certs in the CA bundle you have, you can skip the verification of the server's certificate. This makes the connection A LOT LESS SECURE.
- .referer ➝ string
-
The site that refers us to the current site
- .ca_cert ➝ string
-
If you have a CA cert for the server stored someplace else than in the default bundle.
- .connect_timeout ➝ number
-
The connect timeout duration in milliseconds. Default value is 60,000 (1 minute).
- .receive_timeout ➝ number
-
The receive timeout duration in milliseconds. Default value is 2,000 (2 seconds).
- .headers ➝ dict
-
A dictionary of headers sent along with the request.
- .no_expect ➝ bool
-
Indicates whether to remove the expect header or not only applies to requests with files in the body
- .HttpClient(base_url) ➝ Constructor
-
If the base_url param is set, all calls to HTTP method functions will automatically prepend requested url with the base url if they do not start with the base url.
- @params:
- string? base_url The base url for the HTTP client requests
- @params:
- .send_request(uri, method, data, headers, options)
-
Sends an Http request and returns a HttpResponse.
This can be very useful if you want to reuse the same instance for multiple requests and headers scenarios.
- @params:
-
string uri
-
string? method Default value is
GET
. -
string|dict|nil data
-
dict? headers To override the instance options.
-
dict? client request options
-
- @returns: HttpResponse
- @raises:
- SocketException
- Exception
- @params:
- .get(url, headers)
-
Sends an Http GET request and returns an HttpResponse.
- @params:
- string url
- dict? headers
- @returns: HttpResponse
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- .post(url, data, headers)
-
Sends an Http POST request and returns an HttpResponse.
- @params:
- string url
- string|bytes|nil data
- dict? headers
- @returns: HttpResponse
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- .put(url, data, headers)
-
Sends an Http PUT request and returns an HttpResponse.
- @params:
- string url
- string|bytes|nil data
- dict? headers
- @returns: HttpResponse
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- .patch(url, data, headers)
-
Sends an Http PATCH request and returns an HttpResponse.
- @params:
- string url
- string|bytes|nil data
- dict? headers
- @returns: HttpResponse
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- .delete(url, headers)
-
Sends an Http DELETE request and returns an HttpResponse.
- @params:
- string url
- dict? headers
- @returns: HttpResponse
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- .options(url, headers)
-
Sends an Http OPTIONS request and returns an HttpResponse.
- @params:
- string url
- dict? headers
- @returns: HttpResponse
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- .trace(url, headers)
-
Sends an Http TRACE request and returns an HttpResponse.
- @params:
- string url
- dict? headers
- @returns: HttpResponse
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- .head(url, headers)
-
Sends an Http HEAD request and returns an HttpResponse.
- @params:
- string url
- dict? headers
- @returns: HttpResponse
- @raises:
- Exception
- SocketException
- HttpException
- @params:
- class HttpResponse
-
Represents the response to an Http request.
@printable, @serializable
- .version ➝ string
-
The HTTP version of the response
- .status ➝ number
-
The HTTP response status code
- .headers ➝ dictionary
-
The HTTP response headers
- .time_taken ➝ number
-
Total time taken for the HTTP request that generated this HttpResponse to complete
- .redirects ➝ number
-
The number of times the HTTP request that generated this HttpResponse was redirected.
- .responder ➝ string
-
The final URL that provided the HttpResponse. This will sometimes differ from the original request URI.
- .body ➝ bytes
-
The content of the HTTP response as bytes
-
The cookies to be sent back to the client
- .certificate ➝ dict|nil
-
The SSL certificate for the secure connection. This is only available when visiting HTTPS/SSL/TLS secured websites.
- .HttpResponse(body, status, headers, cookies, version, time_taken, redirects, responder) ➝ Constructor
-
http.HttpResponse constructor
- @params:
- string body
- int status
- dict headers
- list[string] cookies
- string version
- number time_taken
- int redirects
- string responder
- @params:
- .write(data)
-
Writes data to the response stream.
This method should be preferred over writing directly to the body property to prevent unexpected behaviors.
- @params:
- string|bytes data
- @params:
- .json(data, status_code)
-
Writes a json encoded data to the response stream and sets the response
Content-Type
toapplication/json
. If the status code is given, the response will be sent with the given status code.- @params:
- any data
- number? status_code
- @params:
- .file(path, status_code)
-
Writes a file into the response stream and sets the
Content-Type
to the correct mimetype for the file. If the status code is given, the response will be sent with the given status code.- @params:
- string path
- number? status_code
- @params:
-
Sets a cookie to be send back to a client with the given key and value. When other parameters are given, they are used to construct a correct Set-Cookie header based on their named properties.
- @params:
- string key
- string value
- string? domain
- string? path
- string? expires
- bool? secure
- string? extras
- @params:
- .redirect(location, status)
-
Redirects the client to a new location. This function simultaneously sets the
Location
header and returns a 30x status code. If thestatus
parameter is not given, the function defaults to302
.@throw HttpException
@notes:
- When supplying a status, it must be a 30x
- @params:
- string location
- string? status
- .render(path, variables)
-
A shorthand method that renders a template using Blade's template module default settings. Follow the template module documentation to know more about setting up your project to render from templates.
NOTE*
The default template root directory is a directory called "templates" in the current working directory. To use render, ensure that the directory exists as the template instance used for
render()
does not have theauto_init
parameter set to true. This is intentional to discourage misuse and/or unintended behaviors. Support for template rendering in HttpResponse class is lazy loaded and will not be enabled until the first attempt to render a template. This helps reduce the overhead for use cases where rending is never needed.- @params:
- string path
- dict? variables
- @params:
- .content_type(mimetype)
-
Sets the content type of the HTTP response.
- @params:
- string mimetype
- @params:
- .to_string()
-
Returns the response details in a string
- .as_text()
-
Returns the body of an HTTP response as a string or an empty string if the response is empty.
- @returns: string
- .as_dict()
-
Returns the body of an HTTP response as a dictionary.
NOTE:*
Call this method only if you're certain that the response is a JSON response or have set the header
Accepts
and/orContent-Type
to accept onlyapplication/json
responses only because the method will raise and Exception if the response does not contain a valid JSON in the body.- @returns: string
- @raises:
- Exception
- .to_json()
-
Returns the response as a JSON object