mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-07 08:33:50 +08:00
Iterate untyped Headers values (#1969)
This commit is contained in:
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"order": [
|
||||
"<repo>/tests/corpus/7735-untyped-headers-iterators.js"
|
||||
],
|
||||
"diags": []
|
||||
}
|
||||
@@ -2491,11 +2491,44 @@ static bool sf_headers_sorted_entry(SfHeaders *h, size_t index,
|
||||
return found;
|
||||
}
|
||||
|
||||
/* One step of a live Headers iterator (entries, keys or values): the
|
||||
* `*index`th entry of the current sorted list, as Node's iterator re-reads
|
||||
* the list on every step. The result is { value, done }. */
|
||||
static ScrDyn *sf_headers_step(void *ptr, double *index, unsigned selection) {
|
||||
ScrStr *name = NULL;
|
||||
ScrStr *value = NULL;
|
||||
bool found = sf_headers_sorted_entry(ptr, (size_t)*index, &name, &value);
|
||||
ScrDyn *item;
|
||||
if (found) {
|
||||
(*index)++;
|
||||
if (selection == 2) {
|
||||
item = scr_dyn_new_arr();
|
||||
scr_dyn_arr_push(item, scr_dyn_new_str(name));
|
||||
scr_dyn_arr_push(item, scr_dyn_new_str(value));
|
||||
} else {
|
||||
item = scr_dyn_new_str(selection == 1 ? name : value);
|
||||
}
|
||||
scr_str_release(name);
|
||||
scr_str_release(value);
|
||||
} else {
|
||||
item = scr_dyn_retain(scr_dyn_undefined());
|
||||
}
|
||||
ScrDyn *result = scr_dyn_new_obj();
|
||||
scr_dyn_obj_set(result, "value", 5, item);
|
||||
scr_dyn_obj_set(result, "done", 4, scr_dyn_new_bool(!found));
|
||||
return result;
|
||||
}
|
||||
|
||||
static ScrDyn *sf_headers_invoke(void *ptr, ScrDyn *self,
|
||||
const char *method,
|
||||
ScrDyn *const *args, size_t argc,
|
||||
const char *what) {
|
||||
SfHeaders *h = ptr;
|
||||
if (strcmp(method, "entries") == 0 || strcmp(method, "keys") == 0 ||
|
||||
strcmp(method, "values") == 0) {
|
||||
return scr_dyn_native_handle_iterator(
|
||||
self, strcmp(method, "entries") == 0 ? 2 : strcmp(method, "keys") == 0 ? 1 : 0);
|
||||
}
|
||||
if (strcmp(method, "get") == 0 || strcmp(method, "has") == 0) {
|
||||
if (argc < 1) {
|
||||
sf_type_error("Headers.get/has requires a header name");
|
||||
@@ -5487,7 +5520,8 @@ static const ScrDynHandleOps sf_response_ops = {
|
||||
&sf_response_invoke, &sf_response_get, &sf_no_set, NULL};
|
||||
static const ScrDynHandleOps sf_headers_ops = {
|
||||
"Headers", &sf_headers_retain_v, &sf_headers_release_v,
|
||||
&sf_headers_invoke, &sf_headers_get, &sf_no_set, NULL};
|
||||
&sf_headers_invoke, &sf_headers_get, &sf_no_set, NULL, NULL,
|
||||
&sf_headers_step};
|
||||
|
||||
static void sf_teardown(void) {
|
||||
while (sf_live) {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// Headers entries/keys/values on an untyped Headers value: live iterators over the
|
||||
// sorted list, with set-cookie values one by one, as hono's Context copies headers.
|
||||
const holder = JSON.parse("{}");
|
||||
holder.res = new Response("body", { headers: { "x-b": "2", "X-A": "1", "set-cookie": "s=1" } });
|
||||
holder.res.headers.append("set-cookie", "t=2");
|
||||
const headers = holder.res.headers;
|
||||
for (const [k, v] of headers.entries()) console.log("entry", k, v);
|
||||
console.log(JSON.stringify([...headers.keys()]), JSON.stringify([...headers.values()]));
|
||||
const it = headers.entries();
|
||||
console.log(JSON.stringify(it.next()));
|
||||
headers.append("a-first", "0");
|
||||
headers.append("z-last", "9");
|
||||
console.log(JSON.stringify(it.next()), JSON.stringify(it.next()));
|
||||
const rest = [];
|
||||
for (const entry of it) rest.push(entry.join("="));
|
||||
console.log(rest.join(" "), JSON.stringify(it.next()));
|
||||
const copy = JSON.parse("{}");
|
||||
copy.res = new Response(null, { status: 204 });
|
||||
for (const [k, v] of headers.entries()) {
|
||||
if (k === "set-cookie") continue;
|
||||
copy.res.headers.set(k, v);
|
||||
}
|
||||
console.log(JSON.stringify([...copy.res.headers.entries()]));
|
||||
@@ -0,0 +1 @@
|
||||
{ "plain": 4000, "san": 4000 }
|
||||
Reference in New Issue
Block a user