cwist
Modern C web framework with libttak runtime
Loading...
Searching...
No Matches
http2.c File Reference

Implementation of HTTP/2 protocol handler for CWIST. More...

#include <unistd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <poll.h>
#include <fcntl.h>
#include <pthread.h>
#include <ctype.h>
#include <stdatomic.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <time.h>
#include <cwist/net/http/http2.h>
#include <cwist/net/http/http2_flow_control.h>
#include <cwist/net/http/async.h>
#include "async_internal.h"
#include "h2_wire.h"
#include <cwist/core/mem/alloc.h>
#include <cwist/core/mem/gc.h>
#include <cwist/core/log.h>
#include <cwist/sys/metrics/metrics.h>
#include <cwist/core/seq/seq.h>
#include <cwist/sys/err/cwist_err.h>
#include <cwist/sys/app/shutdown.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
Include dependency graph for http2.c:

Go to the source code of this file.

Macros

#define _POSIX_C_SOURCE   200809L
 
#define CWIST_HTTP2_FRAME_HEADER_SIZE   9
 
#define CWIST_HTTP2_CONNECTION_PREFACE   "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
 
#define CWIST_HTTP2_CONNECTION_PREFACE_LEN   24
 
#define CWIST_HTTP2_MAX_FRAME_SIZE   16384
 
#define CWIST_HTTP2_MAX_CONCURRENT_STREAMS   100
 
#define CWIST_HTTP2_HEADER_TABLE_SIZE   4096
 
#define CWIST_HTTP2_FLAG_END_STREAM   0x01
 
#define CWIST_HTTP2_FLAG_END_HEADERS   0x04
 
#define CWIST_HTTP2_FLAG_PADDED   0x08
 
#define CWIST_HTTP2_FLAG_PRIORITY   0x20
 
#define CWIST_HTTP2_FLAG_ACK   0x01
 
#define CWIST_HTTP2_FRAME_DATA   0x00
 
#define CWIST_HTTP2_FRAME_HEADERS   0x01
 
#define CWIST_HTTP2_FRAME_RST_STREAM   0x03
 
#define CWIST_HTTP2_FRAME_SETTINGS   0x04
 
#define CWIST_HTTP2_FRAME_PING   0x06
 
#define CWIST_HTTP2_FRAME_GOAWAY   0x07
 
#define CWIST_HTTP2_FRAME_WINDOW_UPDATE   0x08
 
#define CWIST_HTTP2_FRAME_CONTINUATION   0x09
 
#define CWIST_HTTP2_FRAME_PUSH_PROMISE   0x05
 
#define CWIST_HTTP2_USE_SEQUENCED_DATA   0
 
#define CWIST_HTTP2_SEQ_CHUNK_PAYLOAD(max_frame)    ((uint16_t)((max_frame) > CWIST_SEQ_HEADER_SIZE ? (max_frame) - CWIST_SEQ_HEADER_SIZE : 0))
 
#define H2_ERR_NO_ERROR   0x0
 
#define H2_ERR_PROTOCOL_ERROR   0x1
 
#define H2_ERR_FLOW_CONTROL_ERROR   0x3
 
#define H2_ERR_SETTINGS_TIMEOUT   0x4
 
#define H2_ERR_STREAM_CLOSED   0x5
 
#define H2_ERR_FRAME_SIZE_ERROR   0x6
 
#define H2_ERR_REFUSED_STREAM   0x7
 
#define H2_ERR_COMPRESSION_ERROR   0x9
 
#define H2_ERR_CONNECT_ERROR   0xa
 
#define H2_ERR_ENHANCE_YOUR_CALM   0xb
 
#define CWIST_HTTP2_DEFAULT_RST_BURST   100
 
#define CWIST_HTTP2_DEFAULT_RST_RATE   100 /* resets per second refill */
 
#define CWIST_HTTP2_DEFAULT_PING_BURST   100
 
#define CWIST_HTTP2_DEFAULT_PING_RATE   50 /* pings per second refill */
 
