-
Notifications
You must be signed in to change notification settings - Fork 9
Home
Sönke Ludwig edited this page Nov 5, 2017
·
1 revision
- baseline API with no dynamic per-request memory allocations
- layered on top is a (more or less) 0.8.1 compatible high level API, using structs instead of classes to enable a
scoped
API without requiring all users to addscope
to their request handlers - keep a straight forward API (i.e. no indirect abstractions "IRequestWriter" or something like that)
- support letting a connection "sleep" (no task allocated while waiting for the next request)
- one task per request/response (mostly important for HTTP/2)
- per-request memory must be safely managed (scoped and .dup'ed as soon as the user tries to escape it, either explicitly or implicitly)
- HTTP/2 support must be developed within the existing license/copyright boundaries
- no stream proxy objects or dynamic dispatch by default - all combinations of encryption/encoding/compression streams must be instantiated as static types
- need to keep in mind how to minimize the amount of template bloat this produces
This would be a possible approach for a low-level API with the goal of being as safe/robust, while avoiding any non-stack allocations.
- process request URL and method
- process request headers
- read request body
- write response code
- write response headers
- write response body
struct HTTPInterchange {
struct HeaderReader {
@disable this(this);
BodyReader readHeaders(alias on_header)();
}
struct BodyReader {
@disable this(this);
ResponseWriter readBody(alias on_data)();
}
struct ResponseWriter {
@disable this(this);
HeaderWriter writeResponse(HTTPStatus status);
}
struct HeaderWriter {
@disable this(this);
}
HeaderReader readRequest(alias on_request)();
}
void handler(HTTPInterchange req)
{
req
.readRequest((method, scope uri) {
})
.readHeaders((scope name, scope value) {
})
.readBody((scope data) {
})
.writeResponse(HTTPStatus.ok)
.writeHeader("Set-Cookie", "foo=bar")
.writeHeader("Content-Type", "text/plain")
.writeBody((dst) {
dst.write("Hello, World!");
});
}
// return HTTPServerResponse object?
// multi-match router? what happens if first route has consumed the request, but didn't write a response?
A drawback of this approach is that each API call would have to determine the static stream type all over again (e.g. ChunkedOutputStream(TLSStream(TCPConnection))
).