ASGI, and further work related to www Amirouche Boubekki 15 Jun 2020 05:31 UTC

I read through the ASGI specification again (and again).  It seems to
cover many use-cases including HTTP, WebSockets and HTTP2 and possibly
other protocols.

The goal of the ASGI protocol is to have a common ground to build web
servers, middlewares, and applications that speak HTTP. One can
imagine using an ASGI server that only speaks HTTP1 and later switches
to another server that also speaks HTTP2 without changing the code of
the application.

The idea is the following:

(application scope receive send)

Where SCOPE is metadata about the accepted connection like IP, port,
the implementation of the ASGI server, and possibly more things. In
Python, it is a dictionary mapping. RECEIVE is a coroutine that allows
us to read new messages from the socket. SEND allows us to send
messages to the socket. As far as I understand, depending on the
actual ASGI implementation and the middlewares, RECEIVE and SEND can
respectively return and accept raw bytes or higher-level data types,
and might be stateful. That is one can imagine the following scenario:

(define-values http-code uri http-version (receive))

(define headers (receive))  ;; returns a mapping

(define request (make-request http-code uri headers))

(match (uri-split-component (request-uri request))
  (("admin" model action) (send 403 "Forbidden") (send some-request-body)))

Still, some things remain to be explored:

- What would be the content of SCOPE e.g. can it contain the raw socket?
- In the case of HTTP, what would be the values returned by RECEIVE
- In the case of HTTP, what would be the values accepted by SEND

That is the say, as at the moment the current ASGI specification says
something along the lines:

> an ASGI application will be a nesting of procedures that take a mapping, an accumulator, and a generator as arguments.

The A in ASGI is Asynchronous, but in Scheme, both asynchronous and
synchronous can be supported with the same interface. Also, so far, I
did not see the socket exposed in the application procedure.

The initial microbenchmarks of my tiny asynchronous HTTP server yield
more than 10K requests per second, so it allows me to think that it
can be useful (even if it relies on call/cc (or possibly something
more efficient)).

Anyway, here is a TODO:

1) Continue to explore ASGI, there are several servers and frameworks.
And take a look at WSGI which is the previous more mature standard.

2) Continue to explore sockets as generators and accumulators

3) Start to refresh the code of htmlprag, it is an HTML parser in
scheme. By the way, I am wondering whether an HTML DOM API would be

4) Start to implement microxml based on the work of Oleg Kiselyov on
XML, the idea here is that there are still many (legacy) services that
rely on XML.

5) Start to explore how to control a headless browser from Scheme,
that will be a requirement if one wants to do web stuff

6) Start an SRFI about parsing and using URIs, that may seem trivial, it is not.

7) Start an SRFI about an HTTP client

8) Finalize SRFI-180 (JSON)

Regarding 3 and 4, one might create a single SXML SRFI and include
among other things sxml->html and sxml->xml. There is no SXML SRFI, as
of yet.

Regarding 1 HTTP Server and 7 the HTTP Client, as far as know there is
no existing portable test suite, so probably getting together a test
suite based on existing open-source projects might be the first step
(and it seems easier to me to go through unit tests, that any
specification document).

Have a good day!