koa-classic-server 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -120
- package/index.cjs +236 -21
- package/package.json +10 -5
- package/.github/workflows/npm-publish.yml +0 -98
- package/CLAUDE.md +0 -101
- package/__tests__/benchmark-results-baseline-v1.2.0.txt +0 -354
- package/__tests__/benchmark-results-optimized-v2.0.0.txt +0 -354
- package/__tests__/benchmark-results-v3.0.0.txt +0 -372
- package/__tests__/benchmark.js +0 -239
- package/__tests__/caching-headers.test.js +0 -556
- package/__tests__/compression-fixtures/data.json +0 -1
- package/__tests__/compression-fixtures/large.txt +0 -1
- package/__tests__/compression-fixtures/small.txt +0 -1
- package/__tests__/compression.test.js +0 -284
- package/__tests__/customTest/README.md +0 -6
- package/__tests__/customTest/loadConfig.util.js +0 -41
- package/__tests__/customTest/serversToLoad.util.js +0 -93
- package/__tests__/demo-regex-index.js +0 -140
- package/__tests__/deprecation-warnings.test.js +0 -105
- package/__tests__/directory-sorting-links.test.js +0 -135
- package/__tests__/dt-unknown.test.js +0 -635
- package/__tests__/ejs.test.js +0 -299
- package/__tests__/hidden-fixtures/.dot-dir/inside.txt +0 -1
- package/__tests__/hidden-fixtures/.env +0 -2
- package/__tests__/hidden-fixtures/.well-known/acme-challenge.txt +0 -1
- package/__tests__/hidden-fixtures/config/secrets/password.txt +0 -1
- package/__tests__/hidden-fixtures/data.key +0 -1
- package/__tests__/hidden-fixtures/file.secret +0 -1
- package/__tests__/hidden-fixtures/index.html +0 -1
- package/__tests__/hidden-fixtures/normal.txt +0 -1
- package/__tests__/hidden-fixtures/subdir/.env +0 -1
- package/__tests__/hidden-fixtures/subdir/regular.txt +0 -1
- package/__tests__/hidden-option.test.js +0 -407
- package/__tests__/hideExtension.test.js +0 -607
- package/__tests__/index-option.test.js +0 -449
- package/__tests__/index.test.js +0 -345
- package/__tests__/listing.test.js +0 -437
- package/__tests__/logger.test.js +0 -232
- package/__tests__/performance.test.js +0 -370
- package/__tests__/publicWwwTest/cartella/sottocartella/ciao.html +0 -11
- package/__tests__/publicWwwTest/cartella/sottocartella/provaEjs/testEjs.ejs +0 -11
- package/__tests__/publicWwwTest/cartella vuota con spazi nel nome/file con spazio nel nome .txt +0 -1
- package/__tests__/publicWwwTest/cartella vuota con spazi nel nome /file con spazio nel nome .txt +0 -1
- package/__tests__/publicWwwTest/ejs-templates/complex.ejs +0 -56
- package/__tests__/publicWwwTest/ejs-templates/index.ejs +0 -30
- package/__tests__/publicWwwTest/ejs-templates/simple.ejs +0 -13
- package/__tests__/publicWwwTest/ejs-templates/with-conditional.ejs +0 -28
- package/__tests__/publicWwwTest/ejs-templates/with-escaping.ejs +0 -26
- package/__tests__/publicWwwTest/ejs-templates/with-loop.ejs +0 -16
- package/__tests__/publicWwwTest/hideext-test/about/index.html +0 -1
- package/__tests__/publicWwwTest/hideext-test/about.EJS +0 -1
- package/__tests__/publicWwwTest/hideext-test/about.ejs +0 -2
- package/__tests__/publicWwwTest/hideext-test/blog/articolo.ejs +0 -2
- package/__tests__/publicWwwTest/hideext-test/conflict-test/pagina +0 -1
- package/__tests__/publicWwwTest/hideext-test/conflict-test/pagina.ejs +0 -1
- package/__tests__/publicWwwTest/hideext-test/file.ejs.bak +0 -1
- package/__tests__/publicWwwTest/hideext-test/index.ejs +0 -2
- package/__tests__/publicWwwTest/hideext-test/photo.txt +0 -1
- package/__tests__/publicWwwTest/hideext-test/sezione/index.ejs +0 -1
- package/__tests__/publicWwwTest/hideext-test/style.css +0 -1
- package/__tests__/publicWwwTest/ile_vuoto.txt +0 -0
- package/__tests__/publicWwwTest/index.html +0 -11
- package/__tests__/publicWwwTest/prova file .txt +0 -2
- package/__tests__/publicWwwTest/semplicetxt.txt +0 -1
- package/__tests__/publicWwwTest/test-page.html +0 -1
- package/__tests__/publicWwwTest/test.txt +0 -1
- package/__tests__/range-fixtures/sample.txt +0 -1
- package/__tests__/range.test.js +0 -223
- package/__tests__/security-headers.test.js +0 -165
- package/__tests__/security.test.js +0 -322
- package/__tests__/server-cache-fixtures/large.txt +0 -1
- package/__tests__/server-cache-fixtures/small.txt +0 -1
- package/__tests__/server-cache.test.js +0 -594
- package/__tests__/setup-benchmark.js +0 -178
- package/__tests__/symlink.test.js +0 -441
- package/__tests__/template-timeout.test.js +0 -321
- package/__tests__/test-regex-quick.js +0 -158
- package/__tests__/useOriginalUrl.test.js +0 -213
- package/docs/ACTION_PLAN.md +0 -293
- package/docs/BENCHMARKS.md +0 -317
- package/docs/CHANGELOG.md +0 -880
- package/docs/CODE_REVIEW.md +0 -300
- package/docs/DEBUG_REPORT.md +0 -593
- package/docs/DOCUMENTATION.md +0 -1864
- package/docs/EXAMPLES_INDEX_OPTION.md +0 -395
- package/docs/FLOW_DIAGRAM.md +0 -954
- package/docs/INDEX_OPTION_PRIORITY.md +0 -527
- package/docs/OPTIMIZATION_HTTP_CACHING.md +0 -689
- package/docs/OPTIMIZATION_ROADMAP_for_V3.md +0 -864
- package/docs/PERFORMANCE_ANALYSIS.md +0 -839
- package/docs/PERFORMANCE_COMPARISON.md +0 -388
- package/docs/noteExports.md +0 -148
- package/docs/security_improvement_for_V3.md +0 -421
- package/docs/template-engine/TEMPLATE_ENGINE_GUIDE.md +0 -1734
- package/docs/template-engine/esempi-incrementali.js +0 -192
- package/docs/template-engine/examples/esempio1-nessun-dato.ejs +0 -12
- package/docs/template-engine/examples/esempio2-una-variabile.ejs +0 -11
- package/docs/template-engine/examples/esempio3-piu-variabili.ejs +0 -15
- package/docs/template-engine/examples/esempio4-condizionale.ejs +0 -18
- package/docs/template-engine/examples/esempio5-loop.ejs +0 -18
- package/docs/template-engine/examples/index-esempi.html +0 -181
- package/docs/template-engine/examples/index.html +0 -40
- package/docs/template-engine/examples/test.ejs +0 -64
- package/eslint.config.mjs +0 -17
- package/jest.config.js +0 -18
|
@@ -1,370 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Performance Benchmark Tests
|
|
3
|
-
*
|
|
4
|
-
* These tests measure current performance to establish a baseline.
|
|
5
|
-
* After optimizations, run these tests again to measure improvements.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* npm run test:performance
|
|
9
|
-
*
|
|
10
|
-
* To save results:
|
|
11
|
-
* npm run test:performance > benchmark-results-v1.2.0.txt
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
const Koa = require('koa');
|
|
15
|
-
const supertest = require('supertest');
|
|
16
|
-
const koaClassicServer = require('../index.cjs');
|
|
17
|
-
const path = require('path');
|
|
18
|
-
const fs = require('fs');
|
|
19
|
-
|
|
20
|
-
const BENCHMARK_DIR = path.join(__dirname, 'benchmark-data');
|
|
21
|
-
|
|
22
|
-
// Auto-setup benchmark data if not exists
|
|
23
|
-
function setupBenchmarkData() {
|
|
24
|
-
if (fs.existsSync(BENCHMARK_DIR)) {
|
|
25
|
-
return; // Data already exists
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
console.log('\n🔧 Setting up benchmark data automatically...\n');
|
|
29
|
-
|
|
30
|
-
// Create benchmark directory
|
|
31
|
-
fs.mkdirSync(BENCHMARK_DIR, { recursive: true });
|
|
32
|
-
|
|
33
|
-
// Create small files (1KB each)
|
|
34
|
-
console.log(' Creating 100 small files (1KB each)...');
|
|
35
|
-
const smallDir = path.join(BENCHMARK_DIR, 'small-files');
|
|
36
|
-
fs.mkdirSync(smallDir);
|
|
37
|
-
for (let i = 1; i <= 100; i++) {
|
|
38
|
-
const content = 'X'.repeat(1024);
|
|
39
|
-
fs.writeFileSync(path.join(smallDir, `file-${i}.txt`), content);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Create medium files (100KB each)
|
|
43
|
-
console.log(' Creating 50 medium files (100KB each)...');
|
|
44
|
-
const mediumDir = path.join(BENCHMARK_DIR, 'medium-files');
|
|
45
|
-
fs.mkdirSync(mediumDir);
|
|
46
|
-
for (let i = 1; i <= 50; i++) {
|
|
47
|
-
const content = 'X'.repeat(100 * 1024);
|
|
48
|
-
fs.writeFileSync(path.join(mediumDir, `file-${i}.txt`), content);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Create large files (1MB each)
|
|
52
|
-
console.log(' Creating 10 large files (1MB each)...');
|
|
53
|
-
const largeDir = path.join(BENCHMARK_DIR, 'large-files');
|
|
54
|
-
fs.mkdirSync(largeDir);
|
|
55
|
-
for (let i = 1; i <= 10; i++) {
|
|
56
|
-
const content = 'X'.repeat(1024 * 1024);
|
|
57
|
-
fs.writeFileSync(path.join(largeDir, `file-${i}.txt`), content);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Create directory with 1000 files
|
|
61
|
-
console.log(' Creating directory with 1000 files...');
|
|
62
|
-
const largeDirListing = path.join(BENCHMARK_DIR, 'large-directory');
|
|
63
|
-
fs.mkdirSync(largeDirListing);
|
|
64
|
-
for (let i = 1; i <= 1000; i++) {
|
|
65
|
-
const content = `File number ${i}\n`;
|
|
66
|
-
fs.writeFileSync(path.join(largeDirListing, `item-${String(i).padStart(4, '0')}.txt`), content);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Create directory with 10,000 files
|
|
70
|
-
console.log(' Creating directory with 10,000 files (this may take a moment)...');
|
|
71
|
-
const veryLargeDirListing = path.join(BENCHMARK_DIR, 'very-large-directory');
|
|
72
|
-
fs.mkdirSync(veryLargeDirListing);
|
|
73
|
-
for (let i = 1; i <= 10000; i++) {
|
|
74
|
-
const content = `File number ${i}\n`;
|
|
75
|
-
fs.writeFileSync(path.join(veryLargeDirListing, `item-${String(i).padStart(5, '0')}.txt`), content);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Create HTML file for caching test
|
|
79
|
-
const htmlContent = `<!DOCTYPE html>
|
|
80
|
-
<html>
|
|
81
|
-
<head>
|
|
82
|
-
<meta charset="UTF-8">
|
|
83
|
-
<title>Benchmark Test</title>
|
|
84
|
-
</head>
|
|
85
|
-
<body>
|
|
86
|
-
<h1>Benchmark Test Page</h1>
|
|
87
|
-
<p>${'Lorem ipsum dolor sit amet. '.repeat(100)}</p>
|
|
88
|
-
</body>
|
|
89
|
-
</html>`;
|
|
90
|
-
fs.writeFileSync(path.join(BENCHMARK_DIR, 'test.html'), htmlContent);
|
|
91
|
-
|
|
92
|
-
console.log('\n✅ Benchmark data setup complete!\n');
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Setup benchmark data automatically if needed
|
|
96
|
-
setupBenchmarkData();
|
|
97
|
-
|
|
98
|
-
// Helper to measure execution time
|
|
99
|
-
function measureTime(fn) {
|
|
100
|
-
const start = process.hrtime.bigint();
|
|
101
|
-
const result = fn();
|
|
102
|
-
const end = process.hrtime.bigint();
|
|
103
|
-
const durationMs = Number(end - start) / 1000000; // Convert to ms
|
|
104
|
-
return { result, durationMs };
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
async function measureTimeAsync(fn) {
|
|
108
|
-
const start = process.hrtime.bigint();
|
|
109
|
-
const result = await fn();
|
|
110
|
-
const end = process.hrtime.bigint();
|
|
111
|
-
const durationMs = Number(end - start) / 1000000;
|
|
112
|
-
return { result, durationMs };
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Helper to run multiple iterations and get statistics
|
|
116
|
-
async function benchmark(name, fn, iterations = 10) {
|
|
117
|
-
const times = [];
|
|
118
|
-
|
|
119
|
-
for (let i = 0; i < iterations; i++) {
|
|
120
|
-
const { durationMs } = await measureTimeAsync(fn);
|
|
121
|
-
times.push(durationMs);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const avg = times.reduce((a, b) => a + b, 0) / times.length;
|
|
125
|
-
const min = Math.min(...times);
|
|
126
|
-
const max = Math.max(...times);
|
|
127
|
-
const median = times.sort((a, b) => a - b)[Math.floor(times.length / 2)];
|
|
128
|
-
|
|
129
|
-
return { name, avg, min, max, median, times };
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
describe('Performance Benchmarks - BASELINE (v1.2.0)', () => {
|
|
133
|
-
let app;
|
|
134
|
-
let server;
|
|
135
|
-
let request;
|
|
136
|
-
|
|
137
|
-
beforeAll(() => {
|
|
138
|
-
app = new Koa();
|
|
139
|
-
app.use(koaClassicServer(BENCHMARK_DIR));
|
|
140
|
-
server = app.listen();
|
|
141
|
-
request = supertest(server);
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
afterAll(() => {
|
|
145
|
-
server.close();
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
describe('File Serving Performance', () => {
|
|
149
|
-
test('Benchmark: Small file (1KB) - 100 iterations', async () => {
|
|
150
|
-
const stats = await benchmark(
|
|
151
|
-
'Small file (1KB)',
|
|
152
|
-
async () => {
|
|
153
|
-
const res = await request.get('/small-files/file-1.txt');
|
|
154
|
-
expect(res.status).toBe(200);
|
|
155
|
-
},
|
|
156
|
-
100
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
console.log('\n📊 Small File (1KB) Benchmark:');
|
|
160
|
-
console.log(` Average: ${stats.avg.toFixed(2)}ms`);
|
|
161
|
-
console.log(` Median: ${stats.median.toFixed(2)}ms`);
|
|
162
|
-
console.log(` Min: ${stats.min.toFixed(2)}ms`);
|
|
163
|
-
console.log(` Max: ${stats.max.toFixed(2)}ms`);
|
|
164
|
-
|
|
165
|
-
expect(stats.avg).toBeLessThan(50); // Should be fast
|
|
166
|
-
}, 30000);
|
|
167
|
-
|
|
168
|
-
test('Benchmark: Medium file (100KB) - 50 iterations', async () => {
|
|
169
|
-
const stats = await benchmark(
|
|
170
|
-
'Medium file (100KB)',
|
|
171
|
-
async () => {
|
|
172
|
-
const res = await request.get('/medium-files/file-1.txt');
|
|
173
|
-
expect(res.status).toBe(200);
|
|
174
|
-
},
|
|
175
|
-
50
|
|
176
|
-
);
|
|
177
|
-
|
|
178
|
-
console.log('\n📊 Medium File (100KB) Benchmark:');
|
|
179
|
-
console.log(` Average: ${stats.avg.toFixed(2)}ms`);
|
|
180
|
-
console.log(` Median: ${stats.median.toFixed(2)}ms`);
|
|
181
|
-
console.log(` Min: ${stats.min.toFixed(2)}ms`);
|
|
182
|
-
console.log(` Max: ${stats.max.toFixed(2)}ms`);
|
|
183
|
-
|
|
184
|
-
expect(stats.avg).toBeLessThan(100);
|
|
185
|
-
}, 30000);
|
|
186
|
-
|
|
187
|
-
test('Benchmark: Large file (1MB) - 20 iterations', async () => {
|
|
188
|
-
const stats = await benchmark(
|
|
189
|
-
'Large file (1MB)',
|
|
190
|
-
async () => {
|
|
191
|
-
const res = await request.get('/large-files/file-1.txt');
|
|
192
|
-
expect(res.status).toBe(200);
|
|
193
|
-
},
|
|
194
|
-
20
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
console.log('\n📊 Large File (1MB) Benchmark:');
|
|
198
|
-
console.log(` Average: ${stats.avg.toFixed(2)}ms`);
|
|
199
|
-
console.log(` Median: ${stats.median.toFixed(2)}ms`);
|
|
200
|
-
console.log(` Min: ${stats.min.toFixed(2)}ms`);
|
|
201
|
-
console.log(` Max: ${stats.max.toFixed(2)}ms`);
|
|
202
|
-
|
|
203
|
-
expect(stats.avg).toBeLessThan(500);
|
|
204
|
-
}, 30000);
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
describe('Directory Listing Performance', () => {
|
|
208
|
-
test('Benchmark: Small directory (100 files) - 50 iterations', async () => {
|
|
209
|
-
const stats = await benchmark(
|
|
210
|
-
'Directory listing (100 files)',
|
|
211
|
-
async () => {
|
|
212
|
-
const res = await request.get('/small-files/');
|
|
213
|
-
expect(res.status).toBe(200);
|
|
214
|
-
expect(res.text).toContain('file-1.txt');
|
|
215
|
-
},
|
|
216
|
-
50
|
|
217
|
-
);
|
|
218
|
-
|
|
219
|
-
console.log('\n📊 Small Directory (100 files) Benchmark:');
|
|
220
|
-
console.log(` Average: ${stats.avg.toFixed(2)}ms`);
|
|
221
|
-
console.log(` Median: ${stats.median.toFixed(2)}ms`);
|
|
222
|
-
console.log(` Min: ${stats.min.toFixed(2)}ms`);
|
|
223
|
-
console.log(` Max: ${stats.max.toFixed(2)}ms`);
|
|
224
|
-
}, 30000);
|
|
225
|
-
|
|
226
|
-
test('Benchmark: Large directory (1,000 files) - 20 iterations', async () => {
|
|
227
|
-
const stats = await benchmark(
|
|
228
|
-
'Directory listing (1,000 files)',
|
|
229
|
-
async () => {
|
|
230
|
-
const res = await request.get('/large-directory/');
|
|
231
|
-
expect(res.status).toBe(200);
|
|
232
|
-
expect(res.text).toContain('item-0001.txt');
|
|
233
|
-
},
|
|
234
|
-
20
|
|
235
|
-
);
|
|
236
|
-
|
|
237
|
-
console.log('\n📊 Large Directory (1,000 files) Benchmark:');
|
|
238
|
-
console.log(` Average: ${stats.avg.toFixed(2)}ms`);
|
|
239
|
-
console.log(` Median: ${stats.median.toFixed(2)}ms`);
|
|
240
|
-
console.log(` Min: ${stats.min.toFixed(2)}ms`);
|
|
241
|
-
console.log(` Max: ${stats.max.toFixed(2)}ms`);
|
|
242
|
-
|
|
243
|
-
// This is expected to be slow with current sync implementation
|
|
244
|
-
console.log(` ⚠️ WARNING: This will be MUCH faster after async optimization`);
|
|
245
|
-
}, 60000);
|
|
246
|
-
|
|
247
|
-
test('Benchmark: Very large directory (10,000 files) - 5 iterations', async () => {
|
|
248
|
-
const stats = await benchmark(
|
|
249
|
-
'Directory listing (10,000 files)',
|
|
250
|
-
async () => {
|
|
251
|
-
const res = await request.get('/very-large-directory/');
|
|
252
|
-
expect(res.status).toBe(200);
|
|
253
|
-
expect(res.text).toContain('item-00001.txt');
|
|
254
|
-
},
|
|
255
|
-
5
|
|
256
|
-
);
|
|
257
|
-
|
|
258
|
-
console.log('\n📊 Very Large Directory (10,000 files) Benchmark:');
|
|
259
|
-
console.log(` Average: ${stats.avg.toFixed(2)}ms`);
|
|
260
|
-
console.log(` Median: ${stats.median.toFixed(2)}ms`);
|
|
261
|
-
console.log(` Min: ${stats.min.toFixed(2)}ms`);
|
|
262
|
-
console.log(` Max: ${stats.max.toFixed(2)}ms`);
|
|
263
|
-
console.log(` ⚠️ WARNING: Event loop BLOCKED during this operation!`);
|
|
264
|
-
console.log(` ⚠️ Expected to drop to ~${(stats.avg * 0.3).toFixed(2)}ms after optimization`);
|
|
265
|
-
}, 120000);
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
describe('Concurrent Request Performance', () => {
|
|
269
|
-
test('Benchmark: 10 concurrent small file requests', async () => {
|
|
270
|
-
const start = process.hrtime.bigint();
|
|
271
|
-
|
|
272
|
-
const promises = Array.from({ length: 10 }, (_, i) =>
|
|
273
|
-
request.get(`/small-files/file-${i + 1}.txt`)
|
|
274
|
-
);
|
|
275
|
-
|
|
276
|
-
const results = await Promise.all(promises);
|
|
277
|
-
|
|
278
|
-
const end = process.hrtime.bigint();
|
|
279
|
-
const totalTime = Number(end - start) / 1000000;
|
|
280
|
-
|
|
281
|
-
console.log('\n📊 10 Concurrent Small Files:');
|
|
282
|
-
console.log(` Total time: ${totalTime.toFixed(2)}ms`);
|
|
283
|
-
console.log(` Avg per request: ${(totalTime / 10).toFixed(2)}ms`);
|
|
284
|
-
|
|
285
|
-
results.forEach(res => expect(res.status).toBe(200));
|
|
286
|
-
}, 10000);
|
|
287
|
-
|
|
288
|
-
test('Benchmark: 5 concurrent directory listings (100 files each)', async () => {
|
|
289
|
-
const start = process.hrtime.bigint();
|
|
290
|
-
|
|
291
|
-
const promises = Array.from({ length: 5 }, () =>
|
|
292
|
-
request.get('/small-files/')
|
|
293
|
-
);
|
|
294
|
-
|
|
295
|
-
const results = await Promise.all(promises);
|
|
296
|
-
|
|
297
|
-
const end = process.hrtime.bigint();
|
|
298
|
-
const totalTime = Number(end - start) / 1000000;
|
|
299
|
-
|
|
300
|
-
console.log('\n📊 5 Concurrent Directory Listings (100 files):');
|
|
301
|
-
console.log(` Total time: ${totalTime.toFixed(2)}ms`);
|
|
302
|
-
console.log(` Avg per request: ${(totalTime / 5).toFixed(2)}ms`);
|
|
303
|
-
console.log(` ⚠️ With current sync code, these run SEQUENTIALLY`);
|
|
304
|
-
console.log(` ⚠️ After async optimization, will run in PARALLEL`);
|
|
305
|
-
|
|
306
|
-
results.forEach(res => expect(res.status).toBe(200));
|
|
307
|
-
}, 30000);
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
describe('404 Not Found Performance', () => {
|
|
311
|
-
test('Benchmark: Non-existent file - 50 iterations', async () => {
|
|
312
|
-
const stats = await benchmark(
|
|
313
|
-
'404 Not Found',
|
|
314
|
-
async () => {
|
|
315
|
-
const res = await request.get('/does-not-exist-12345.txt');
|
|
316
|
-
expect(res.status).toBe(404);
|
|
317
|
-
},
|
|
318
|
-
50
|
|
319
|
-
);
|
|
320
|
-
|
|
321
|
-
console.log('\n📊 404 Not Found Benchmark:');
|
|
322
|
-
console.log(` Average: ${stats.avg.toFixed(2)}ms`);
|
|
323
|
-
console.log(` Median: ${stats.median.toFixed(2)}ms`);
|
|
324
|
-
console.log(` Min: ${stats.min.toFixed(2)}ms`);
|
|
325
|
-
console.log(` Max: ${stats.max.toFixed(2)}ms`);
|
|
326
|
-
}, 10000);
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
describe('Memory Usage (Informational)', () => {
|
|
330
|
-
test('Memory usage during large directory listing', async () => {
|
|
331
|
-
// Force garbage collection if available
|
|
332
|
-
if (global.gc) {
|
|
333
|
-
global.gc();
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
const memBefore = process.memoryUsage();
|
|
337
|
-
|
|
338
|
-
// Request large directory
|
|
339
|
-
const res = await request.get('/very-large-directory/');
|
|
340
|
-
expect(res.status).toBe(200);
|
|
341
|
-
|
|
342
|
-
const memAfter = process.memoryUsage();
|
|
343
|
-
|
|
344
|
-
const heapUsedDiff = (memAfter.heapUsed - memBefore.heapUsed) / 1024 / 1024;
|
|
345
|
-
const externalDiff = (memAfter.external - memBefore.external) / 1024 / 1024;
|
|
346
|
-
|
|
347
|
-
console.log('\n📊 Memory Usage (10,000 files directory):');
|
|
348
|
-
console.log(` Heap used increase: ${heapUsedDiff.toFixed(2)} MB`);
|
|
349
|
-
console.log(` External increase: ${externalDiff.toFixed(2)} MB`);
|
|
350
|
-
console.log(` Response size: ${(res.text.length / 1024 / 1024).toFixed(2)} MB`);
|
|
351
|
-
console.log(` ⚠️ Expected to reduce by ~30-40% after optimization`);
|
|
352
|
-
}, 30000);
|
|
353
|
-
});
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
// Summary report
|
|
357
|
-
afterAll(() => {
|
|
358
|
-
console.log('\n' + '='.repeat(70));
|
|
359
|
-
console.log('📋 BASELINE BENCHMARK SUMMARY');
|
|
360
|
-
console.log('='.repeat(70));
|
|
361
|
-
console.log('\nThese results represent the CURRENT performance (v1.2.0)');
|
|
362
|
-
console.log('After implementing optimizations, run this test again to see improvements.\n');
|
|
363
|
-
console.log('Expected improvements after optimization:');
|
|
364
|
-
console.log(' ✓ Small files: 10-20% faster (async operations)');
|
|
365
|
-
console.log(' ✓ Large directories: 50-70% faster (async + array join)');
|
|
366
|
-
console.log(' ✓ Concurrent requests: 5-10x faster (non-blocking event loop)');
|
|
367
|
-
console.log(' ✓ Memory usage: 30-40% reduction (array join vs concatenation)');
|
|
368
|
-
console.log(' ✓ With HTTP caching: 80-95% faster (304 responses)');
|
|
369
|
-
console.log('='.repeat(70) + '\n');
|
|
370
|
-
});
|
package/__tests__/publicWwwTest/cartella vuota con spazi nel nome/file con spazio nel nome .txt
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
hello world
|
package/__tests__/publicWwwTest/cartella vuota con spazi nel nome /file con spazio nel nome .txt
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
hello world
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="it">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<title><%= pageTitle %></title>
|
|
6
|
-
<style>
|
|
7
|
-
.product { border: 1px solid #ccc; padding: 10px; margin: 10px 0; }
|
|
8
|
-
.price { color: green; font-weight: bold; }
|
|
9
|
-
.discount { color: red; }
|
|
10
|
-
</style>
|
|
11
|
-
</head>
|
|
12
|
-
<body>
|
|
13
|
-
<h1><%= pageTitle %></h1>
|
|
14
|
-
|
|
15
|
-
<% if (user) { %>
|
|
16
|
-
<div class="user-info">
|
|
17
|
-
<p>Ciao, <%= user.name %>!</p>
|
|
18
|
-
</div>
|
|
19
|
-
<% } %>
|
|
20
|
-
|
|
21
|
-
<h2>Prodotti Disponibili</h2>
|
|
22
|
-
|
|
23
|
-
<% if (products && products.length > 0) { %>
|
|
24
|
-
<div class="products">
|
|
25
|
-
<% products.forEach(function(product) { %>
|
|
26
|
-
<div class="product" data-id="<%= product.id %>">
|
|
27
|
-
<h3><%= product.name %></h3>
|
|
28
|
-
<p><%= product.description %></p>
|
|
29
|
-
<p class="price">Prezzo: €<%= product.price.toFixed(2) %></p>
|
|
30
|
-
|
|
31
|
-
<% if (product.discount > 0) { %>
|
|
32
|
-
<p class="discount">Sconto: <%= product.discount %>%</p>
|
|
33
|
-
<p class="final-price">
|
|
34
|
-
Prezzo finale: €<%= (product.price * (1 - product.discount / 100)).toFixed(2) %>
|
|
35
|
-
</p>
|
|
36
|
-
<% } %>
|
|
37
|
-
|
|
38
|
-
<% if (product.inStock) { %>
|
|
39
|
-
<button>Aggiungi al carrello</button>
|
|
40
|
-
<% } else { %>
|
|
41
|
-
<p class="out-of-stock">Non disponibile</p>
|
|
42
|
-
<% } %>
|
|
43
|
-
</div>
|
|
44
|
-
<% }); %>
|
|
45
|
-
</div>
|
|
46
|
-
|
|
47
|
-
<p>Totale prodotti: <%= products.length %></p>
|
|
48
|
-
<% } else { %>
|
|
49
|
-
<p>Nessun prodotto disponibile al momento.</p>
|
|
50
|
-
<% } %>
|
|
51
|
-
|
|
52
|
-
<footer>
|
|
53
|
-
<p>Generato il: <%= new Date().toLocaleDateString('it-IT') %></p>
|
|
54
|
-
</footer>
|
|
55
|
-
</body>
|
|
56
|
-
</html>
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="it">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>EJS Templates - Index</title>
|
|
7
|
-
<style>
|
|
8
|
-
body { font-family: Arial, sans-serif; max-width: 800px; margin: 50px auto; padding: 20px; }
|
|
9
|
-
h1 { color: #333; }
|
|
10
|
-
ul { list-style: none; padding: 0; }
|
|
11
|
-
li { margin: 10px 0; }
|
|
12
|
-
a { color: #007bff; text-decoration: none; padding: 8px 12px; display: inline-block; border: 1px solid #007bff; border-radius: 4px; }
|
|
13
|
-
a:hover { background: #007bff; color: white; }
|
|
14
|
-
</style>
|
|
15
|
-
</head>
|
|
16
|
-
<body>
|
|
17
|
-
<h1>Test Templates EJS</h1>
|
|
18
|
-
<p>Questa directory contiene vari template EJS per testare diverse funzionalità:</p>
|
|
19
|
-
|
|
20
|
-
<ul>
|
|
21
|
-
<li><a href="simple.ejs">simple.ejs</a> - Template semplice con variabili</li>
|
|
22
|
-
<li><a href="with-loop.ejs">with-loop.ejs</a> - Template con cicli forEach</li>
|
|
23
|
-
<li><a href="with-conditional.ejs">with-conditional.ejs</a> - Template con condizionali if/else</li>
|
|
24
|
-
<li><a href="with-escaping.ejs">with-escaping.ejs</a> - Template con HTML escaping</li>
|
|
25
|
-
<li><a href="complex.ejs">complex.ejs</a> - Template complesso con tutto combinato</li>
|
|
26
|
-
</ul>
|
|
27
|
-
|
|
28
|
-
<p><strong>Nota:</strong> Questi template richiedono che il server passi i dati appropriati tramite la funzione render.</p>
|
|
29
|
-
</body>
|
|
30
|
-
</html>
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="it">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title><%= title %></title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<h1><%= heading %></h1>
|
|
10
|
-
<p><%= message %></p>
|
|
11
|
-
<p>Timestamp: <%= timestamp %></p>
|
|
12
|
-
</body>
|
|
13
|
-
</html>
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="it">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<title>EJS Conditional Test</title>
|
|
6
|
-
</head>
|
|
7
|
-
<body>
|
|
8
|
-
<h1>Test Condizionali</h1>
|
|
9
|
-
|
|
10
|
-
<% if (isLoggedIn) { %>
|
|
11
|
-
<div class="user-panel">
|
|
12
|
-
<p>Benvenuto, <%= username %>!</p>
|
|
13
|
-
<p>Ruolo: <%= role %></p>
|
|
14
|
-
</div>
|
|
15
|
-
<% } else { %>
|
|
16
|
-
<div class="guest-panel">
|
|
17
|
-
<p>Benvenuto, ospite!</p>
|
|
18
|
-
<a href="/login">Login</a>
|
|
19
|
-
</div>
|
|
20
|
-
<% } %>
|
|
21
|
-
|
|
22
|
-
<% if (notifications > 0) { %>
|
|
23
|
-
<div class="notifications">
|
|
24
|
-
<p>Hai <%= notifications %> nuove notifiche</p>
|
|
25
|
-
</div>
|
|
26
|
-
<% } %>
|
|
27
|
-
</body>
|
|
28
|
-
</html>
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="it">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<title>EJS Escaping Test</title>
|
|
6
|
-
</head>
|
|
7
|
-
<body>
|
|
8
|
-
<h1>Test HTML Escaping</h1>
|
|
9
|
-
|
|
10
|
-
<div class="escaped">
|
|
11
|
-
<h2>HTML Escaped (safe):</h2>
|
|
12
|
-
<p><%= userInput %></p>
|
|
13
|
-
</div>
|
|
14
|
-
|
|
15
|
-
<div class="unescaped">
|
|
16
|
-
<h2>HTML Unescaped (unsafe - solo per test):</h2>
|
|
17
|
-
<p><%- htmlContent %></p>
|
|
18
|
-
</div>
|
|
19
|
-
|
|
20
|
-
<div class="mixed">
|
|
21
|
-
<h2>Mixed Content:</h2>
|
|
22
|
-
<p>Safe: <%= safeText %></p>
|
|
23
|
-
<p>HTML: <%- allowedHtml %></p>
|
|
24
|
-
</div>
|
|
25
|
-
</body>
|
|
26
|
-
</html>
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="it">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<title>EJS Loop Test</title>
|
|
6
|
-
</head>
|
|
7
|
-
<body>
|
|
8
|
-
<h1>Lista di Items</h1>
|
|
9
|
-
<ul>
|
|
10
|
-
<% items.forEach(function(item, index) { %>
|
|
11
|
-
<li data-index="<%= index %>"><%= item.name %> - <%= item.value %></li>
|
|
12
|
-
<% }); %>
|
|
13
|
-
</ul>
|
|
14
|
-
<p>Totale items: <%= items.length %></p>
|
|
15
|
-
</body>
|
|
16
|
-
</html>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<h1>About Directory Index</h1>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<h1>About UPPERCASE</h1>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
plain pagina file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<h1>Pagina EJS</h1>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
backup file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
This is a photo description file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<h1>Sezione Index</h1>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
body { color: red; }
|
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
hello world
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><title>Test Page</title></head><body><h1>Test Page</h1></body></html>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
hello world
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0123456789abcdefghij
|