#define CWIST_HTTP2_MAX_HEADER_BLOCK_SIZE   65536
 
#define CWIST_HTTP2_MAX_CONTINUATIONS   32
 
#define CWIST_HTTP2_MAX_HEADERS_PER_REQUEST   256
 
#define CWIST_HTTP2_GOAWAY_GRACE_MS_DEFAULT   2000
 Grace window between sending GOAWAY on idle timeout and closing the connection. A client that raced a request onto the connection just as it went idle needs time to see the GOAWAY and retry; closing the socket the instant GOAWAY leaves makes strict clients (Firefox) surface a protocol error where lenient ones silently retry. Overridable via CWIST_HTTP2_GOAWAY_GRACE_MS.
 
#define CWIST_H2_BATCH_DEFAULT_BYTES   (64 * 1024)
 
#define H2_DECODE_OK   0
 
#define H2_DECODE_STREAM_ERROR   1
 
#define H2_DECODE_COMPRESSION_ERROR   2
 

Typedefs

typedef struct h2_conn h2_conn
 
typedef struct cwist_h2_stream h2_stream
 
typedef struct h2_hpack_entry h2_hpack_entry
 
typedef struct h2_deferred_frame h2_deferred_frame
 
typedef struct h2_async_node h2_async_node
 
typedef struct h2_huffman_node h2_huffman_node
 
typedef struct h2_header_state h2_header_state
 
typedef struct h2_session h2_session
 

Functions

cwist_h2_async_queue * cwist_h2_async_queue_acquire (cwist_h2_async_queue *q)
 Take an additional reference on the queue (for an in-flight cwist_async handle).
 
void cwist_h2_async_queue_release (cwist_h2_async_queue *q)
 Drop a reference on the queue. On the last reference: closes the wake descriptors, destroys the mutex, and frees the queue. Callers must not enqueue after close().
 
int cwist_h2_async_queue_enqueue (cwist_h2_async_queue *q, uint32_t stream_id, cwist_http_request *req, cwist_http_response *send, cwist_http_response *res, bool send_owned)
 
int h2_decode_integer (const unsigned char *buf, size_t len, size_t *pos, uint8_t prefix_bits, uint32_t *value)
 Decode an HPACK integer.
 
char * h2_huffman_decode (const unsigned char *src, size_t src_len, size_t *out_len)
 Decode an HPACK Huffman-coded string (RFC 7541 Appendix B). Lazily initializes the decode tree on first call.
 
char * h2_decode_string (const unsigned char *buf, size_t len, size_t *pos)
 Decode one HPACK string literal (with optional Huffman coding). Reads the length prefix (7-bit prefix integer with the Huffman flag) and advances pos past the encoded bytes.
 
const cwist_http2_static_header * h2_static_header (uint32_t index)
 Resolve an RFC 7541 static table entry by 1-based index.
 
size_t h2_encode_integer (unsigned char *dst, size_t dst_cap, uint32_t value, uint8_t prefix_bits)
 Encode an integer with an N-bit prefix (RFC 7541 section 5.1). Preserves the high bits of dst[0] outside the prefix mask.
 
size_t h2_encode_string (unsigned char *dst, size_t dst_cap, const char *str)
 Encode a literal string without Huffman coding (RFC 7541 section 5.2).
 
int cwist_http2_stream_send_headers (cwist_h2_stream *stream, int status, const cwist_http2_header *headers, size_t header_count, int end_stream)
 
int cwist_http2_stream_send_data (cwist_h2_stream *stream, const unsigned char *data, size_t len)
 Send DATA on a hook-taken stream, honoring flow-control credit. Splits data into peer_max_frame_size chunks. When the send window is exhausted the batch buffer is flushed and the calling handler thread parks on the connection's fc_cond until the dispatcher applies WINDOW_UPDATE credit or the stream goes away; credit is re-checked under out_mu before each frame is written.
 
