Skip to content

Commit 5c982e2

Browse files
committed
Update Mockttp for HTTP/2 & trailer improvements
Most of these are server side, but notably this makes it possible for us to (eventually) listen for trailers and include those in the inspectable UI data too. For now, we do enough to make the types work, but we don't actually subscribe to these events or show trailer data yet.
1 parent 73683b5 commit 5c982e2

File tree

6 files changed

+105
-50
lines changed

6 files changed

+105
-50
lines changed

package-lock.json

Lines changed: 64 additions & 43 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@
103103
"mobx-shallow-undo": "^1.0.0",
104104
"mobx-utils": "^5.1.0",
105105
"mockrtc": "^0.3.1",
106-
"mockttp": "^3.10.1",
106+
"mockttp": "^3.11.0",
107107
"monaco-editor": "^0.27.0",
108108
"node-forge": "^1.3.0",
109109
"openapi-directory": "^1.3.0",

src/model/http/har.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as querystring from 'querystring';
66

77
import {
88
Headers,
9+
Trailers,
910
HtkRequest,
1011
HarRequest,
1112
HarResponse,
@@ -60,6 +61,11 @@ export interface ExtendedHarRequest extends HarFormat.Request {
6061
| 'discarded:not-representable'
6162
| 'discarded:not-decodable';
6263
_content?: RequestContentData;
64+
_trailers?: HarFormat.Header[];
65+
}
66+
67+
export interface ExtendedHarResponse extends HarFormat.Response {
68+
_trailers?: HarFormat.Header[];
6369
}
6470

6571
export interface HarEntry extends HarFormat.Entry {
@@ -120,7 +126,7 @@ export async function generateHar(
120126
};
121127
}
122128

123-
function asHarHeaders(headers: Headers) {
129+
function asHarHeaders(headers: Headers | Trailers) {
124130
return _.map(headers, (headerValue, headerKey) => ({
125131
name: headerKey,
126132
value: _.isArray(headerValue)
@@ -167,6 +173,9 @@ export function generateHarRequest(
167173
httpVersion: `HTTP/${request.httpVersion || '1.1'}`,
168174
cookies: [],
169175
headers: asHarHeaders(request.headers),
176+
...(request.trailers ? {
177+
_trailers: asHarHeaders(request.trailers)
178+
} : {}),
170179
queryString: Array.from(request.parsedUrl.searchParams.entries()).map(
171180
([paramKey, paramValue]) => ({
172181
name: paramKey,
@@ -714,7 +723,9 @@ function parseHarRequest(
714723
? parseHarRequestContents(request._content)
715724
: parseHarPostData(request.postData),
716725
encodedLength: request.bodySize
717-
}
726+
},
727+
rawTrailers: request._trailers?.map(t => [t.name, t.value]) ?? [],
728+
trailers: asHtkHeaders(request._trailers ?? []) as Trailers
718729
}
719730
}
720731

@@ -768,7 +779,7 @@ function parseHarPostData(data: HarFormat.PostData | undefined): Buffer {
768779

769780
function parseHarResponse(
770781
id: string,
771-
response: HarFormat.Response,
782+
response: ExtendedHarResponse,
772783
timingEvents: TimingEvents
773784
): HarResponse {
774785
return {
@@ -787,6 +798,8 @@ function parseHarResponse(
787798
encodedLength: (!response.bodySize || response.bodySize === -1)
788799
? 0 // If bodySize is missing or inaccessible, just zero it
789800
: response.bodySize
790-
}
801+
},
802+
rawTrailers: response._trailers?.map(t => [t.name, t.value]) ?? [],
803+
trailers: asHtkHeaders(response._trailers ?? []) as Trailers,
791804
}
792805
}

src/model/send/send-response-model.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { RawHeaders } from "../../types";
1+
import { RawHeaders, RawTrailers } from "../../types";
22

33
export type ResponseStreamEvent =
44
| RequestStartEvent
55
| ResponseHeadEvent
66
| ResponseBodyPartEvent
7+
| ResponseTrailersEvent
78
| ResponseEndEvent
89
| ErrorEvent;
910

@@ -27,6 +28,12 @@ interface ResponseBodyPartEvent {
2728
timestamp: number;
2829
}
2930

31+
interface ResponseTrailersEvent {
32+
type: 'response-trailers';
33+
trailers: RawTrailers;
34+
timestamp: number;
35+
}
36+
3037
interface ResponseEndEvent {
3138
type: 'response-end';
3239
timestamp: number;

src/model/send/send-store.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import {
99
TimingEvents
1010
} from 'mockttp';
1111

12+
import { RawTrailers } from '../../types';
13+
1214
import { logError } from '../../errors';
1315
import { getObservableDeferred, lazyObservablePromise } from '../../util/observable';
1416
import { persist, hydrate } from '../../util/mobx-persist/persist';
@@ -250,6 +252,7 @@ const trackResponseEvents = flow(function * (
250252

251253
let responseHead: ResponseHeadEvent | undefined;
252254
let responseBodyParts: Buffer[] = [];
255+
let rawTrailers: RawTrailers = [];
253256

254257
while (true) {
255258
const { done, value } = (
@@ -270,6 +273,9 @@ const trackResponseEvents = flow(function * (
270273
case 'response-body-part':
271274
responseBodyParts.push(value.rawBody);
272275
break;
276+
case 'response-trailers':
277+
rawTrailers.push(...value.trailers);
278+
break;
273279
case 'response-end':
274280
if (!responseHead) throw new Error(`Received response-end before response-head!`);
275281

@@ -282,6 +288,8 @@ const trackResponseEvents = flow(function * (
282288
headers: rawHeadersToHeaders(responseHead.headers),
283289
rawHeaders: responseHead.headers,
284290
body: { buffer: Buffer.concat(responseBodyParts) },
291+
trailers: rawHeadersToHeaders(rawTrailers),
292+
rawTrailers: rawTrailers,
285293
tags: [],
286294
timingEvents
287295
});

0 commit comments

Comments
 (0)