Event loop and callbacks#
LWHTTP never blocks unless you ask it to. A request is started with lwhttp_client_request() and then moves
forward whenever lwIP-CE reports socket activity. Those reports are delivered from lwhttp_service_events(),
which your program calls in its main loop.
The main loop#
Call lwhttp_service_events() instead of lwip_service_events(). It runs lwIP-CE’s own event processing and
then frees sockets that LWHTTP retired while it was inside a callback.
while (running) {
lwhttp_service_events();
draw_frame();
handle_keys();
}
Important
lwIP-CE delivers at most one queued event per socket per call, so call lwhttp_service_events() often. A
loop that does a lot of other work between calls makes transfers slower, not incorrect.
Lifecycle of a request#
lwhttp_client_request()validates the request, builds the request head and either reuses a kept-alive connection or opens a new one. Problems found here (bad arguments, a bad URL, an unsupported scheme, no memory) are returned directly and no callback is called.Once connected, the request head and body are written.
When the response head has been parsed,
on_responseruns. Status and headers are available throughlwhttp_client_status()andlwhttp_client_header().on_bodyruns for every piece of the body, already de-chunked.on_completeruns exactly once with the final result.
Redirects, interim 1xx responses and automatic retries happen inside this flow without extra callbacks.
Callback rules#
You may |
Details |
|---|---|
Start the next request from |
The client is idle again by then; a kept-alive connection is reused. |
Destroy the client from any callback |
|
Cancel from any callback |
|
Abort from |
Return |
You must not |
Why |
|---|---|
Keep |
They point into the client’s receive buffer and are reused immediately. |
Call |
They run the event loop themselves. |
Free request data before |
The |
Blocking wrappers#
lwhttp_client_wait() loops on lwhttp_service_events() until the current request has finished and
returns its result. lwhttp_client_request_sync() is lwhttp_client_request() followed by
lwhttp_client_wait(). Handlers are optional with both; pass NULL when the status and headers are all you
need.
if (lwhttp_client_request_sync(client, &request, NULL, NULL) == LWHTTP_OK) {
const char *type = lwhttp_client_header(client, "Content-Type");
}
Several clients#
Clients are independent. Each one runs a single request at a time, so run requests in parallel by creating several clients and driving them all from the same loop:
lwhttp_client_request(a, &first, &handlers, &state_a);
lwhttp_client_request(b, &second, &handlers, &state_b);
while (!state_a.done || !state_b.done) lwhttp_service_events();