int cwist_http2_stream_send_trailers (cwist_h2_stream *stream, const cwist_http2_header *trailers, size_t trailer_count)
 
cwist_error_t cwist_http2_serve_connection (cwist_https_connection *conn, void *user_ctx, cwist_http2_request_handler_func handler)
 Serve one HTTP/2 connection until it closes (no stream hooks). Convenience wrapper over cwist_http2_serve_connection_ex with NULL hooks.
 
cwist_error_t cwist_http2_serve_connection_ex (cwist_https_connection *conn, void *user_ctx, cwist_http2_request_handler_func handler, const cwist_http2_stream_hooks *hooks)
 Serve one HTTP/2 connection until it closes. Verifies the preface, sends our SETTINGS, then runs the frame dispatcher: HEADERS/CONTINUATION, DATA, SETTINGS, PING, WINDOW_UPDATE, RST_STREAM, and GOAWAY, with per-connection DoS budgets and flow control. A session may be parked off its thread (cwist_https_park) and resumed via conn->proto_state; on exit the session is torn down and proto_state cleared.
 
int cwist_http2_push_resource (cwist_http_request *req, const char *path, const char *content_type, const unsigned char *data, size_t data_len)
 Push a resource to the client (HTTP/2 server push). Sends a PUSH_PROMISE on the request's stream for a fresh server-initiated stream, then responds on that promised stream with a 200 and the supplied body. The :authority pseudo-header is copied from the request's Host header.
 

Detailed Description

Implementation of HTTP/2 protocol handler for CWIST.

Author
Lee Yunjin
Date
2026-04-27

Definition in file http2.c.

Macro Definition Documentation

◆ _POSIX_C_SOURCE

#define _POSIX_C_SOURCE   200809L

Definition at line 8 of file http2.c.

◆ CWIST_H2_BATCH_DEFAULT_BYTES

#define CWIST_H2_BATCH_DEFAULT_BYTES   (64 * 1024)

Definition at line 1050 of file http2.c.

◆ CWIST_HTTP2_CONNECTION_PREFACE

#define CWIST_HTTP2_CONNECTION_PREFACE   "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"

Definition at line 48 of file http2.c.

◆ CWIST_HTTP2_CONNECTION_PREFACE_LEN

#define CWIST_HTTP2_CONNECTION_PREFACE_LEN   24

Definition at line 49 of file http2.c.

◆ CWIST_HTTP2_DEFAULT_PING_BURST

#define CWIST_HTTP2_DEFAULT_PING_BURST   100

Definition at line 94 of file http2.c.

◆ CWIST_HTTP2_DEFAULT_PING_RATE

#define CWIST_HTTP2_DEFAULT_PING_RATE   50 /* pings per second refill */

Definition at line 95 of file http2.c.

◆ CWIST_HTTP2_DEFAULT_RST_BURST

#define CWIST_HTTP2_DEFAULT_RST_BURST   100

Definition at line 92 of file http2.c.

◆ CWIST_HTTP2_DEFAULT_RST_RATE

#define CWIST_HTTP2_DEFAULT_RST_RATE   100 /* resets per second refill */

Definition at line 93 of file http2.c.

◆ CWIST_HTTP2_FLAG_ACK

#define CWIST_HTTP2_FLAG_ACK   0x01

Definition at line 60 of file http2.c.

◆ CWIST_HTTP2_FLAG_END_HEADERS

#define CWIST_HTTP2_FLAG_END_HEADERS   0x04

Definition at line 57 of file http2.c.

◆ CWIST_HTTP2_FLAG_END_STREAM

#define CWIST_HTTP2_FLAG_END_STREAM   0x01

Definition at line 56 of file http2.c.

◆ CWIST_HTTP2_FLAG_PADDED

#define CWIST_HTTP2_FLAG_PADDED   0x08

Definition at line 58 of file http2.c.

◆ CWIST_HTTP2_FLAG_PRIORITY

#define CWIST_HTTP2_FLAG_PRIORITY   0x20

