11#if DETWS_ENABLE_EDGE_CACHE
20size_t head_end(
const uint8_t *b,
size_t n)
22 for (
size_t i = 0; i + 3 < n; i++)
23 if (b[i] ==
'\r' && b[i + 1] ==
'\n' && b[i + 2] ==
'\r' && b[i + 3] ==
'\n')
28bool hex_val(uint8_t c,
int *v)
30 if (c >=
'0' && c <=
'9')
36 if (c >=
'a' && c <=
'f')
45bool chunked_complete(
const uint8_t *b,
size_t n)
54 while (j < n && hex_val(b[j], &v))
56 sz = sz * 16 + (size_t)v;
62 while (j < n && b[j] !=
'\n')
72 if (j + 1 < n && b[j] ==
'\r' && b[j + 1] ==
'\n')
75 while (k < n && b[k] !=
'\n')
82 size_t next = j + sz + 2;
90bool has_chunked(
const char *s)
94 for (; s[i] && i + 1 <
sizeof(low); i++)
95 low[i] = (s[i] >=
'A' && s[i] <=
'Z') ? (char)(s[i] + 32) : s[i];
97 return strstr(low,
"chunked") !=
nullptr;
101bool edge_resp_complete(
const uint8_t *buf,
size_t len,
bool conn_closed,
size_t *head_len)
103 size_t h = head_end(buf, len);
108 if (edge_header_value((
const char *)buf, h,
"Content-Length", v,
sizeof(v)))
112 for (
const char *p = v; *p >=
'0' && *p <=
'9'; p++)
114 cl = cl * 10 + (size_t)(*p -
'0');
118 return len >= h + cl;
121 if (edge_header_value((
const char *)buf, h,
"Transfer-Encoding", te,
sizeof(te)) && has_chunked(te))
122 return chunked_complete(buf + h, len - h);
126void edge_fetch_begin(EdgeFetch *f,
const EdgeFetchTransport *t,
const char *host, uint16_t port,
const void *request,
127 size_t req_len, uint32_t now_ms)
129 memset(f, 0,
sizeof(*f));
131 f->start_ms = now_ms;
132 f->st = EdgeFetchStatus::PENDING;
136 f->st = EdgeFetchStatus::FAILED;
139 if (!t->send(t->ctx, f->cid, request, req_len))
140 f->st = EdgeFetchStatus::FAILED;
143EdgeFetchStatus edge_fetch_pump(EdgeFetch *f,
const EdgeFetchTransport *t, uint32_t now_ms)
145 if (f->st != EdgeFetchStatus::PENDING)
148 while (f->got <
sizeof(f->buf))
150 size_t n = t->read(t->ctx, f->cid, f->buf + f->got,
sizeof(f->buf) - f->got);
155 bool closed = t->closed(t->ctx, f->cid);
158 if (edge_resp_complete(f->buf, f->got, closed, &hl))
162 int status = http_client_parse_response(f->buf, f->got, &bo, &bl);
165 f->st = EdgeFetchStatus::FAILED;
172 f->st = EdgeFetchStatus::DONE;
175 if (f->got >=
sizeof(f->buf))
177 f->st = EdgeFetchStatus::OVERSIZE;
182 f->st = EdgeFetchStatus::FAILED;
187 f->st = EdgeFetchStatus::FAILED;
190 return EdgeFetchStatus::PENDING;
193void edge_fetch_end(EdgeFetch *f,
const EdgeFetchTransport *t)
197 t->close(t->ctx, f->cid);
#define DETWS_EDGE_FETCH_TIMEOUT_MS
CDN edge-cache tier - pure engine (DETWS_ENABLE_EDGE_CACHE).
CDN edge-cache tier - async origin-fetch engine (DETWS_ENABLE_EDGE_CACHE).
Zero-heap outbound HTTP(S) client over raw lwIP (DETWS_ENABLE_HTTP_CLIENT).