Like JSGI, but using streams.
Like JSGI, but using streams for the request bodies.
An EJSGI Application is a JavaScript Function which takes exactly one argument, the Request as a JavaScript Object, and returns its Response as EITHER (a) a JavaScript Object with data relevant to the HTTP response, OR (b) a Promise which resolves to said object.
EJSGI Middleware are EJSGI applications that can call other EJSGI applications. Middleware can be stacked up into a call chain to provide useful services to Requests and Responses.
An EJSGI Server is the glue that connects EJSGI Applications to HTTP request and response messages.
The reference implementation is built on nodejs.
A promise is an object that exposes an addCallback
method. addCallback
takes a single function argument, which is called with the appropriate arguments when they're ready. For the purpose of EJSGI, this is the only required functionality, but servers MAY add additional features.
(IZS Maybe apps should just take a callback, and then we don't have to talk about promises at all? It'd make post-app middleware a lot simpler.)
Stream Objects are representations of a stream of data in an asynchronous evented paradigm.
Stream Objects have the following methods:
write
is called. Returns true
if the data could be written to the output stream immediately, or false
if the data was buffered for writing later. If it returns false
, then the caller can attach a listener to the drain
event to know when it's ready to receive more data.data
events. This is useful when a reader needs to throttle a stream of incoming data.data
events will begin firing again.Stream Objects emit the following events
write
eventually triggers a data
event. The argument is the data that was written.write()
call.pause
method.resume
method.Stream objects MUST implement some sort of "event queue" in order to defer callbacks until after the current execution context has exited. Specifically, the data
, end
, and drain
events MUST NOT be fired immediately on the corresponding calls to write()
, close()
, and resume()
.
All streams SHOULD be both readable and writeable. This allows for middleware to step into the flow and filter the input or output to/from an app. Of course, the underlying input and output streams may be read- or write-only.
The request environment MUST be an Object representative of an HTTP request. Applications are free to modify the Request.
The Request is required to have these keys:
scriptName
MUST start with "/", MUST NOT end with "/" and MUST NOT be decoded.pathInfo
MUST start with "/" and MUST NOT be decoded.queryString
key MUST NOT be undefined.scheme
. Restriction: MUST be non-empty String, MUST NOT contain a colon or slash. Note: when combined with scheme
, port
, scriptName
, pathInfo
, and queryString
this variable can be used to complete the URL. If not found in the request line, then the HOST
header, can be used. If not found in the HOST
header.host
is followed by a colon this is all digits following this colon. If not present in the request URL port
can be derived from the scheme
. Restriction: MUST NOT be undefined and MUST be an integer.headers
object. The presence or absence of these variables should correspond with the presence or absence of the appropriate HTTP header in the request. All keys in the headers
object MUST be the lower-case equivalent of the request's HTTP header keys. See: example requests for more details.jsgi
key:
env
key. Servers are encouraged to add any additional relevant data relating to the Request in a key in the env
object. Requirements: MUST be an object.The Request MAY contain contain these keys:
The Request body object is required to emit the following events at the appropriate time, in this order:
The app may call the following methods on the request body:
Applications MUST return a JavaScript object.
The Response is required to have these fields:
header
values supplied as Arrays. All keys MUST be lower-case. The headers
object MUST NOT contain a status
key and MUST NOT contain key names that end in -
or _
. It MUST contain keys that consist of letters, digits, _
or -
and start with a letter. Header values MUST NOT contain characters below 037. Additionally:
content-type
header key, except when the Status is 1xx, 204 or 3xx, in which case `content-type MUST NOT be present.content-length
header key when the Status is 1xx, 204 or 3xx.The application should call the following methods on the response body stream:
write
method, passing the data as an argument. This is optional; in cases where a response body is not appropriate, don't do it.close
the output stream. This signals the end of the connection. This event is optional; in cases where it is not appropriate to terminate the connection (such as long-polling comet connections), do not call it.0.0.4
- Add the return value from write()
, clarify the semantics of drain
, rename eof
to end
.0.0.3
- More JSGI compliance. At this point, it's ready to be written up as an extension.0.0.2
- Updated to use Streams instead of direct Emitters. (Makes the name make less sense, but the code make more sense.)0.0.1
- Initial pass.