Definition at line 59 of file http2.c.

◆ CWIST_HTTP2_FRAME_CONTINUATION

#define CWIST_HTTP2_FRAME_CONTINUATION   0x09

Definition at line 69 of file http2.c.

◆ CWIST_HTTP2_FRAME_DATA

#define CWIST_HTTP2_FRAME_DATA   0x00

Definition at line 62 of file http2.c.

◆ CWIST_HTTP2_FRAME_GOAWAY

#define CWIST_HTTP2_FRAME_GOAWAY   0x07

Definition at line 67 of file http2.c.

◆ CWIST_HTTP2_FRAME_HEADER_SIZE

#define CWIST_HTTP2_FRAME_HEADER_SIZE   9

Definition at line 47 of file http2.c.

◆ CWIST_HTTP2_FRAME_HEADERS

#define CWIST_HTTP2_FRAME_HEADERS   0x01

Definition at line 63 of file http2.c.

◆ CWIST_HTTP2_FRAME_PING

#define CWIST_HTTP2_FRAME_PING   0x06

Definition at line 66 of file http2.c.

◆ CWIST_HTTP2_FRAME_PUSH_PROMISE

#define CWIST_HTTP2_FRAME_PUSH_PROMISE   0x05

Definition at line 70 of file http2.c.

◆ CWIST_HTTP2_FRAME_RST_STREAM

#define CWIST_HTTP2_FRAME_RST_STREAM   0x03

Definition at line 64 of file http2.c.

◆ CWIST_HTTP2_FRAME_SETTINGS

#define CWIST_HTTP2_FRAME_SETTINGS   0x04

Definition at line 65 of file http2.c.

◆ CWIST_HTTP2_FRAME_WINDOW_UPDATE

#define CWIST_HTTP2_FRAME_WINDOW_UPDATE   0x08

Definition at line 68 of file http2.c.

◆ CWIST_HTTP2_GOAWAY_GRACE_MS_DEFAULT

#define CWIST_HTTP2_GOAWAY_GRACE_MS_DEFAULT   2000

Grace window between sending GOAWAY on idle timeout and closing the connection. A client that raced a request onto the connection just as it went idle needs time to see the GOAWAY and retry; closing the socket the instant GOAWAY leaves makes strict clients (Firefox) surface a protocol error where lenient ones silently retry. Overridable via CWIST_HTTP2_GOAWAY_GRACE_MS.

Definition at line 158 of file http2.c.

◆ CWIST_HTTP2_HEADER_TABLE_SIZE

#define CWIST_HTTP2_HEADER_TABLE_SIZE   4096

Definition at line 54 of file http2.c.

◆ CWIST_HTTP2_MAX_CONCURRENT_STREAMS

#define CWIST_HTTP2_MAX_CONCURRENT_STREAMS   100

Definition at line 51 of file http2.c.

◆ CWIST_HTTP2_MAX_CONTINUATIONS

#define CWIST_HTTP2_MAX_CONTINUATIONS   32

Definition at line 97 of file http2.c.

◆ CWIST_HTTP2_MAX_FRAME_SIZE

#define CWIST_HTTP2_MAX_FRAME_SIZE   16384

Definition at line 50 of file http2.c.

◆ CWIST_HTTP2_MAX_HEADER_BLOCK_SIZE

#define CWIST_HTTP2_MAX_HEADER_BLOCK_SIZE   65536

Definition at line 96 of file http2.c.

◆ CWIST_HTTP2_MAX_HEADERS_PER_REQUEST

#define CWIST_HTTP2_MAX_HEADERS_PER_REQUEST   256

Definition at line 98 of file http2.c.

◆ CWIST_HTTP2_SEQ_CHUNK_PAYLOAD

#define CWIST_HTTP2_SEQ_CHUNK_PAYLOAD (   max_frame)     ((uint16_t)((max_frame) > CWIST_SEQ_HEADER_SIZE ? (max_frame) - CWIST_SEQ_HEADER_SIZE : 0))

