Skip to content

Commit 36b8a0e

Browse files
Add request interceptor to sniff all incomming http traffic
1 parent 7bfbb9b commit 36b8a0e

File tree

5 files changed

+75
-5
lines changed

5 files changed

+75
-5
lines changed

package-lock.json

Lines changed: 6 additions & 0 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 & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
"jsonpath": "^1.1.1",
111111
"lodash": "^4.17.21",
112112
"minimatch": "^9.0.3",
113+
"parse-headers": "^2.0.5",
113114
"regex-parser": "^2.3.0",
114115
"uuid": "^9.0.1",
115116
"yargs": "^17.7.2",

src/interceptor.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { ErrorCallback, IContext } from 'http-mitm-proxy';
2+
import stream from 'stream';
3+
import { constructURLFromRequest } from './utils/proxy';
4+
import responseDecoder from './response-decoder';
5+
import parseHeader from 'parse-headers';
6+
7+
function interceptBody(writable: stream.Writable | undefined, callback: (value: any) => void) {
8+
if (!writable) {
9+
return callback(null);
10+
}
11+
const [originalWrite, originalEnd] = [writable.write, writable.end];
12+
const chunks: Buffer[] = [];
13+
14+
(writable.write as unknown) = function (...args: any) {
15+
chunks.push(typeof args[0] === 'string' ? Buffer.from(args[0]) : args[0]);
16+
originalWrite.apply(writable, args);
17+
};
18+
19+
(writable.end as unknown) = async function (...args: any) {
20+
if (args[0]) {
21+
chunks.push(typeof args[0] === 'string' ? Buffer.from(args[0]) : args[0]);
22+
}
23+
originalEnd.apply(writable, args);
24+
callback(Buffer.concat(chunks).toString('utf8'));
25+
};
26+
}
27+
28+
function RequestInterceptor(requestCompletionCallback: (value: any) => void) {
29+
return function (ctx: IContext, callback: ErrorCallback) {
30+
ctx.use(responseDecoder);
31+
const requestData = {} as any;
32+
ctx.onRequestEnd((ctx, callback) => {
33+
interceptBody(ctx.proxyToServerRequest, (requestBody) => {
34+
requestData['postBody'] = requestBody;
35+
requestData['requestHeaders'] = ctx.proxyToServerRequest?.getHeaders();
36+
});
37+
callback();
38+
});
39+
40+
interceptBody(ctx.proxyToClientResponse, (response) => {
41+
const { headers, url } = ctx.clientToProxyRequest;
42+
const protocol = ctx.isSSL ? 'https://' : 'http://';
43+
const _url = constructURLFromRequest({
44+
host: headers.host!,
45+
path: url!,
46+
protocol,
47+
});
48+
const responseHeaders = parseHeader((ctx.proxyToClientResponse as any)?._header || '');
49+
requestData['url'] = _url;
50+
requestData['method'] = ctx.clientToProxyRequest.method;
51+
requestData['responseBody'] = response;
52+
requestData['responseHeaders'] = responseHeaders;
53+
54+
requestCompletionCallback(requestData);
55+
});
56+
callback();
57+
};
58+
}
59+
60+
export { RequestInterceptor };

src/proxy.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
} from './utils/proxy';
1515
import ResponseDecoder from './response-decoder';
1616
import { Mock } from './mock';
17+
import { RequestInterceptor } from './interceptor';
1718

1819
export interface ProxyOptions {
1920
deviceUDID: string;
@@ -63,6 +64,13 @@ export class Proxy {
6364
forceSNI: true,
6465
};
6566

67+
this.httpProxy.onRequest(
68+
RequestInterceptor((requestData: any) => {
69+
// console.log('****** REQUEST **********');
70+
// console.log(JSON.stringify(requestData, null, 2));
71+
// console.log('****************************');
72+
})
73+
);
6674
this.httpProxy.onRequest(this.handleMockApiRequest.bind(this));
6775

6876
await new Promise((resolve) => {

src/utils/proxy.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,6 @@ export function modifyRequestBody(ctx: IContext, mockConfig: MockConfig) {
8181
if (mockConfig.updateRequestBody) {
8282
postBody = processBody(mockConfig.updateRequestBody, originalBody);
8383
}
84-
if (postBody) {
85-
console.log('************* REQUEST BODY **************************');
86-
console.log(postBody);
87-
}
8884
ctx.proxyToServerRequest?.setHeader('Content-Length', Buffer.byteLength(postBody));
8985
ctx.proxyToServerRequest?.write(postBody);
9086
callback();
@@ -100,7 +96,6 @@ export function modifyResponseBody(ctx: IContext, mockConfig: MockConfig) {
10096
ctx.onResponseEnd((ctx: IContext, callback: OnRequestDataCallback) => {
10197
const originalResponse = Buffer.concat(responseBodyChunks).toString('utf8');
10298
let responseBody = mockConfig.responseBody || originalResponse;
103-
//console.log(originalResponse);
10499

105100
if (mockConfig.statusCode) {
106101
ctx.proxyToClientResponse.writeHead(mockConfig.statusCode);

0 commit comments

Comments
 (0)