ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
http_date.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 http_date.h
6 * @brief Render a Unix epoch as an RFC 7231 IMF-fixdate.
7 *
8 * One formatter serves every header that carries a timestamp (`Date`, `Last-Modified`, `Expires`),
9 * so the wire rendering is fixed in one place. The break-down is reentrant (`gmtime_r`, never the
10 * shared static `tm`), which is what makes it callable from any worker.
11 *
12 * Every rejection - no epoch, no buffer, a time that will not break down - returns 0 and leaves
13 * @p out an empty string, so a caller that ignores the length still emits a well-formed header
14 * value rather than whatever the buffer held.
15 *
16 * @author Douglas Quigg (dstroy0)
17 * @date 2026
18 */
19
20#ifndef PROTOCORE_HTTP_DATE_H
21#define PROTOCORE_HTTP_DATE_H
22
23#include <stdint.h>
24#include <time.h>
25
27
28/**
29 * @brief Smallest buffer that holds an RFC 7231 IMF-fixdate plus its NUL.
30 *
31 * `Sun, 06 Nov 1994 08:49:37 GMT` is 29 characters and the format is fixed-width, so this is a
32 * property of the protocol rather than a tuning choice. A smaller buffer truncates silently,
33 * because strftime writes nothing and returns 0 when the result does not fit.
34 */
35#define PC_HTTP_DATE_MAX 30
36
37/**
38 * @brief Write @p epoch into @p out as an IMF-fixdate in GMT.
39 * @return characters written, excluding the NUL, or 0 with an empty @p out on any rejection.
40 */
41inline uint8_t pc_http_date(time_t epoch, char *out, uint32_t out_cap)
42{
43 if (!out || out_cap == 0)
44 {
45 return 0;
46 }
47 if (epoch == 0)
48 {
49 out[0] = '\0';
50 return 0;
51 }
52 struct tm broken_down;
53 if (!pc_gmtime_r(&epoch, &broken_down))
54 {
55 out[0] = '\0';
56 return 0;
57 }
58 return (uint8_t)strftime(out, out_cap, "%a, %d %b %Y %H:%M:%S GMT", &broken_down);
59}
60
61#endif // PROTOCORE_HTTP_DATE_H
uint8_t pc_http_date(time_t epoch, char *out, uint32_t out_cap)
Write epoch into out as an IMF-fixdate in GMT.
Definition http_date.h:41
Reentrant UTC broken-down time, portable across the host and target toolchains.
struct tm * pc_gmtime_r(const time_t *epoch, struct tm *out)
Convert epoch to broken-down UTC in caller storage (reentrant).
Definition time_compat.h:28