Definition at line 77 of file http2.c.

◆ CWIST_HTTP2_USE_SEQUENCED_DATA

#define CWIST_HTTP2_USE_SEQUENCED_DATA   0

Definition at line 76 of file http2.c.

◆ H2_DECODE_COMPRESSION_ERROR

#define H2_DECODE_COMPRESSION_ERROR   2

Definition at line 1743 of file http2.c.

◆ H2_DECODE_OK

#define H2_DECODE_OK   0

Definition at line 1741 of file http2.c.

◆ H2_DECODE_STREAM_ERROR

#define H2_DECODE_STREAM_ERROR   1

Definition at line 1742 of file http2.c.

◆ H2_ERR_COMPRESSION_ERROR

#define H2_ERR_COMPRESSION_ERROR   0x9

Definition at line 87 of file http2.c.

◆ H2_ERR_CONNECT_ERROR

#define H2_ERR_CONNECT_ERROR   0xa

Definition at line 88 of file http2.c.

◆ H2_ERR_ENHANCE_YOUR_CALM

#define H2_ERR_ENHANCE_YOUR_CALM   0xb

Definition at line 89 of file http2.c.

◆ H2_ERR_FLOW_CONTROL_ERROR

#define H2_ERR_FLOW_CONTROL_ERROR   0x3

Definition at line 82 of file http2.c.

◆ H2_ERR_FRAME_SIZE_ERROR

#define H2_ERR_FRAME_SIZE_ERROR   0x6

Definition at line 85 of file http2.c.

◆ H2_ERR_NO_ERROR

#define H2_ERR_NO_ERROR   0x0

Definition at line 80 of file http2.c.

◆ H2_ERR_PROTOCOL_ERROR

#define H2_ERR_PROTOCOL_ERROR   0x1

Definition at line 81 of file http2.c.

◆ H2_ERR_REFUSED_STREAM

#define H2_ERR_REFUSED_STREAM   0x7

Definition at line 86 of file http2.c.

◆ H2_ERR_SETTINGS_TIMEOUT

#define H2_ERR_SETTINGS_TIMEOUT   0x4

Definition at line 83 of file http2.c.

◆ H2_ERR_STREAM_CLOSED

#define H2_ERR_STREAM_CLOSED   0x5

Definition at line 84 of file http2.c.

Typedef Documentation

◆ h2_async_node

typedef struct h2_async_node h2_async_node

◆ h2_conn

typedef struct h2_conn h2_conn

Definition at line 200 of file http2.c.

◆ h2_deferred_frame

typedef struct h2_deferred_frame h2_deferred_frame

◆ h2_header_state

typedef struct h2_header_state h2_header_state

◆ h2_hpack_entry

typedef struct h2_hpack_entry h2_hpack_entry

◆ h2_huffman_node

typedef struct h2_huffman_node h2_huffman_node

◆ h2_session

typedef struct h2_session h2_session

◆ h2_stream

typedef struct cwist_h2_stream h2_stream

Function Documentation

◆ cwist_h2_async_queue_acquire()

cwist_h2_async_queue * cwist_h2_async_queue_acquire ( cwist_h2_async_queue *  q)

Take an additional reference on the queue (for an in-flight cwist_async handle).

Parameters
qQueue to retain; NULL is tolerated.
Returns
q.

Definition at line 316 of file http2.c.

References cap.

Referenced by cwist_async_defer().

◆ cwist_h2_async_queue_enqueue()

int cwist_h2_async_queue_enqueue ( cwist_h2_async_queue *  q,
uint32_t  stream_id,
cwist_http_request *  req,
cwist_http_response *  send,
cwist_http_response *  res,
bool  send_owned 
)

◆ cwist_h2_async_queue_release()

void cwist_h2_async_queue_release ( cwist_h2_async_queue *  q)

Drop a reference on the queue. On the last reference: closes the wake descriptors, destroys the mutex, and frees the queue. Callers must not enqueue after close().

