-
-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathproxy_tests.ts
144 lines (130 loc) · 4.19 KB
/
proxy_tests.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import {Server as HTTPServer} from 'http';
import createHTTPServer from './util/http_server';
import {equal as assertEqual} from 'assert';
import {gzipSync, gunzipSync} from 'zlib';
import {default as MITMProxy, InterceptedHTTPMessage, nopInterceptor} from 'mitmproxy';
const HTTP_PORT = 8888;
interface TestFile {
mimeType: string;
data: Buffer;
headers?: {[name: string]: string}
}
// 'Files' present in the test HTTP server
const FILES: {[name: string]: TestFile} = {
'/test.html': {
mimeType: 'text/html',
data: Buffer.from('<!DOCTYPE html><html><head><title>My Web Page</title></head></html>', 'utf8')
},
'/test.js': {
mimeType: 'text/javascript',
data: Buffer.from('window.SHENANIGANS = true;', 'utf8')
},
'/test.js.gz': {
mimeType: 'text/javascript',
data: gzipSync(Buffer.from('window.SHENANIGANS = true;', 'utf8')),
headers: {
'content-encoding': 'gzip'
}
},
'/test.jpg': {
mimeType: 'image/jpeg',
data: Buffer.alloc(1025, 0)
},
'/huge.html': {
mimeType: 'text/html',
// 10MB file filled w/ a's.
data: Buffer.alloc(1024*1024*10, 97)
},
'/huge.jpg': {
mimeType: 'image/jpeg',
data: Buffer.alloc(1024*1024*10, 0)
},
'/': {
mimeType: 'text/html',
data: Buffer.from('<!DOCTYPE html><html><title>Not Found</title></html>', 'utf8')
}
};
describe('Proxy', function() {
this.timeout(30000);
let proxy: MITMProxy;
let httpServer: HTTPServer;
before(async function() {
httpServer = await createHTTPServer(FILES, HTTP_PORT);
proxy = await MITMProxy.Create(undefined, [], true);
});
async function requestFile(path: string, expected: Buffer): Promise<void> {
const response = await proxy.proxyGet(`http://localhost:${HTTP_PORT}${path}`);
if (!response.body.equals(expected)) {
console.log(`${response.body.length} actual, ${expected.length} expected`);
console.log(`${response.body[10]}, ${expected[10]}`);
}
assertEqual(response.body.equals(expected), true);
}
it("Properly proxies text files", async function() {
proxy.cb = nopInterceptor;
const promises = ['/test.html', '/test.js'].map((filename) => {
return requestFile(filename, FILES[filename].data);
});
promises.push(requestFile('/test.jpg', FILES['/test.jpg'].data));
return Promise.all(promises);
});
it("Properly handles compressed data", async function() {
proxy.cb = nopInterceptor;
await requestFile('/test.js.gz', gunzipSync(FILES['/test.js.gz'].data));
});
it("Properly rewrites text files", async function() {
const MAGIC_STRING = Buffer.from("HELLO THERE", 'utf8');
function transform(m: InterceptedHTTPMessage): void {
const mimeType = m.response.getHeader('content-type').toLowerCase();
if (mimeType === "text/html" || mimeType === "text/javascript") {
m.setResponseBody(MAGIC_STRING);
}
}
proxy.cb = transform;
const promises = ['/test.html', '/test.js'].map((filename) => {
return requestFile(filename, MAGIC_STRING);
});
promises.push(requestFile('/test.jpg', FILES['/test.jpg'].data));
return Promise.all(promises);
});
it("Properly proxies huge binary files", async function() {
proxy.cb = nopInterceptor;
return requestFile('/huge.jpg', FILES['/huge.jpg'].data);
});
it("Properly proxies huge text files", async function() {
const raw = FILES['/huge.html'].data;
const expected = Buffer.alloc(raw.length, 98);
proxy.cb = (f: InterceptedHTTPMessage): void => {
f.setResponseBody(Buffer.from(f.responseBody.toString().replace(/a/g, 'b'), 'utf8'));
};
return requestFile('/huge.html', expected);
});
after(function(done) {
// Shutdown both HTTP server and proxy.
let e: any;
function wrappedDone() {
done(e);
}
function closeProxy() {
if (proxy) {
proxy.shutdown().then(wrappedDone, (localE) => {
e = localE;
wrappedDone();
});
} else {
wrappedDone();
}
}
function closeHttpServer() {
if (httpServer) {
httpServer.close((localE: any) => {
e = localE;
closeProxy();
});
} else {
closeProxy();
}
}
closeHttpServer();
});
});