mod_esi(3erl)

πŸ’… mod_esi β€” Erlang Server Interface (yes that's ESI, and yes it slays)

Okay bestie, so this page is the mod_esi manual from inets (the Erlang module definition doc, obvs) πŸŽ€ β€” it's the whole Erlang Server Interface API, and lowkey it's the glow-up version of writing Erlang scripts for your Inets web server: instead of doing common CGI scripts like a peasant, you do ESI. It's literally more efficient, no cap ✨


🌸 DESCRIPTION 🌸

This module defines the Erlang Server Interface (ESI) API. It's a more efficient way of writing Erlang scripts for your Inets web server than writing them as common CGI scripts.

Periodt. That's the whole flex πŸ’…


πŸ¦‹ DATA TYPES πŸ¦‹

So these are the data types used in the functions for mod_esi, keep up bestie:

env() = :

{EnvKey()::atom(), Value::term()}

Currently supported key/value pairs β€” the whole squad 🫢

  • {server_software, string()} β€” tells you the inets version.
  • {server_name, string()} β€” the local hostname.
  • {gateway_interface, string()} β€” legacy string used in CGI, just ignore it, it's giving old money and nobody cares πŸ™ˆ
  • {server_protocol, string()} β€” HTTP version, currently "HTTP/1.1".
  • {server_port, integer()} β€” the server's port number.
  • {request_method, "GET | "PUT" | "DELETE" | "POST" | "PATCH"} β€” the HTTP request method.
  • {remote_adress, inet:ip_address()} β€” the client's IP address. (Yes that's spelled remote_adress, we don't fix it, we respect it πŸ’€)
  • {peer_cert, undefined | no_peercert | DER:binary()} β€” for TLS connections where client certificates are used, this is an ASN.1 DER-encoded X509-certificate as an Erlang binary. If client certificates aren't used, the value is no_peercert, and if TLS isn't used (HTTP, or the connection got lost due to network failure) the value is undefined. Iconic little trio.
  • {script_name, string()} β€” the request URI.
  • {http_LowerCaseHTTPHeaderName, string()} β€” example: {http_content_type, "text/html"}.

✨ EXPORTS ✨

🌈 deliver(SessionID, Data) -> ok | {error, Reason}

Types bestie:

SessionID = term()
Data = string() | io_list() | binary()
Reason = term()

This function is only intended to be used from functions called by the Erl Scheme interface to deliver parts of the content to the user 🫢 It sends data from an Erl Scheme script back to the client.

⚠️ Note (read this, seriously): if any HTTP header fields are added by the script, they must be in the first call to deliver/2, and the data in that call must be a string. Calls after the headers are complete can contain binary data to reduce copying overhead. Do not assume anything about the data type of SessionID. SessionID must be the value given as input to the ESI callback function that you implemented. Like, must must. πŸ™

🧚 ESI CALLBACK FUNCTIONS 🧚

πŸ‘‘ EXPORTS πŸ‘‘

⭐ Module:Function(SessionID, Env, Input)-> {continue, State} | _

Types, gather round:

SessionID = term()
Env = env()
Input = string() | chunked_data()
chunked_data() = {first, Data::binary()} | {continue,
Data::binary(), State::term()} | {last, Data::binary(),
State::term()}
State = term()

Module must be found in the code path and export Function with an arity of three. An erlScriptAlias must also be set up in the configuration file for the web server β€” no alias, no entry, that's the vibe check πŸ’…

mod_esi:deliver/2 shall be used to generate the response to the client, and SessionID is an identifier that shall be used when calling this function β€” do not assume anything about the datatype, fr fr. This function may be called several times to chunk the response data. Notice that the first chunk of data sent to the client must at least contain all HTTP header fields that the response will generate. If the first chunk does not contain the end of HTTP header β€” that is, "\r\n\r\n" β€” the server assumes that no HTTP header fields will be generated. So like… don't forget your \r\n\r\n, bestie 😭

Env is the environment data of the request, see description above πŸ‘†

Input is the query data of a GET request or the body of a PUT or POST request. The default behavior (legacy reasons, we don't judge) for delivering the body is that the whole body is gathered and converted to a string. But if the httpd config parameter max_client_body_chunk is set, the body will be delivered as binary chunks instead. The maximum size of the chunks is either max_client_body_chunk or decided by the client if it uses HTTP chunked encoding to send the body. When using the chunking mechanism this callback must return {continue, State::term()} for all calls where Input is {first, Data::binary()} or {continue, Data::binary(), State::term()}. When Input is {last, Data::binary(), State::term()} the return value will be ignored β€” like, literally ignored, don't stress about it 🫢

⚠️ Note: if the body is small, all data may be delivered in only one chunk, and then the callback will be called with {last, Data::binary(), undefined} without getting called with {first, Data::binary()}. Yeah. Sneaky. Watch for it πŸ‘€

The input State is the last returned State β€” in it the callback can include any data that it needs to keep track of when handling the chunks. State stays carrying the group chat, periodt πŸ’–


And that's the whole page, bestie β€” go forth and serve some ESI scripts ✨ This adorable little doc drop is brought to you by Ericsson AB, running inets 8.3.1.2, in the mod_esi(3erl) era. Slay! πŸ’…πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from