Skip to content

Commit 33c9039

Browse files
jsha0xE282B0
authored andcommitted
docs(ffi): add more documentation for the FFI API (hyperium#3424)
1 parent 89e8fe8 commit 33c9039

File tree

7 files changed

+316
-55
lines changed

7 files changed

+316
-55
lines changed

capi/include/hyper.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ typedef struct hyper_executor hyper_executor;
168168
typedef struct hyper_headers hyper_headers;
169169

170170
/*
171-
An IO object used to represent a socket or similar concept.
171+
A read/write handle for a specific connection.
172172
*/
173173
typedef struct hyper_io hyper_io;
174174

@@ -214,7 +214,7 @@ extern "C" {
214214
const char *hyper_version(void);
215215

216216
/*
217-
Create a new "empty" body.
217+
Creates a new "empty" body.
218218
*/
219219
struct hyper_body *hyper_body_new(void);
220220

@@ -224,12 +224,12 @@ struct hyper_body *hyper_body_new(void);
224224
void hyper_body_free(struct hyper_body *body);
225225

226226
/*
227-
Return a task that will poll the body for the next buffer of data.
227+
Creates a task that will poll a response body for the next buffer of data.
228228
*/
229229
struct hyper_task *hyper_body_data(struct hyper_body *body);
230230

231231
/*
232-
Return a task that will poll the body and execute the callback with each
232+
Creates a task to execute the callback with each body chunk received.
233233
*/
234234
struct hyper_task *hyper_body_foreach(struct hyper_body *body,
235235
hyper_body_foreach_callback func,
@@ -241,7 +241,7 @@ struct hyper_task *hyper_body_foreach(struct hyper_body *body,
241241
void hyper_body_set_userdata(struct hyper_body *body, void *userdata);
242242

243243
/*
244-
Set the data callback for this body.
244+
Set the outgoing data callback for this body.
245245
*/
246246
void hyper_body_set_data_func(struct hyper_body *body, hyper_body_data_callback func);
247247

@@ -266,13 +266,13 @@ size_t hyper_buf_len(const struct hyper_buf *buf);
266266
void hyper_buf_free(struct hyper_buf *buf);
267267

268268
/*
269-
Starts an HTTP client connection handshake using the provided IO transport
269+
Creates an HTTP client handshake task.
270270
*/
271271
struct hyper_task *hyper_clientconn_handshake(struct hyper_io *io,
272272
struct hyper_clientconn_options *options);
273273

274274
/*
275-
Send a request on the client connection.
275+
Creates a task to send a request on the client connection.
276276
*/
277277
struct hyper_task *hyper_clientconn_send(struct hyper_clientconn *conn, struct hyper_request *req);
278278

@@ -287,13 +287,13 @@ void hyper_clientconn_free(struct hyper_clientconn *conn);
287287
struct hyper_clientconn_options *hyper_clientconn_options_new(void);
288288

289289
/*
290-
Set the whether or not header case is preserved.
290+
Set whether header case is preserved.
291291
*/
292292
void hyper_clientconn_options_set_preserve_header_case(struct hyper_clientconn_options *opts,
293293
int enabled);
294294

295295
/*
296-
Set the whether or not header order is preserved.
296+
Set whether header order is preserved.
297297
*/
298298
void hyper_clientconn_options_set_preserve_header_order(struct hyper_clientconn_options *opts,
299299
int enabled);
@@ -310,12 +310,12 @@ void hyper_clientconn_options_exec(struct hyper_clientconn_options *opts,
310310
const struct hyper_executor *exec);
311311

312312
/*
313-
Set the whether to use HTTP2.
313+
Set whether to use HTTP2.
314314
*/
315315
enum hyper_code hyper_clientconn_options_http2(struct hyper_clientconn_options *opts, int enabled);
316316

317317
/*
318-
Set whether HTTP/1 connections will accept obsolete line folding for header values.
318+
Set whether HTTP/1 connections accept obsolete line folding for header values.
319319
*/
320320
enum hyper_code hyper_clientconn_options_http1_allow_multiline_headers(struct hyper_clientconn_options *opts,
321321
int enabled);
@@ -376,7 +376,7 @@ enum hyper_code hyper_request_set_uri_parts(struct hyper_request *req,
376376
enum hyper_code hyper_request_set_version(struct hyper_request *req, int version);
377377

378378
/*
379-
Gets a reference to the HTTP headers of this request
379+
Gets a mutable reference to the HTTP headers of this request
380380
*/
381381
struct hyper_headers *hyper_request_headers(struct hyper_request *req);
382382

@@ -493,7 +493,7 @@ void hyper_executor_free(const struct hyper_executor *exec);
493493
enum hyper_code hyper_executor_push(const struct hyper_executor *exec, struct hyper_task *task);
494494

495495
/*
496-
Polls the executor, trying to make progress on any tasks that have notified
496+
Polls the executor, trying to make progress on any tasks that can do so.
497497
*/
498498
struct hyper_task *hyper_executor_poll(const struct hyper_executor *exec);
499499

@@ -523,7 +523,7 @@ void hyper_task_set_userdata(struct hyper_task *task, void *userdata);
523523
void *hyper_task_userdata(struct hyper_task *task);
524524

525525
/*
526-
Copies a waker out of the task context.
526+
Creates a waker associated with the task context.
527527
*/
528528
struct hyper_waker *hyper_context_waker(struct hyper_context *cx);
529529

src/ffi/body.rs

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,39 @@ use super::{UserDataPointer, HYPER_ITER_CONTINUE};
1111
use crate::body::{Bytes, Frame, Incoming as IncomingBody};
1212

1313
/// A streaming HTTP body.
14+
///
15+
/// This is used both for sending requests (with `hyper_request_set_body`) and
16+
/// for receiving responses (with `hyper_response_body`).
17+
///
18+
/// For outgoing request bodies, call `hyper_body_set_data_func` to provide the
19+
/// data.
20+
///
21+
/// For incoming response bodies, call `hyper_body_data` to get a task that will
22+
/// yield a chunk of data each time it is polled. That task must be then be
23+
/// added to the executor with `hyper_executor_push`.
24+
///
25+
/// Methods:
26+
///
27+
/// - hyper_body_new: Create a new “empty” body.
28+
/// - hyper_body_set_userdata: Set userdata on this body, which will be passed to callback functions.
29+
/// - hyper_body_set_data_func: Set the data callback for this body.
30+
/// - hyper_body_data: Creates a task that will poll a response body for the next buffer of data.
31+
/// - hyper_body_foreach: Creates a task to execute the callback with each body chunk received.
32+
/// - hyper_body_free: Free a body.
1433
pub struct hyper_body(pub(super) IncomingBody);
1534

1635
/// A buffer of bytes that is sent or received on a `hyper_body`.
36+
///
37+
/// Obtain one of these in the callback of `hyper_body_foreach` or by receiving
38+
/// a task of type `HYPER_TASK_BUF` from `hyper_executor_poll` (after calling
39+
/// `hyper_body_data` and pushing the resulting task).
40+
///
41+
/// Methods:
42+
///
43+
/// - hyper_buf_bytes: Get a pointer to the bytes in this buffer.
44+
/// - hyper_buf_copy: Create a new hyper_buf * by copying the provided bytes.
45+
/// - hyper_buf_free: Free this buffer.
46+
/// - hyper_buf_len: Get the length of the bytes this buffer contains.
1747
pub struct hyper_buf(pub(crate) Bytes);
1848

1949
pub(crate) struct UserBody {
@@ -29,7 +59,7 @@ type hyper_body_data_callback =
2959
extern "C" fn(*mut c_void, *mut hyper_context<'_>, *mut *mut hyper_buf) -> c_int;
3060

3161
ffi_fn! {
32-
/// Create a new "empty" body.
62+
/// Creates a new "empty" body.
3363
///
3464
/// If not configured, this body acts as an empty payload.
3565
///
@@ -51,20 +81,31 @@ ffi_fn! {
5181
}
5282

5383
ffi_fn! {
54-
/// Return a task that will poll the body for the next buffer of data.
84+
/// Creates a task that will poll a response body for the next buffer of data.
5585
///
56-
/// The task value may have different types depending on the outcome:
86+
/// The task may have different types depending on the outcome:
5787
///
5888
/// - `HYPER_TASK_BUF`: Success, and more data was received.
5989
/// - `HYPER_TASK_ERROR`: An error retrieving the data.
6090
/// - `HYPER_TASK_EMPTY`: The body has finished streaming data.
6191
///
92+
/// When the application receives the task from `hyper_executor_poll`,
93+
/// if the task type is `HYPER_TASK_BUF`, it should cast the task to
94+
/// `hyper_buf *` and consume all the bytes in the buffer. Then
95+
/// the application should call `hyper_body_data` again for the same
96+
/// `hyper_body *`, to create a task for the next buffer of data.
97+
/// Repeat until the polled task type is `HYPER_TASK_ERROR` or
98+
/// `HYPER_TASK_EMPTY`.
99+
///
62100
/// To avoid a memory leak, the task must eventually be consumed by
63101
/// `hyper_task_free`, or taken ownership of by `hyper_executor_push`
64102
/// without subsequently being given back by `hyper_executor_poll`.
65103
///
66-
/// This does not consume the `hyper_body *`, so it may be used to again.
67-
/// However, it MUST NOT be used or freed until the related task completes.
104+
/// This does not consume the `hyper_body *`, so it may be used again.
105+
/// However, the `hyper_body *` MUST NOT be used or freed until the
106+
/// related task is returned from `hyper_executor_poll`.
107+
///
108+
/// For a more convenient method, see also `hyper_body_foreach`.
68109
fn hyper_body_data(body: *mut hyper_body) -> *mut hyper_task {
69110
// This doesn't take ownership of the Body, so don't allow destructor
70111
let mut body = ManuallyDrop::new(non_null!(Box::from_raw(body) ?= ptr::null_mut()));
@@ -88,18 +129,20 @@ ffi_fn! {
88129
}
89130

90131
ffi_fn! {
91-
/// Return a task that will poll the body and execute the callback with each
92-
/// body chunk that is received.
132+
/// Creates a task to execute the callback with each body chunk received.
93133
///
94134
/// To avoid a memory leak, the task must eventually be consumed by
95135
/// `hyper_task_free`, or taken ownership of by `hyper_executor_push`
96136
/// without subsequently being given back by `hyper_executor_poll`.
97137
///
98-
/// The `hyper_buf` pointer is only a borrowed reference, it cannot live outside
99-
/// the execution of the callback. You must make a copy to retain it.
138+
/// The `hyper_buf` pointer is only a borrowed reference. It cannot live outside
139+
/// the execution of the callback. You must make a copy of the bytes to retain them.
100140
///
101141
/// The callback should return `HYPER_ITER_CONTINUE` to continue iterating
102-
/// chunks as they are received, or `HYPER_ITER_BREAK` to cancel.
142+
/// chunks as they are received, or `HYPER_ITER_BREAK` to cancel. Each
143+
/// invocation of the callback must consume all the bytes it is provided.
144+
/// There is no mechanism to signal to Hyper that only a subset of bytes were
145+
/// consumed.
103146
///
104147
/// This will consume the `hyper_body *`, you shouldn't use it anymore or free it.
105148
fn hyper_body_foreach(body: *mut hyper_body, func: hyper_body_foreach_callback, userdata: *mut c_void) -> *mut hyper_task {
@@ -129,7 +172,7 @@ ffi_fn! {
129172
}
130173

131174
ffi_fn! {
132-
/// Set the data callback for this body.
175+
/// Set the outgoing data callback for this body.
133176
///
134177
/// The callback is called each time hyper needs to send more data for the
135178
/// body. It is passed the value from `hyper_body_set_userdata`.

src/ffi/client.rs

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ use super::io::hyper_io;
1212
use super::task::{hyper_executor, hyper_task, hyper_task_return_type, AsTaskType, WeakExec};
1313

1414
/// An options builder to configure an HTTP client connection.
15+
///
16+
/// Methods:
17+
///
18+
/// - hyper_clientconn_options_new: Creates a new set of HTTP clientconn options to be used in a handshake.
19+
/// - hyper_clientconn_options_exec: Set the client background task executor.
20+
/// - hyper_clientconn_options_http2: Set whether to use HTTP2.
21+
/// - hyper_clientconn_options_set_preserve_header_case: Set whether header case is preserved.
22+
/// - hyper_clientconn_options_set_preserve_header_order: Set whether header order is preserved.
23+
/// - hyper_clientconn_options_http1_allow_multiline_headers: Set whether HTTP/1 connections accept obsolete line folding for header values.
24+
/// - hyper_clientconn_options_free: Free a set of HTTP clientconn options.
1525
pub struct hyper_clientconn_options {
1626
http1_allow_obsolete_multiline_headers_in_responses: bool,
1727
http1_preserve_header_case: bool,
@@ -23,9 +33,42 @@ pub struct hyper_clientconn_options {
2333

2434
/// An HTTP client connection handle.
2535
///
26-
/// These are used to send a request on a single connection. It's possible to
27-
/// send multiple requests on a single connection, such as when HTTP/1
28-
/// keep-alive or HTTP/2 is used.
36+
/// These are used to send one or more requests on a single connection.
37+
///
38+
/// It's possible to send multiple requests on a single connection, such
39+
/// as when HTTP/1 keep-alive or HTTP/2 is used.
40+
///
41+
/// To create a `hyper_clientconn`:
42+
///
43+
/// 1. Create a `hyper_io` with `hyper_io_new`.
44+
/// 2. Create a `hyper_clientconn_options` with `hyper_clientconn_options_new`.
45+
/// 3. Call `hyper_clientconn_handshake` with the `hyper_io` and `hyper_clientconn_options`.
46+
/// This creates a `hyper_task`.
47+
/// 5. Call `hyper_task_set_userdata` to assign an application-specific pointer to the task.
48+
/// This allows keeping track of multiple connections that may be handshaking
49+
/// simultaneously.
50+
/// 4. Add the `hyper_task` to an executor with `hyper_executor_push`.
51+
/// 5. Poll that executor until it yields a task of type `HYPER_TASK_CLIENTCONN`.
52+
/// 6. Extract the `hyper_clientconn` from the task with `hyper_task_value`.
53+
/// This will require a cast from `void *` to `hyper_clientconn *`.
54+
///
55+
/// This process results in a `hyper_clientconn` that permanently owns the
56+
/// `hyper_io`. Because the `hyper_io` in turn owns a TCP or TLS connection, that means
57+
/// the `hyper_clientconn` owns the connection for both the clientconn's lifetime
58+
/// and the connection's lifetime.
59+
///
60+
/// In other words, each connection (`hyper_io`) must have exactly one `hyper_clientconn`
61+
/// associated with it. That's because `hyper_clientconn_handshake` sends the
62+
/// [HTTP/2 Connection Preface] (for HTTP/2 connections). Since that preface can't
63+
/// be sent twice, handshake can't be called twice.
64+
///
65+
/// [HTTP/2 Connection Preface]: https://datatracker.ietf.org/doc/html/rfc9113#name-http-2-connection-preface
66+
///
67+
/// Methods:
68+
///
69+
/// - hyper_clientconn_handshake: Creates an HTTP client handshake task.
70+
/// - hyper_clientconn_send: Creates a task to send a request on the client connection.
71+
/// - hyper_clientconn_free: Free a hyper_clientconn *.
2972
pub struct hyper_clientconn {
3073
tx: Tx,
3174
}
@@ -40,8 +83,7 @@ enum Tx {
4083
// ===== impl hyper_clientconn =====
4184

4285
ffi_fn! {
43-
/// Starts an HTTP client connection handshake using the provided IO transport
44-
/// and options.
86+
/// Creates an HTTP client handshake task.
4587
///
4688
/// Both the `io` and the `options` are consumed in this function call.
4789
/// They should not be used or freed afterwards.
@@ -89,7 +131,7 @@ ffi_fn! {
89131
}
90132

91133
ffi_fn! {
92-
/// Send a request on the client connection.
134+
/// Creates a task to send a request on the client connection.
93135
///
94136
/// This consumes the request. You should not use or free the request
95137
/// afterwards.
@@ -153,7 +195,7 @@ ffi_fn! {
153195
}
154196

155197
ffi_fn! {
156-
/// Set the whether or not header case is preserved.
198+
/// Set whether header case is preserved.
157199
///
158200
/// Pass `0` to allow lowercase normalization (default), `1` to retain original case.
159201
fn hyper_clientconn_options_set_preserve_header_case(opts: *mut hyper_clientconn_options, enabled: c_int) {
@@ -163,7 +205,7 @@ ffi_fn! {
163205
}
164206

165207
ffi_fn! {
166-
/// Set the whether or not header order is preserved.
208+
/// Set whether header order is preserved.
167209
///
168210
/// Pass `0` to allow reordering (default), `1` to retain original ordering.
169211
fn hyper_clientconn_options_set_preserve_header_order(opts: *mut hyper_clientconn_options, enabled: c_int) {
@@ -198,7 +240,7 @@ ffi_fn! {
198240
}
199241

200242
ffi_fn! {
201-
/// Set the whether to use HTTP2.
243+
/// Set whether to use HTTP2.
202244
///
203245
/// Pass `0` to disable, `1` to enable.
204246
fn hyper_clientconn_options_http2(opts: *mut hyper_clientconn_options, enabled: c_int) -> hyper_code {
@@ -219,7 +261,8 @@ ffi_fn! {
219261
}
220262

221263
ffi_fn! {
222-
/// Set whether HTTP/1 connections will accept obsolete line folding for header values.
264+
/// Set whether HTTP/1 connections accept obsolete line folding for header values.
265+
///
223266
/// Newline codepoints (\r and \n) will be transformed to spaces when parsing.
224267
///
225268
/// Pass `0` to disable, `1` to enable.

src/ffi/error.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
use libc::size_t;
22

33
/// A more detailed error object returned by some hyper functions.
4+
///
5+
/// Compare with `hyper_code`, which is a simpler error returned from
6+
/// some hyper functions.
7+
///
8+
/// Methods:
9+
///
10+
/// - hyper_error_code: Get an equivalent hyper_code from this error.
11+
/// - hyper_error_print: Print the details of this error to a buffer.
12+
/// - hyper_error_free: Frees a hyper_error.
413
pub struct hyper_error(crate::Error);
514

615
/// A return code for many of hyper's methods.

0 commit comments

Comments
 (0)