Skip to content

Commit a165404

Browse files
authored
Merge pull request #186 from fitudao3788/main
Implement req in beforeResponse #80
2 parents 89717b1 + a44926b commit a165404

File tree

3 files changed

+45
-9
lines changed

3 files changed

+45
-9
lines changed

src/rules/requests/request-handler-definitions.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -550,17 +550,19 @@ export interface PassThroughHandlerOptions extends PassThroughHandlerConnectionO
550550
/**
551551
* A callback that will be passed the full response before it is passed through,
552552
* and which returns a value that defines how the the response content should
553-
* be transformed before it's returned to the client.
553+
* be transformed before it's returned to the client. The callback is also passed
554+
* the request that was sent to the server (as a 2nd parameter) for reference.
554555
*
555556
* The callback can either return an object to define how the response should be
556-
* changed, or the string 'close' to immediately close the underlying connection.
557+
* changed, or the strings 'close' or 'reset' to immediately close/reset the
558+
* underlying connection.
557559
*
558560
* All fields on the object are optional, and returning undefined is equivalent
559561
* to returning an empty object (transforming nothing).
560562
*
561563
* See {@link CallbackResponseMessageResult} for the possible fields that can be set.
562564
*/
563-
beforeResponse?: (res: PassThroughResponse) => MaybePromise<CallbackResponseResult | void> | void;
565+
beforeResponse?: (res: PassThroughResponse, req: CompletedRequest) => MaybePromise<CallbackResponseResult | void> | void;
564566
}
565567

566568
export interface RequestTransform {
@@ -754,7 +756,7 @@ export interface BeforePassthroughRequestRequest {
754756
* @internal
755757
*/
756758
export interface BeforePassthroughResponseRequest {
757-
args: [Replace<PassThroughResponse, { body: string }>];
759+
args: [Replace<PassThroughResponse, { body: string }>, Replace<CompletedRequest, { body: string }>];
758760
}
759761

760762
/**
@@ -780,7 +782,7 @@ export class PassThroughHandlerDefinition extends Serializable implements Reques
780782

781783
public readonly beforeRequest?: (req: CompletedRequest) =>
782784
MaybePromise<CallbackRequestResult | void> | void;
783-
public readonly beforeResponse?: (res: PassThroughResponse) =>
785+
public readonly beforeResponse?: (res: PassThroughResponse, req: CompletedRequest) =>
784786
MaybePromise<CallbackResponseResult | void> | void;
785787

786788
public readonly proxyConfig?: ProxyConfig;
@@ -925,7 +927,8 @@ export class PassThroughHandlerDefinition extends Serializable implements Reques
925927
CallbackResponseResult | undefined
926928
>('beforeResponse', async (req) => {
927929
const callbackResult = await this.beforeResponse!(
928-
withDeserializedBodyReader(req.args[0])
930+
withDeserializedBodyReader(req.args[0]),
931+
withDeserializedBodyReader(req.args[1]),
929932
);
930933

931934
if (typeof callbackResult === 'string') {

src/rules/requests/request-handlers.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -924,13 +924,27 @@ export class PassThroughHandler extends PassThroughHandlerDefinition {
924924
originalBody = await streamToBuffer(serverRes);
925925
let serverHeaders = rawHeadersToObject(serverRawHeaders);
926926

927+
let reqHeader = rawHeadersToObjectPreservingCase(rawHeaders);
927928
modifiedRes = await this.beforeResponse({
928929
id: clientReq.id,
929930
statusCode: serverStatusCode,
930931
statusMessage: serverRes.statusMessage,
931932
headers: serverHeaders,
932933
rawHeaders: _.cloneDeep(serverRawHeaders),
933934
body: buildBodyReader(originalBody, serverHeaders)
935+
}, {
936+
id: clientReq.id,
937+
protocol: protocol?.replace(':', '') ?? '',
938+
method: method,
939+
url: reqUrl,
940+
path: path ?? '',
941+
headers: reqHeader,
942+
rawHeaders: rawHeaders,
943+
timingEvents: clientReq.timingEvents,
944+
tags: clientReq.tags,
945+
body: buildBodyReader(reqBodyOverride ? Buffer.from(reqBodyOverride.buffer) : await clientReq.body.asDecodedBuffer(), reqHeader),
946+
rawTrailers: clientReq.rawTrailers ?? [],
947+
trailers: rawHeadersToObject(clientReq.rawTrailers ?? []),
934948
});
935949

936950
if (modifiedRes === 'close') {
@@ -1214,17 +1228,17 @@ export class PassThroughHandler extends PassThroughHandlerDefinition {
12141228
};
12151229
}
12161230

1217-
let beforeResponse: ((res: PassThroughResponse) => MaybePromise<CallbackResponseResult | void>) | undefined;
1231+
let beforeResponse: ((res: PassThroughResponse, req: CompletedRequest) => MaybePromise<CallbackResponseResult | void>) | undefined;
12181232
if (data.hasBeforeResponseCallback) {
1219-
beforeResponse = async (res: PassThroughResponse) => {
1233+
beforeResponse = async (res: PassThroughResponse, req: CompletedRequest) => {
12201234
const callbackResult = await channel.request<
12211235
BeforePassthroughResponseRequest,
12221236
| WithSerializedCallbackBuffers<CallbackResponseMessageResult>
12231237
| 'close'
12241238
| 'reset'
12251239
| undefined
12261240
>('beforeResponse', {
1227-
args: [withSerializedBodyReader(res)]
1241+
args: [withSerializedBodyReader(res), withSerializedBodyReader(req)]
12281242
})
12291243

12301244
if (callbackResult && typeof callbackResult !== 'string') {

test/integration/proxying/http-proxying.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,25 @@ nodeOnly(() => {
778778
expect(response).to.equal('all good');
779779
});
780780

781+
it("should be able to examine the request in beforeResponse", async () => {
782+
await remoteServer.forGet('/').thenCallback(() => ({
783+
status: 500,
784+
headers: {
785+
'UPPERCASE-HEADER': 'VALUE'
786+
}
787+
}));
788+
789+
await server.forGet(remoteServer.urlFor("/")).thenPassThrough({
790+
beforeResponse: (_res, req) => {
791+
expect(req.url).to.equal(remoteServer.urlFor('/'));
792+
return { status: 200, body: 'got correct req url' };
793+
}
794+
});
795+
796+
let response = await request.get(remoteServer.urlFor("/"));
797+
expect(response).to.equal('got correct req url');
798+
});
799+
781800
it("should be able to rewrite a response's status", async () => {
782801
await remoteServer.forGet('/').thenReply(404);
783802
await server.forGet(remoteServer.urlFor("/")).thenPassThrough({

0 commit comments

Comments
 (0)