Parameters
qQueue to release; NULL is tolerated.

Definition at line 327 of file http2.c.

References cap, and cwist_free().

◆ cwist_http2_push_resource()

int cwist_http2_push_resource ( cwist_http_request *  req,
const char *  path,
const char *  content_type,
const unsigned char *  data,
size_t  data_len 
)

Push a resource to the client (HTTP/2 server push). Sends a PUSH_PROMISE on the request's stream for a fresh server-initiated stream, then responds on that promised stream with a 200 and the supplied body. The :authority pseudo-header is copied from the request's Host header.

Push a resource to the client over HTTP/2 Server Push.

Parameters
reqRequest of the stream that triggered the push; its private_data must be the cwist_https_connection.
path:path for the promised request.
content_typeOptional content-type header value.
dataBody bytes (may be NULL when data_len is 0).
data_lenBody length.
Return values
0Response queued/written successfully.
-1Invalid arguments, missing Host header, or send failure.

Definition at line 4210 of file http2.c.

References cwist_http_request::arena, cwist_http_response::body, cap, CWIST_HTTP2_FLAG_END_HEADERS, CWIST_HTTP2_MAX_FRAME_SIZE, cwist_http_header_add(), CWIST_HTTP_OK, cwist_http_response_create_in_arena(), cwist_http_response_destroy(), cwist_sstring_assign_len(), cwist_sstring::data, h2_encode_integer(), h2_encode_string(), cwist_http_request::headers, cwist_http_response::headers, cwist_http_header_node::key, cwist_http_header_node::next, cwist_http_request::private_data, cwist_http_response::status_code, cwist_http_request::stream_id, and cwist_http_header_node::value.

◆ cwist_http2_serve_connection()

cwist_error_t cwist_http2_serve_connection ( cwist_https_connection *  conn,
void *  user_ctx,
cwist_http2_request_handler_func  handler 
)

Serve one HTTP/2 connection until it closes (no stream hooks). Convenience wrapper over cwist_http2_serve_connection_ex with NULL hooks.

Starts serving an HTTP/2 connection over an established HTTPS session.

Parameters
connHTTPS connection with a completed TLS (or h2c) handshake.
user_ctxOpaque context passed to handler.
handlerRequest handler invoked per stream.
Returns
CWIST_ERR_INT16 with err_i16 0 on orderly close, -1 on setup or preface failure.

Definition at line 3493 of file http2.c.

References cap, and cwist_http2_serve_connection_ex().

◆ cwist_http2_serve_connection_ex()

cwist_error_t cwist_http2_serve_connection_ex ( cwist_https_connection *  conn,
void *  user_ctx,
cwist_http2_request_handler_func  handler,
const cwist_http2_stream_hooks *  hooks 
)

Serve one HTTP/2 connection until it closes. Verifies the preface, sends our SETTINGS, then runs the frame dispatcher: HEADERS/CONTINUATION, DATA, SETTINGS, PING, WINDOW_UPDATE, RST_STREAM, and GOAWAY, with per-connection DoS budgets and flow control. A session may be parked off its thread (cwist_https_park) and resumed via conn->proto_state; on exit the session is torn down and proto_state cleared.

Parameters
connHTTPS connection with a completed TLS (or h2c) handshake.
user_ctxOpaque context passed to handler and the hooks.
handlerRequest handler invoked per stream.
hooksOptional stream-lifetime hooks (may be NULL).
Returns
CWIST_ERR_INT16 with err_i16 0 on orderly close, -1 on argument, allocation, or preface failure.

Definition at line 3573 of file http2.c.

