httpdate
nimony/lib/std/http/httpdate.nim
const HttpDateLen: int64Every IMF-fixdate is exactly this long โ the format has no variable-width field. So a caller sizes its buffer from the type rather than from a guess, and
writeHttpDatenever has to answer "how much would it have needed".proc writeHttpDate(dest: var openArray; t: Time): int64Write
tas an IMF-fixdate into the front ofdest. ReturnsHttpDateLen, or0whendestis smaller than that and nothing was written.The year is clamped to four digits: HTTP has no spelling for a fifth, and a header that is 30 bytes where every parser expects 29 is worse than one that is wrong about the year 10000.
proc formatHttpDate(t: Time): stringtas an IMF-fixdate. The allocating form, for the places that want a string anyway;writeHttpDateis the one a response takes per request.proc nowHttpDate(dest: var openArray): int64The current instant as an IMF-fixdate. Returns
HttpDateLen, or0ifdestis too small.Cached for the second it names, which is not an optimisation so much as an admission: the format has one-second resolution, so every response inside the same second must produce the same 29 bytes, and doing the calendar arithmetic again to arrive at them is work whose result was already known. A server answering 50k requests a second does 1 conversion rather than 50k.
The cache is per thread, so it needs no lock and can never be torn. Two lanes each keeping their own 29 bytes is cheaper than one they have to agree about, and they agree anyway โ they are reading the same clock.
proc parseHttpDate(buf: openArray; t: var Time): boolRead one HTTP date.
bufis the whole header value โ there is no cursor to advance, because a date header holds one date and nothing follows it.Accepts all three formats RFC 9110 ยง5.6.7 names, and
tis untouched when it accepts none. A recipient MUST accept the obsolete two: a server that rejects the RFC 850 form in anIf-Modified-Sincedoes not fail visibly, it just stops answering 304 to the caches that send it.