11#if PC_ENABLE_EDGE_CACHE
20size_t head_end(
const uint8_t *b,
size_t n)
22 for (
size_t i = 0; i + 3 < n; i++)
24 if (b[i] ==
'\r' && b[i + 1] ==
'\n' && b[i + 2] ==
'\r' && b[i + 3] ==
'\n')
32bool hex_val(uint8_t c,
int *v)
34 if (c >=
'0' && c <=
'9')
40 if (c >=
'a' && c <=
'f')
50bool chunked_trailer_complete(
const uint8_t *b,
size_t n,
size_t j)
54 if (j + 1 < n && b[j] ==
'\r' && b[j + 1] ==
'\n')
59 while (k < n && b[k] !=
'\n')
72bool chunked_complete(
const uint8_t *b,
size_t n)
81 while (j < n && hex_val(b[j], &v))
83 sz = sz * 16 + (size_t)v;
91 while (j < n && b[j] !=
'\n')
102 return chunked_trailer_complete(b, n, j);
104 size_t next = j + sz + 2;
114bool has_chunked(
const char *s)
122 for (; s[i] && i + 1 <
sizeof(low); i++)
124 low[i] = (s[i] >=
'A' && s[i] <=
'Z') ? (
char)(s[i] + 32) : s[i];
127 return strstr(low,
"chunked") !=
nullptr;
131bool edge_resp_complete(
const uint8_t *buf,
size_t len,
bool conn_closed,
size_t *head_len)
133 size_t h = head_end(buf, len);
140 if (edge_header_value((
const char *)buf, h,
"Content-Length", v,
sizeof(v)))
144 for (
const char *p = v; *p >=
'0' && *p <=
'9'; p++)
146 cl = cl * 10 + (size_t)(*p -
'0');
151 return len >= h + cl;
155 if (edge_header_value((
const char *)buf, h,
"Transfer-Encoding", te,
sizeof(te)) && has_chunked(te))
157 return chunked_complete(buf + h, len - h);
162void edge_fetch_begin(EdgeFetch *f,
const EdgeFetchTransport *t,
const char *host, uint16_t port,
const void *request,
163 size_t req_len, uint32_t now_ms)
165 memset(f, 0,
sizeof(*f));
167 f->start_ms = now_ms;
168 f->st = EdgeFetchStatus::PENDING;
172 f->st = EdgeFetchStatus::FAILED;
175 if (!t->send(t->ctx, f->cid, request, req_len))
177 f->st = EdgeFetchStatus::FAILED;
181EdgeFetchStatus edge_fetch_pump(EdgeFetch *f,
const EdgeFetchTransport *t, uint32_t now_ms)
183 if (f->st != EdgeFetchStatus::PENDING)
188 while (f->got <
sizeof(f->buf))
190 size_t n = t->read(t->ctx, f->cid, f->buf + f->got,
sizeof(f->buf) - f->got);
197 bool closed = t->closed(t->ctx, f->cid);
200 if (edge_resp_complete(f->buf, f->got, closed, &hl))
204 int status = http_client_parse_response(f->buf, f->got, &bo, &bl);
207 f->st = EdgeFetchStatus::FAILED;
214 f->st = EdgeFetchStatus::DONE;
217 if (f->got >=
sizeof(f->buf))
219 f->st = EdgeFetchStatus::OVERSIZE;
224 f->st = EdgeFetchStatus::FAILED;
229 f->st = EdgeFetchStatus::FAILED;
232 return EdgeFetchStatus::PENDING;
235void edge_fetch_end(EdgeFetch *f,
const EdgeFetchTransport *t)
239 t->close(t->ctx, f->cid);
CDN edge-cache tier - pure engine (PC_ENABLE_EDGE_CACHE).
CDN edge-cache tier - async origin-fetch engine (PC_ENABLE_EDGE_CACHE).
Zero-heap outbound HTTP(S) client over raw lwIP (PC_ENABLE_HTTP_CLIENT).
#define PC_EDGE_FETCH_TIMEOUT_MS