|
KEEL 1.0.0
Minimal C11 HTTP client/server library built on epoll/kqueue/io_uring/poll
|


Go to the source code of this file.
Data Structures | |
| struct | KlMultipartPartMeta |
| struct | KlMultipartConfig |
Macros | |
| #define | KL_MP_MAX_BOUNDARY 70 |
| Streaming multipart/form-data parser. | |
Typedefs | |
| typedef struct KlMultipartReader | KlMultipartReader |
Functions | |
| KlBodyReader * | kl_body_reader_multipart (KlAllocator *alloc, const KlRequest *req, void *user_data) |
| Factory: produce a streaming multipart reader for a request. | |
| KlMultipartEvent | kl_multipart_next (KlBodyReader *br, KlMultipartPartMeta *meta, const char **data, size_t *data_len) |
| Advance the parser by one event. | |
| KlMultipartErrorCode | kl_multipart_last_error (const KlBodyReader *br) |
| Return the error code for the latest ERROR event. | |
| #define KL_MP_MAX_BOUNDARY 70 |
Streaming multipart/form-data parser.
The reader is a pull iterator on top of the framework's push-shaped body callback. Each call to kl_multipart_next() advances the parser by one event:
PART_BEGIN — headers parsed; meta is populated. The pointers in meta are owned by the reader and remain valid until the NEXT call to kl_multipart_next(). PART_DATA — a chunk of the current part body is available. *data / *data_len are populated with a borrowed slice of the internal input buffer. Valid until the next call. PART_END — the current part finished (boundary hit). No data. DONE — the closing boundary was seen. The reader is finished. NEED_DATA — input buffer drained; the caller should yield and wait for more bytes to arrive via on_data. ERROR — malformed input or a cap was exceeded. Call kl_multipart_last_error() for the specific code.
Caps: max_part_size — bytes of body per part. Exceeded → ERROR. max_total_size — total bytes received from the socket. max_parts — distinct parts; counted when PART_BEGIN is emitted. max_input_buffer — bytes the reader may hold internally. Exceeded means the framework delivered data faster than the handler consumed it. 0 = unlimited.
413 mapping: The factory returns NULL for non-multipart content types (→ 415). Any cap overflow during parsing causes kl_multipart_next() to return ERROR; the handler should respond 413. RFC 2046 maximum boundary length.
| typedef struct KlMultipartReader KlMultipartReader |
Opaque reader. Obtain via the factory; consume via kl_multipart_next.
| enum KlMultipartEvent |
| enum KlMultipartErrorCode |
Error codes reported by kl_multipart_last_error().
| KlBodyReader * kl_body_reader_multipart | ( | KlAllocator * | alloc, |
| const KlRequest * | req, | ||
| void * | user_data | ||
| ) |
Factory: produce a streaming multipart reader for a request.
Extracts boundary from Content-Type. Returns NULL if the content type is not multipart/form-data, the boundary is missing or too long, or allocation fails. NULL triggers a 415 response from the framework.
| alloc | Allocator used for all internal allocations. |
| req | Parsed request; Content-Type header must be set. |
| user_data | Optional KlMultipartConfig*; NULL → defaults. |
| KlMultipartEvent kl_multipart_next | ( | KlBodyReader * | br, |
| KlMultipartPartMeta * | meta, | ||
| const char ** | data, | ||
| size_t * | data_len | ||
| ) |
Advance the parser by one event.
| br | The body reader returned by the factory. |
| meta | On PART_BEGIN: populated with part metadata. Otherwise untouched. |
| data | On PART_DATA: set to a borrowed slice of the input buffer. Borrowed pointer is valid only until the NEXT mutation of the reader — that is, the next kl_multipart_next() call OR the next on_data callback. If your caller can yield to the framework's read loop while holding the slice (so on_data may fire), copy the bytes before yielding. |
| data_len | On PART_DATA: bytes in *data. |
meta and data may be NULL if the caller doesn't care about that variant.
| KlMultipartErrorCode kl_multipart_last_error | ( | const KlBodyReader * | br | ) |
Return the error code for the latest ERROR event.
| br | The body reader. |