http
HTTP handling framework
Import
_ <- fat.http
Route
A route is a structure used to map HTTP methods to certain path patterns, specifying what code should be executed when a request comes in. Each route can define a different behavior for each HTTP method (POST
, GET
, PUT
, DELETE
).
Constructor
Name | Signature | Brief |
---|---|---|
Route | (path: Text, post: Method, get: Method, put: Method, delete: Method) | Constructs a Route object |
each implemented method receives an HttpRequest as argument and shall return an HttpResponse object
HttpRequest
An HttpRequest
represents an HTTP request message. This is what your server receives from a client when it makes a request to your server.
Constructor
Name | Signature | Brief |
---|---|---|
HttpRequest | (method: Text, path: Text, headers: List, params: Scope, body: Any) | Constructs an HttpRequest object |
the items
params
andbody
may be omitted depending on the request received
HttpResponse
An HttpResponse
represents an HTTP response message. This is what a server sends back to the client in response to an HTTP request.
Constructor
Name | Signature | Brief |
---|---|---|
HttpResponse | (status: Number, headers: List/Text, body: Any) | Constructs an HttpResponse object |
for client mode responses,
body
will be provided asText
if a textual MIME type can be found in theheaders
, otherwise it will be provided asChunk
Methods
Name | Signature | Brief |
---|---|---|
setHeaders | (headers: List): Void | Set headers of requests |
post | (url: Text, body, wait): HttpResponse | Create/post body to url |
get | (url: Text, wait): HttpResponse | Read/get from url |
put | (url: Text, body, wait): HttpResponse | Update/put body to url |
delete | (url: Text, wait): HttpResponse | Delete on url |
setName | (name: Text): Void | Set user agent/server name |
verifySSL | (enabled: Boolean): Void | SSL configuration (client mode) |
setSSL | (certPath: Text, keyPath: Text): Void | SSL configuration (server mode) |
listen | (port: Number, routes: List/Route, maxMs) | Endpoint provider (server mode) |
body: Any
andwait: Number
are always optional parameters, being that ifbody
does not fall underText
orChunk
, it will be automatically converted to JSON during the send process, andwait
is the maximum waiting time and the default is 30,000ms (30 seconds)
verifySSL
is enabled by default for the client mode
setSSL
may not be available, case the system doesn't have OpenSSL
Usage Notes
Client mode
In the HttpResponse.body
, you may need to explicitly parse a JSON response to Scope
using the fromJSON
method. To post a native type as JSON, you can encode it using the toJSON
method; however, this is not strictly necessary, as it will be done implicitly. Both methods are available in the fat.recode library.
If headers are not set, the default Content-Type
header for Chunk
will be application/octet-stream
, for Text
will be text/plain; charset=UTF-8
and for other types, it will be application/json; charset=UTF-8
(due to implicit conversion).
You can set custom request headers like so:
http <- fat.http
url = ...
token = ...
body = ...
http.setHeaders([
"Accept: application/json; charset=UTF-8"
"Content-Type: application/json; charset=UTF-8"
"Authorization: Bearer " + token # custom header
])
http.post(url, body)
setting headers will completely replace previous list with new list
When performing async requests, you may need to call setHeaders
, setName
, and configure verifySSL
within each Worker, as these settings are local to each thread.
Server mode
Handling HTTP Responses
You can define the maxMs
optional parameter, when calling listen
to restrict how long the server will wait for each request to transfer its contents (inbound connection), returning status 408 if exceeded.
The FatScript server automatically handles common HTTP status codes such as 200, 400, 404, 405, 408, 500, and 501. Being 200 the default when constructing an HttpResponse
object.
In addition to the common status codes, you can also explicitly return other status codes, such as 201, 202, 203, 204, 205, 301, 401, and 403, by specifying the status code in the HttpResponse
object, for example: HttpResponse(status = 401)
. For all codes mentioned here, the server provides default plain text bodies. However, you have the option to override these defaults and provide your own custom response bodies when necessary.
By automatically handling these status codes and providing default response bodies, the FatScript server simplifies the development process while still allowing you to have control over the response content when needed.
if the status code doesn't belong to any of the above, the server will return a 500 code
See an example of a simple file HTTP server:
_ <- fat.std
# adapt to content location
directory = '/home/user/contentFolder'
# restrict to some extensions only
mediaTypesByExtension = {
htm = html = 'text/html'
js = 'application/javascript'
json = 'application/json'
css = 'text/css'
md = 'text/markdown'
xml = 'application/xml'
csv = 'text/csv'
txt = 'text/plain'
svg = 'image/svg+xml'
rss = 'application/rss+xml'
atom = 'application/atom+xml'
png = 'image/png'
jpg = jpeg = 'image/jpeg'
gif = 'image/gif'
ico = 'image/x-icon'
webp = 'image/webp'
woff = 'font/woff'
woff2 = 'font/woff2'
}
routes: List/Route = [
Route(
'*'
get = (request: HttpRequest): HttpResponse -> {
path = file.resolve(directory + request.path) # sanitized path
type = path & path.startsWith(directory) # jailed access
? mediaTypesByExtension(path.split('.')(-1))
path.isEmpty => HttpResponse(status = 404) # not found
type.isEmpty => HttpResponse(status = 403) # forbidden
_ => HttpResponse(
status = 200
headers = [ 'Content-Type: {type}' ]
body = file.readBin(path)
)
}
)
]
http.listen(8080, routes)
use
http.listen(0, routes)
to start a server with an auto-assigned port number, and check the actual port assigned to the server through the$port
embedded command