Skip to content

Commit 7e3c79b

Browse files
authored
fix: repairing malformed HAR postData objects on the fly (readmeio#111)
1 parent 7d956b9 commit 7e3c79b

4 files changed

Lines changed: 54 additions & 15 deletions

File tree

src/helpers/har-validator.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,6 @@ export const validateHarRequest = (request: any): request is Request => {
3030

3131
const valid = validate(request);
3232
if (!valid && validate.errors) {
33-
if (validate.errors.length === 1) {
34-
// While not ideal, or compliant with the HAR spec, if we have an empty `postData` object in
35-
// our HAR and no other errors we should let this through because it's fine and our client
36-
// targets are able to handle it okay.
37-
const error = validate.errors[0];
38-
if (
39-
error.dataPath === '.postData' &&
40-
error.message === "should have required property 'mimeType'" &&
41-
JSON.stringify(request.postData) === '{}'
42-
) {
43-
return true;
44-
}
45-
}
46-
4733
throw new HARError(validate.errors);
4834
}
4935

src/index.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,54 @@ describe('HTTPSnippet', () => {
2323
expect(attempt).toThrow('validation failed');
2424
});
2525

26+
describe('repair malformed `postData`', () => {
27+
it('should repair a HAR with an empty `postData` object', () => {
28+
const snippet = new HTTPSnippet({
29+
method: 'POST',
30+
url: 'https://httpbin.org/anything',
31+
postData: {},
32+
} as Request);
33+
34+
const request = snippet.requests[0];
35+
expect(request.postData).toStrictEqual({
36+
mimeType: 'application/octet-stream',
37+
});
38+
});
39+
40+
it('should repair a HAR with a `postData` params object missing `mimeType`', () => {
41+
// @ts-expect-error Testing a malformed HAR case.
42+
const snippet = new HTTPSnippet({
43+
method: 'POST',
44+
url: 'https://httpbin.org/anything',
45+
postData: {
46+
params: [],
47+
},
48+
} as Request);
49+
50+
const request = snippet.requests[0];
51+
expect(request.postData).toStrictEqual({
52+
mimeType: 'application/octet-stream',
53+
params: [],
54+
});
55+
});
56+
57+
it('should repair a HAR with a `postData` text object missing `mimeType`', () => {
58+
const snippet = new HTTPSnippet({
59+
method: 'POST',
60+
url: 'https://httpbin.org/anything',
61+
postData: {
62+
text: '',
63+
},
64+
} as Request);
65+
66+
const request = snippet.requests[0];
67+
expect(request.postData).toStrictEqual({
68+
mimeType: 'application/octet-stream',
69+
text: '',
70+
});
71+
});
72+
});
73+
2674
it('should parse HAR file with multiple entries', () => {
2775
const snippet = new HTTPSnippet({
2876
log: {

src/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ export class HTTPSnippet {
119119
...request,
120120
};
121121

122+
// Per the HAR spec `mimeType` needs to always be present if we have a `postData` object.
123+
if (req.postData && !req.postData.mimeType) {
124+
req.postData.mimeType = 'application/octet-stream';
125+
}
126+
122127
if (validateHarRequest(req)) {
123128
this.requests.push(this.prepare(req, options));
124129
}

src/targets/r/httr/fixtures/postdata-malformed.r

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ library(httr)
22

33
url <- "https://httpbin.org/anything"
44

5-
response <- VERB("POST", url, content_type("undefined"))
5+
response <- VERB("POST", url, content_type("application/octet-stream"))
66

77
content(response, "text")

0 commit comments

Comments
 (0)