References cap, cwist_alloc(), cwist_async_dispatch_ack(), cwist_async_dispatch_take(), CWIST_DEFER_FREE, CWIST_ERR_INT16, cwist_free(), CWIST_HTTP2_FLAG_ACK, CWIST_HTTP2_FLAG_END_HEADERS, CWIST_HTTP2_FLAG_END_STREAM, CWIST_HTTP2_FLAG_PADDED, CWIST_HTTP2_FLAG_PRIORITY, cwist_http2_flow_control_consume(), cwist_http2_flow_control_receive(), cwist_http2_flow_control_update_rtt(), CWIST_HTTP2_FRAME_CONTINUATION, CWIST_HTTP2_FRAME_DATA, CWIST_HTTP2_FRAME_GOAWAY, CWIST_HTTP2_FRAME_HEADERS, CWIST_HTTP2_FRAME_PING, CWIST_HTTP2_FRAME_PUSH_PROMISE, CWIST_HTTP2_FRAME_RST_STREAM, CWIST_HTTP2_FRAME_SETTINGS, CWIST_HTTP2_FRAME_WINDOW_UPDATE, CWIST_HTTP2_MAX_FRAME_SIZE, CWIST_HTTP2_MAX_WINDOW, cwist_http2_stream_flow_control_consume(), cwist_http2_stream_flow_control_receive(), CWIST_HTTP_MAX_BODY_SIZE, cwist_http_response_create_in_arena(), cwist_http_response_destroy(), cwist_https_conn_idle(), cwist_https_park(), CWIST_HTTPS_PARK_HTTP2, CWIST_LOG_WARN, cwist_seq_assembler_create_limited(), cwist_seq_assembler_feed(), cwist_seq_assembler_get_data(), cwist_seq_chunk_parse(), CWIST_SEQ_HEADER_SIZE, cwist_sstring_append_len(), __prim_cwist_error_t::err_i16, cwist_error_t::error, g_cwist_running, H2_ERR_ENHANCE_YOUR_CALM, H2_ERR_FLOW_CONTROL_ERROR, H2_ERR_FRAME_SIZE_ERROR, H2_ERR_NO_ERROR, H2_ERR_PROTOCOL_ERROR, H2_ERR_REFUSED_STREAM, make_error(), cwist_http2_stream_hooks::next_deadline_ms, cwist_http2_stream_hooks::on_cancel, cwist_http2_stream_hooks::on_conn_open, cwist_http2_stream_hooks::on_data, cwist_http2_stream_hooks::on_poll, cwist_https_connection::park_expired, cwist_https_connection::proto_state, and cwist_https_connection::proto_state_free.

Referenced by cwist_app_http_handler(), cwist_app_http_handler_async(), and cwist_http2_serve_connection().

◆ cwist_http2_stream_send_data()

int cwist_http2_stream_send_data ( cwist_h2_stream *  stream,
const unsigned char *  data,
size_t  len 
)

Send DATA on a hook-taken stream, honoring flow-control credit. Splits data into peer_max_frame_size chunks. When the send window is exhausted the batch buffer is flushed and the calling handler thread parks on the connection's fc_cond until the dispatcher applies WINDOW_UPDATE credit or the stream goes away; credit is re-checked under out_mu before each frame is written.

Parameters
streamStream to send on; must belong to a live connection.
dataPayload bytes.
lenPayload length.
Returns
0 when the whole payload was queued/written, -1 on send failure or stream/connection teardown.

Definition at line 2642 of file http2.c.

References cap, CWIST_HTTP2_FRAME_DATA, and CWIST_HTTP2_MAX_FRAME_SIZE.

◆ cwist_http2_stream_send_headers()

int cwist_http2_stream_send_headers ( cwist_h2_stream *  stream,
int  status,
const cwist_http2_header *  headers,
size_t  header_count,
int  end_stream 
)

Immediate outbound writes for hook-taken streams. Safe to call from the stream handler's own thread; frames bypass the batching delay and are flushed to the socket before returning.

