Skip to content

Commit

Permalink
Make non-GET query canonicalization consistent with new spec
Browse files Browse the repository at this point in the history
This is part of bringing consistency between pywb and warcio.js
with regard to how query parameters are constructed from request
bodies for non-GET requests.

The more complicated test is duplicated in pywb to help ensure
that the results are consistent across our toolsets/langauges.
  • Loading branch information
tw4l committed Apr 2, 2024
1 parent 397c2a6 commit 2437622
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 8 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 34 additions & 6 deletions src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,41 @@ export function jsonToQueryParams(json: string | any, ignoreInvalid = true) {
return key + "." + ++dupes[key] + "_";
};

try {
JSON.stringify(json, (k, v) => {
if (!["object", "function"].includes(typeof v)) {
q.set(getKey(k), v);
const parser = (jsonObj: object, key="") => {
let queryValue = "";

// if object, attempt to recurse through key/value pairs
if (typeof(jsonObj) === "object" && !(jsonObj instanceof Array)) {
try {
for (const [key, value] of Object.entries(jsonObj)) {
parser(value, key);
}
} catch (e) {
// special case for null
if (jsonObj === null) {
queryValue = "null";
}
}
}

// if array, recurse through values, re-using key
else if (jsonObj instanceof Array) {
for (let i=0; i < jsonObj.length; i++) {
parser(jsonObj[i], key);
}
return v;
});
}

if (["string", "number", "boolean"].includes(typeof(jsonObj))) {
queryValue = jsonObj.toString();
}

if (queryValue) {
q.set(getKey(key), queryValue);
}
};

try {
parser(json);
} catch (e) {
if (!ignoreInvalid) {
throw e;
Expand Down
16 changes: 16 additions & 0 deletions test/testUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,22 @@ describe("utils", () => {
).toBe("abc=def&data=bar&bar=2&a=3&a.2_=4&bar.2_=123&a.3_=5");
});

test("another json with more complicated data", () => {
expect(
toQuery({
"type": "event",
"id": 44.0,
"float": 35.7,
"values": [true, false, null],
"source": {
"type": "component",
"id": "a+b&c= d",
"values": [3, 4]
}
})
).toBe("type=event&id=44&float=35.7&values=true&values.2_=false&values.3_=null&type.2_=component&id.2_=a%2Bb%26c%3D+d&values.4_=3&values.5_=4");
});

test("post-to-get empty", () => {
const request = {
postData: "",
Expand Down

0 comments on commit 2437622

Please sign in to comment.