DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
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 Format a Unix epoch as an RFC 7231 IMF-fixdate (one shared copy).
7 *
8 * The `Date:` header formatter (gmtime_r + strftime to "%a, %d %b %Y %H:%M:%S GMT")
9 * was open-coded in the NTP service; the time-source-fed Date header needs the same
10 * thing. This header-only inline helper is the single home for it - reentrant
11 * (gmtime_r, never the shared static tm buffer, so it is worker-safe) and fail-closed
12 * (empty string, length 0) when the epoch is unset or does not fit a broken-down year.
13 *
14 * @author Douglas Quigg (dstroy0)
15 * @date 2026
16 */
17
18#ifndef DETERMINISTICESPASYNCWEBSERVER_DET_HTTP_DATE_H
19#define DETERMINISTICESPASYNCWEBSERVER_DET_HTTP_DATE_H
20
21#include <stddef.h>
22#include <stdint.h>
23#include <time.h>
24
25/**
26 * @brief Write @p epoch as an RFC 7231 IMF-fixdate into @p out (always GMT).
27 * @return bytes written (excluding the NUL), or 0 with an empty @p out when @p epoch is 0,
28 * @p out is null / @p out_cap is 0, or the time cannot be broken down.
29 */
30inline size_t detws_http_date(time_t epoch, char *out, size_t out_cap)
31{
32 if (!out || out_cap == 0)
33 return 0;
34 if (epoch == 0)
35 {
36 out[0] = '\0';
37 return 0;
38 }
39 struct tm tmv; // reentrant: gmtime_r, never the shared static buffer (worker-safe)
40 if (!gmtime_r(&epoch, &tmv))
41 {
42 out[0] = '\0';
43 return 0;
44 }
45 return strftime(out, out_cap, "%a, %d %b %Y %H:%M:%S GMT", &tmv);
46}
47
48#endif // DETERMINISTICESPASYNCWEBSERVER_DET_HTTP_DATE_H
size_t detws_http_date(time_t epoch, char *out, size_t out_cap)
Write epoch as an RFC 7231 IMF-fixdate into out (always GMT).
Definition http_date.h:30