cwist_http2_stream_send_headers emits a response HEADERS frame (status is taken from status, the pairs carry the remaining fields). cwist_http2_stream_send_data emits DATA frames (chunked to the peer's frame/window limits). cwist_http2_stream_send_trailers emits a trailer HEADERS frame with END_STREAM. All return 0 on success, -1 on failure.

Definition at line 2608 of file http2.c.

References cap, cwist_free(), CWIST_HTTP2_FLAG_END_HEADERS, CWIST_HTTP2_FLAG_END_STREAM, and CWIST_HTTP2_FRAME_HEADERS.

◆ cwist_http2_stream_send_trailers()

int cwist_http2_stream_send_trailers ( cwist_h2_stream *  stream,
const cwist_http2_header *  trailers,
size_t  trailer_count 
)

◆ h2_decode_integer()

int h2_decode_integer ( const unsigned char *  buf,
size_t  len,
size_t *  pos,
uint8_t  prefix_bits,
uint32_t *  value 
)

Decode an HPACK integer.

Definition at line 1267 of file http2.c.

References cap.

Referenced by h2_decode_string().

◆ h2_decode_string()

char * h2_decode_string ( const unsigned char *  buf,
size_t  len,
size_t *  pos 
)

Decode one HPACK string literal (with optional Huffman coding). Reads the length prefix (7-bit prefix integer with the Huffman flag) and advances pos past the encoded bytes.

Decode an HPACK string (literal or huffman).

Parameters
bufBuffer holding the encoded header block.
lenTotal length of buf.
posIn/out: offset of the string; advanced past it on success.
Returns
Newly allocated string (caller frees), or NULL on malformed input.

Definition at line 1543 of file http2.c.

References cap, cwist_alloc(), h2_decode_integer(), and h2_huffman_decode().

◆ h2_encode_integer()

size_t h2_encode_integer ( unsigned char *  dst,
size_t  dst_cap,
uint32_t  value,
uint8_t  prefix_bits 
)

Encode an integer with an N-bit prefix (RFC 7541 section 5.1). Preserves the high bits of dst[0] outside the prefix mask.

Encode an HPACK integer; returns bytes written, 0 when dst is too small.

Parameters
dstDestination buffer; dst[0] must already hold any flag bits.
dst_capCapacity of dst in bytes.
valueInteger to encode.
prefix_bitsNumber of prefix bits (1..8).
Returns
Bytes written, or 0 when dst_cap is too small.

Definition at line 1875 of file http2.c.

References cap.

Referenced by cwist_http2_push_resource(), and h2_encode_string().

◆ h2_encode_string()

size_t h2_encode_string ( unsigned char *  dst,
size_t  dst_cap,
const char *  str 
)

Encode a literal string without Huffman coding (RFC 7541 section 5.2).

Encode an HPACK string (literal, non-huffman); 0 when dst is too small.

Parameters
dstDestination buffer.
dst_capCapacity of dst in bytes.
strNUL-terminated string to encode.
Returns
Bytes written, or 0 when dst_cap is too small.

Definition at line 1903 of file http2.c.

References cap, and h2_encode_integer().

Referenced by cwist_http2_push_resource().

◆ h2_huffman_decode()

char * h2_huffman_decode ( const unsigned char *  src,
size_t  src_len,
size_t *  out_len 
)

Decode an HPACK Huffman-coded string (RFC 7541 Appendix B). Lazily initializes the decode tree on first call.

Decode an HPACK huffman-encoded string.

Parameters
srcEncoded bytes.
src_lenNumber of encoded bytes.
out_lenOut: decoded length in bytes.
Returns
Newly allocated NUL-terminated decoded string (caller frees), or NULL on initialization, allocation, or coding errors.

Definition at line 1442 of file http2.c.

References cap, cwist_alloc(), cwist_free(), and cwist_realloc().

Referenced by h2_decode_string().

◆ h2_static_header()

const cwist_http2_static_header * h2_static_header ( uint32_t  index)

Resolve an RFC 7541 static table entry by 1-based index.

Resolve an HPACK static table index (1-based); NULL when out of range.

Parameters
indexStatic table index (1..61).
Returns
Pointer to the static entry, or NULL for index 0 or out of range.

Definition at line 1570 of file http2.c.

References cap, and count.