DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
grpcweb.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file grpcweb.h
6 * @brief gRPC-Web message framing (DETWS_ENABLE_GRPC_WEB) - zero-heap length-prefixed frame
7 * builder + parser, the HTTP/1.1-reachable subset of gRPC that wraps the Protobuf
8 * codec (services/protobuf). gRPC proper needs HTTP/2; gRPC-Web rides the shipped
9 * HTTP/1.1 server/client.
10 *
11 * Each gRPC / gRPC-Web message is a 5-octet prefix then the body:
12 * @code
13 * [flags(1)][length(4, big-endian)][body...]
14 * @endcode
15 * - flags bit 0 = compressed (per the Message-Encoding header); bit 7 (0x80) marks a
16 * gRPC-Web trailers frame whose body is an HTTP/1.1-style trailer block
17 * (`grpc-status:0\r\ngrpc-message:...\r\n`) instead of a Protobuf message.
18 * - A response is zero or more message frames followed by exactly one trailers frame.
19 *
20 * The message body is an encoded Protobuf message (build it with the protobuf codec, then
21 * frame it here). This is the framing layer only.
22 *
23 * @author Douglas Quigg (dstroy0)
24 * @date 2026
25 */
26
27#ifndef DETERMINISTICESPASYNCWEBSERVER_GRPCWEB_H
28#define DETERMINISTICESPASYNCWEBSERVER_GRPCWEB_H
29
30#include "ServerConfig.h"
31
32#if DETWS_ENABLE_GRPC_WEB
33
34#include <stddef.h>
35#include <stdint.h>
36
37#define GRPCWEB_FLAG_COMPRESSED 0x01
38#define GRPCWEB_FLAG_TRAILER 0x80
39#define GRPCWEB_PREFIX_LEN 5
40
41/** @brief Frame a body: `[flags][len BE32][body]`. Returns total octets, or 0 on overflow. */
42size_t grpcweb_frame(uint8_t *buf, size_t cap, uint8_t flags, const uint8_t *body, size_t body_len);
43
44/** @brief Frame a (Protobuf) message; @p compressed sets the compressed flag. */
45size_t grpcweb_frame_message(uint8_t *buf, size_t cap, const uint8_t *msg, size_t msg_len, bool compressed);
46
47/**
48 * @brief Build a trailers frame: `grpc-status:<status>\r\n` plus, when @p message is given,
49 * `grpc-message:<message>\r\n`, wrapped with the 0x80 trailer flag.
50 * @return total octets written, or 0 on overflow.
51 */
52size_t grpcweb_frame_trailer(uint8_t *buf, size_t cap, int status, const char *message);
53
54/** @brief One parsed frame; @ref body points INTO the source buffer. */
55struct GrpcWebFrame
56{
57 uint8_t flags;
58 bool compressed; ///< flags & 0x01
59 bool trailer; ///< flags & 0x80
60 const uint8_t *body;
61 size_t body_len;
62};
63
64/**
65 * @brief Parse one frame at the head of [buf, buf+len).
66 * @param consumed receives the frame's total length so the caller can advance.
67 * @return true on a complete frame; false if fewer than the prefix + body octets are buffered.
68 */
69bool grpcweb_parse(const uint8_t *buf, size_t len, GrpcWebFrame *out, size_t *consumed);
70
71/** @brief Extract `grpc-status` (an integer) from a trailers-frame body. */
72bool grpcweb_trailer_status(const uint8_t *body, size_t len, int *status);
73
74#endif // DETWS_ENABLE_GRPC_WEB
75
76#endif // DETERMINISTICESPASYNCWEBSERVER_GRPCWEB_H
User-facing configuration for DeterministicESPAsyncWebServer.