Re: HTTP request handler / middleware SRFI
Lassi Kortela 05 Apr 2019 13:37 UTC
> I have a working SCGI implementation for both MIT and chez scheme
> (ported, not the same codebase, but only superficial differences).
>
> It is rather ugly code, but I've used it in production with both nginx
> and apache, and it seems to work fine. It is written purely in Scheme.
Great! Have you considered publishing the Chez version in Akku?
<https://akkuscm.org/>
> Headers are passed as alists, bodies as bytevectors / strings. This is
> not ideal, sometimes it would be better to be able to write content
> directly, but I haven't figured out how to properly do this *and*
> support custom headers nicely.
Do you mean that if the user's handler returns an alist of response
headers, then you need to ensure that it didn't write anything in the
body before the server gets the chance to write those headers?
Off the top of my head, here's a sketch:
(define (handler1 req)
"Hello world")
(define (handler2 req)
'(200
((content-type "text/plain"))
"Hello world"))
(define (handler3 req)
(append-header! req 'content-type "text/plain")
(flush-header req)
(append-to-body! req "Hello ")
(append-to-body! req "world")
#f)
So append-to-body! would cause an error unless flush-header has been
called on that request.
In addition, flush-header would be implicitly called after writing all
the headers from the handler's return value and before writing the body
from the return value.
> Also, there is no portable way to have
> custom ports in Scheme, so that makes things even harder :-/
Yeah, I ran into that issue with the archive file SRFI as well. I made
it so you can either pass a filename, a byte port, or an arbitrary
procedure that has an interface similar to read-bytevector! or
write-bytevector.
> I'd strongly suggest implementing this and getting it stable before
> writing an actual SRFI for it.
That is the plan :) But we'd need to get some momentum going and do it
with a view to eventually publishing an SRFI, hence have a draft spec
from the get go so we remember not to bake in assumptions about the
particular implementation strategies we happen to be using.