|
cwist
Modern C web framework with libttak runtime
|
HTTP/2-based gRPC client (h2c cleartext, or TLS with ALPN "h2"). More...
#include <cwist/net/grpc/grpc_client.h>#include <cwist/core/mem/alloc.h>#include <arpa/inet.h>#include <errno.h>#include <fcntl.h>#include <netdb.h>#include <poll.h>#include <pthread.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <strings.h>#include <sys/socket.h>#include <time.h>#include <unistd.h>#include <openssl/ssl.h>
Go to the source code of this file.
Macros | |
| #define | _POSIX_C_SOURCE 200809L |
| #define | GRPC_CLIENT_FRAME_HEADER 9 |
| #define | GRPC_CLIENT_MAX_FRAME (16u * 1024u * 1024u) |
| #define | GRPC_CLIENT_DEFAULT_WINDOW 65535 |
| #define | GRPC_CLIENT_HEADER_TABLE 4096 |
| #define | H2_FRAME_DATA 0x00 |
| #define | H2_FRAME_HEADERS 0x01 |
| #define | H2_FRAME_RST_STREAM 0x03 |
| #define | H2_FRAME_SETTINGS 0x04 |
| #define | H2_FRAME_PUSH_PROMISE 0x05 |
| #define | H2_FRAME_PING 0x06 |
| #define | H2_FRAME_GOAWAY 0x07 |
| #define | H2_FRAME_WINDOW_UPDATE 0x08 |
| #define | H2_FRAME_CONTINUATION 0x09 |
| #define | H2_FLAG_END_STREAM 0x01 |
| #define | H2_FLAG_END_HEADERS 0x04 |
| #define | H2_FLAG_ACK 0x01 |
Typedefs | |
| typedef struct grpc_client_hpack_entry | grpc_client_hpack_entry |
| typedef struct grpc_client_msg | grpc_client_msg |
| typedef struct grpc_client_frame | grpc_client_frame |
| typedef void(* | grpc_client_header_cb) (void *ctx, const char *name, const char *value) |
| typedef struct grpc_client_headers_ctx | grpc_client_headers_ctx |
Functions | |
| cwist_grpc_client * | cwist_grpc_client_connect (const char *host, uint16_t port, const cwist_grpc_client_options *options) |
| Connect to a gRPC server and complete the HTTP/2 handshake. | |
| void | cwist_grpc_client_close (cwist_grpc_client *c) |
| Close the client: send GOAWAY, tear down TLS and the socket, free all state. | |
| cwist_grpc_call * | cwist_grpc_call_start (cwist_grpc_client *c, const char *method, const void *request, size_t request_len, uint64_t timeout_ms) |
| Start a unary call (no previous-attempt marker). | |
| cwist_grpc_call * | cwist_grpc_call_start_ex (cwist_grpc_client *c, const char *method, const void *request, size_t request_len, uint64_t timeout_ms, uint32_t previous_attempts) |
| Start a unary call, with a gRFC A6 retry-attempt marker. | |
| int | cwist_grpc_call_recv (cwist_grpc_call *call, cwist_grpc_message *out) |
| Receive the next response message of a call. | |
| int | cwist_grpc_call_await_headers (cwist_grpc_call *call) |
| Block until response headers arrive or the stream ends. | |
| int | cwist_grpc_call_committed (const cwist_grpc_call *call) |
| Whether response headers have committed the RPC (gRFC A6). | |
| int | cwist_grpc_call_refused (const cwist_grpc_call *call) |
| Whether the call failed before commit in a retryable way (gRFC A6 case 3: REFUSED_STREAM before headers, or GOAWAY below our stream id). | |
| int | cwist_grpc_call_retry_pushback_ms (const cwist_grpc_call *call, int32_t *out_ms) |
| Report the server-provided retry pushback delay, if any. | |
| int | cwist_grpc_client_dead (cwist_grpc_client *c) |
| Whether the client connection is unusable. | |
| cwist_grpc_status_t | cwist_grpc_call_status (const cwist_grpc_call *call) |
| Current gRPC status code of a call. | |
| cwist_grpc_status_t | cwist_grpc_call_finish (cwist_grpc_call *call, const char **message) |
| Drain the call to completion and return its final status. | |
| void | cwist_grpc_call_cancel (cwist_grpc_call *call) |
| Cancel a call: send RST_STREAM(CANCEL), mark it failed with CWIST_GRPC_CANCELLED, and end its stream. | |
| void | cwist_grpc_call_destroy (cwist_grpc_call *call) |
| Destroy a call: cancel it if still open, release it as the client's active call, and free all queued and buffered state. | |
HTTP/2-based gRPC client (h2c cleartext, or TLS with ALPN "h2").
The client speaks a minimal but complete HTTP/2 subset: client preface, SETTINGS exchange, HEADERS/DATA framing with HPACK (encoding reuses the shared h2_encode_* helpers from net/http/http2.c; decoding keeps a small per-connection dynamic table), coarse flow control (WINDOW_UPDATE in both directions), PING ACKs, and GOAWAY tolerance. gRPC message framing reuses cwist_grpc_encode_message / cwist_grpc_decoder from grpc.c.
One active call per connection; the mutex serializes call setup.
Definition in file grpc_client.c.
Definition at line 15 of file grpc_client.c.
| #define GRPC_CLIENT_DEFAULT_WINDOW 65535 |
Definition at line 35 of file grpc_client.c.
| #define GRPC_CLIENT_FRAME_HEADER 9 |
Definition at line 33 of file grpc_client.c.
| #define GRPC_CLIENT_HEADER_TABLE 4096 |
Definition at line 36 of file grpc_client.c.
| #define GRPC_CLIENT_MAX_FRAME (16u * 1024u * 1024u) |
Definition at line 34 of file grpc_client.c.
| #define H2_FLAG_ACK 0x01 |
Definition at line 49 of file grpc_client.c.
| #define H2_FLAG_END_HEADERS 0x04 |
Definition at line 48 of file grpc_client.c.
| #define H2_FLAG_END_STREAM 0x01 |
Definition at line 47 of file grpc_client.c.
| #define H2_FRAME_CONTINUATION 0x09 |
Definition at line 46 of file grpc_client.c.
| #define H2_FRAME_DATA 0x00 |
Definition at line 38 of file grpc_client.c.
| #define H2_FRAME_GOAWAY 0x07 |
Definition at line 44 of file grpc_client.c.
| #define H2_FRAME_HEADERS 0x01 |
Definition at line 39 of file grpc_client.c.
| #define H2_FRAME_PING 0x06 |
Definition at line 43 of file grpc_client.c.
| #define H2_FRAME_PUSH_PROMISE 0x05 |
Definition at line 42 of file grpc_client.c.
| #define H2_FRAME_RST_STREAM 0x03 |
Definition at line 40 of file grpc_client.c.
| #define H2_FRAME_SETTINGS 0x04 |
Definition at line 41 of file grpc_client.c.
| #define H2_FRAME_WINDOW_UPDATE 0x08 |
Definition at line 45 of file grpc_client.c.
Definition at line 394 of file grpc_client.c.
| int cwist_grpc_call_await_headers | ( | cwist_grpc_call * | call | ) |
Block until response headers arrive or the stream ends.
| call | The call. |
| 0 | Response headers received (the RPC is committed). |
| 1 | The stream ended before any response headers (retryable). |
| -1 | Invalid call, error, or deadline. |
Definition at line 1228 of file grpc_client.c.
Referenced by cwist_grpc_channel_call_start().
| void cwist_grpc_call_cancel | ( | cwist_grpc_call * | call | ) |
Cancel a call: send RST_STREAM(CANCEL), mark it failed with CWIST_GRPC_CANCELLED, and end its stream.
| call | The call; NULL or an already-ended call is a no-op. |
Definition at line 1308 of file grpc_client.c.
References cap, CWIST_GRPC_CANCELLED, and H2_FRAME_RST_STREAM.
Referenced by cwist_grpc_call_destroy(), and cwist_grpc_channel_call_cancel().
Whether response headers have committed the RPC (gRFC A6).
Definition at line 1241 of file grpc_client.c.
| void cwist_grpc_call_destroy | ( | cwist_grpc_call * | call | ) |
Destroy a call: cancel it if still open, release it as the client's active call, and free all queued and buffered state.
| call | The call; NULL is a no-op. |
Definition at line 1323 of file grpc_client.c.
References cap, cwist_free(), cwist_grpc_call_cancel(), and cwist_grpc_decoder_destroy().
Referenced by cwist_grpc_channel_call_destroy(), cwist_grpc_channel_call_start(), and cwist_grpc_client_close().
| cwist_grpc_status_t cwist_grpc_call_finish | ( | cwist_grpc_call * | call, |
| const char ** | message | ||
| ) |
Drain the call to completion and return its final status.
| call | The call. |
| message | When non-NULL, set to the status message text; the pointer is owned by the call and stays valid until cwist_grpc_call_destroy. |
Definition at line 1291 of file grpc_client.c.
References cap, and CWIST_GRPC_INTERNAL.
Referenced by cwist_grpc_channel_call_finish().
| int cwist_grpc_call_recv | ( | cwist_grpc_call * | call, |
| cwist_grpc_message * | out | ||
| ) |
Receive the next response message of a call.
| call | The call. |
| out | Filled with the next message; out->data is owned by the call and stays valid until the next recv or cwist_grpc_call_destroy. |
| 1 | A message was returned. |
| 0 | The stream ended cleanly and no more messages will arrive. |
| -1 | The call failed (see cwist_grpc_call_status). |
Definition at line 1203 of file grpc_client.c.
References cap, cwist_grpc_message::compressed, cwist_free(), cwist_grpc_message::data, and cwist_grpc_message::len.
Referenced by cwist_grpc_channel_call_recv().
Whether the call failed before commit in a retryable way (gRFC A6 case 3: REFUSED_STREAM before headers, or GOAWAY below our stream id).
Definition at line 1250 of file grpc_client.c.
Referenced by cwist_grpc_channel_call_start().
Report the server-provided retry pushback delay, if any.
| call | The call. |
| out_ms | Set to the pushback delay in ms (negative = do not retry) when present. |
Definition at line 1261 of file grpc_client.c.
References cap.
Referenced by cwist_grpc_channel_call_start().
| cwist_grpc_call * cwist_grpc_call_start | ( | cwist_grpc_client * | c, |
| const char * | method, | ||
| const void * | request, | ||
| size_t | request_len, | ||
| uint64_t | timeout_ms | ||
| ) |
Start a unary call (no previous-attempt marker).
| c | Client; must be connected and have no active call. |
| method | gRPC method path (e.g. "/pkg.Service/Method"). |
| request | Request message bytes; may be NULL when request_len is 0. |
| request_len | Request length in bytes. |
| timeout_ms | Per-call deadline in ms; 0 means no deadline. |
Definition at line 1094 of file grpc_client.c.
References cap, and cwist_grpc_call_start_ex().
| cwist_grpc_call * cwist_grpc_call_start_ex | ( | cwist_grpc_client * | c, |
| const char * | method, | ||
| const void * | request, | ||
| size_t | request_len, | ||
| uint64_t | timeout_ms, | ||
| uint32_t | previous_attempts | ||
| ) |
Start a unary call, with a gRFC A6 retry-attempt marker.
Sends HEADERS (:method POST, :scheme, :path, :authority, content-type, te) followed by the framed request message, then commits the call as the client's active call. Serialized by the client mutex: one active call per connection.
| previous_attempts | Value for grpc-previous-rpc-attempts; 0 omits the header. |
Definition at line 1112 of file grpc_client.c.
References cap, cwist_alloc(), cwist_free(), cwist_grpc_decoder_destroy(), cwist_grpc_decoder_init(), cwist_grpc_encode_message(), CWIST_GRPC_OK, H2_FLAG_END_HEADERS, and H2_FRAME_HEADERS.
Referenced by cwist_grpc_call_start(), and cwist_grpc_channel_call_start().
| cwist_grpc_status_t cwist_grpc_call_status | ( | const cwist_grpc_call * | call | ) |
Current gRPC status code of a call.
| call | The call. |
Definition at line 1280 of file grpc_client.c.
References CWIST_GRPC_INTERNAL.
Referenced by cwist_grpc_channel_call_destroy(), and cwist_grpc_channel_call_start().
| void cwist_grpc_client_close | ( | cwist_grpc_client * | c | ) |
Close the client: send GOAWAY, tear down TLS and the socket, free all state.
| c | Client to close; NULL is a no-op. |
Definition at line 701 of file grpc_client.c.
References cap, cwist_free(), cwist_grpc_call_destroy(), H2_FRAME_GOAWAY, SSL_CTX_free, SSL_free, and SSL_shutdown.
Referenced by cwist_grpc_channel_close(), and cwist_grpc_client_connect().
| cwist_grpc_client * cwist_grpc_client_connect | ( | const char * | host, |
| uint16_t | port, | ||
| const cwist_grpc_client_options * | options | ||
| ) |
Connect to a gRPC server and complete the HTTP/2 handshake.
| host | Server hostname or address. |
| port | TCP port number. |
| options | Optional TLS/timeout/authority options; NULL for defaults (no TLS, 10 s connect timeout, authority "host:port"). |
Definition at line 624 of file grpc_client.c.
References cwist_grpc_client_options::authority, cap, cwist_grpc_client_options::connect_timeout_ms, cwist_alloc(), cwist_free(), cwist_grpc_client_close(), GRPC_CLIENT_DEFAULT_WINDOW, GRPC_CLIENT_HEADER_TABLE, H2_FLAG_ACK, H2_FRAME_GOAWAY, H2_FRAME_PING, H2_FRAME_SETTINGS, cwist_grpc_client_options::tls_server_name, cwist_grpc_client_options::use_tls, and cwist_grpc_client_options::verify_peer.
| int cwist_grpc_client_dead | ( | cwist_grpc_client * | c | ) |
Whether the client connection is unusable.
Definition at line 1271 of file grpc_client.c.
References cap.
Referenced by cwist_grpc_channel_get_state().