koa-classic-server 1.1.0 → 2.0.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/BENCHMARKS.md +317 -0
- package/CHANGELOG.md +181 -0
- package/CREATE_RELEASE.sh +53 -0
- package/DEBUG_REPORT.md +593 -0
- package/DOCUMENTATION.md +1585 -0
- package/EXAMPLES_INDEX_OPTION.md +395 -0
- package/INDEX_OPTION_PRIORITY.md +527 -0
- package/LICENSE +21 -0
- package/OPTIMIZATION_HTTP_CACHING.md +687 -0
- package/PERFORMANCE_ANALYSIS.md +839 -0
- package/PERFORMANCE_COMPARISON.md +388 -0
- package/README.md +278 -103
- package/__tests__/index-option.test.js +447 -0
- package/__tests__/index.test.js +15 -11
- package/__tests__/performance.test.js +301 -0
- package/__tests__/publicWwwTest/cartella vuota con spazi nel nome/file con spazio nel nome .txt +1 -0
- package/__tests__/security.test.js +336 -0
- package/benchmark-results-baseline-v1.2.0.txt +354 -0
- package/benchmark-results-optimized-v2.0.0.txt +354 -0
- package/benchmark.js +239 -0
- package/demo-regex-index.js +140 -0
- package/index.cjs +386 -156
- package/jest.config.js +18 -0
- package/package.json +18 -5
- package/publish-to-npm.sh +65 -0
- package/scripts/setup-benchmark.js +178 -0
- package/test-regex-quick.js +158 -0
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
# Enhanced Index Option - Esempi Pratici
|
|
2
|
+
|
|
3
|
+
## ⚠️ Formato Raccomandato: Array
|
|
4
|
+
|
|
5
|
+
**IMPORTANTE:** L'opzione `index` deve essere usata in **formato array**. Il formato stringa è **deprecato** e verrà rimosso in versioni future.
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
// ✅ RACCOMANDATO
|
|
9
|
+
index: ['index.html']
|
|
10
|
+
index: ['index.html', 'index.htm']
|
|
11
|
+
index: [/index\.html/i]
|
|
12
|
+
|
|
13
|
+
// ⚠️ DEPRECATO (genera warning)
|
|
14
|
+
index: 'index.html' // NON usare! Usa ['index.html'] invece
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Opzione index con RegExp - Casi d'uso reali
|
|
20
|
+
|
|
21
|
+
### 1. Case-insensitive matching (Windows/Mac filesystems)
|
|
22
|
+
|
|
23
|
+
```javascript
|
|
24
|
+
const Koa = require('koa');
|
|
25
|
+
const koaClassicServer = require('koa-classic-server');
|
|
26
|
+
|
|
27
|
+
const app = new Koa();
|
|
28
|
+
|
|
29
|
+
// Trova index.html, INDEX.HTML, Index.Html, INDEX.html, etc.
|
|
30
|
+
app.use(koaClassicServer('./public', {
|
|
31
|
+
index: [/index\.html/i]
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
app.listen(3000);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Cosa matcha:**
|
|
38
|
+
- `index.html`
|
|
39
|
+
- `INDEX.HTML`
|
|
40
|
+
- `Index.Html`
|
|
41
|
+
- `INDEX.html`
|
|
42
|
+
- `InDeX.HtMl`
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
### 2. Multiple estensioni con case-insensitive
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
// Trova index.html, index.htm, INDEX.HTML, Index.HTM, etc.
|
|
50
|
+
app.use(koaClassicServer('./public', {
|
|
51
|
+
index: [/index\.(html|htm)/i]
|
|
52
|
+
}));
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Cosa matcha:**
|
|
56
|
+
- `index.html`
|
|
57
|
+
- `index.htm`
|
|
58
|
+
- `INDEX.HTML`
|
|
59
|
+
- `INDEX.HTM`
|
|
60
|
+
- `Index.Html`
|
|
61
|
+
- `Index.Htm`
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
### 3. Template engines con varianti di case
|
|
66
|
+
|
|
67
|
+
```javascript
|
|
68
|
+
// Trova index.ejs, INDEX.EJS, index.pug, INDEX.PUG, etc.
|
|
69
|
+
app.use(koaClassicServer('./views', {
|
|
70
|
+
index: [
|
|
71
|
+
/index\.ejs/i,
|
|
72
|
+
/index\.pug/i,
|
|
73
|
+
/index\.html/i
|
|
74
|
+
]
|
|
75
|
+
}));
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Priorità:** Primo match vince
|
|
79
|
+
- Prima cerca: index.ejs, INDEX.EJS, Index.Ejs, etc.
|
|
80
|
+
- Poi cerca: index.pug, INDEX.PUG, Index.Pug, etc.
|
|
81
|
+
- Infine cerca: index.html, INDEX.HTML, Index.Html, etc.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
### 4. Pattern complessi con numeri
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
// Trova index.html, index1.html, index2.html, INDEX10.HTML, etc.
|
|
89
|
+
app.use(koaClassicServer('./public', {
|
|
90
|
+
index: [/index\d*\.html/i]
|
|
91
|
+
}));
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Cosa matcha:**
|
|
95
|
+
- `index.html`
|
|
96
|
+
- `index1.html`
|
|
97
|
+
- `index2.html`
|
|
98
|
+
- `index10.html`
|
|
99
|
+
- `INDEX.HTML`
|
|
100
|
+
- `INDEX99.HTML`
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
### 5. Default files con varianti
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
// Cerca default.html, default.htm, DEFAULT.HTML, etc.
|
|
108
|
+
app.use(koaClassicServer('./public', {
|
|
109
|
+
index: [
|
|
110
|
+
/index\.(html|htm)/i,
|
|
111
|
+
/default\.(html|htm)/i,
|
|
112
|
+
/home\.(html|htm)/i
|
|
113
|
+
]
|
|
114
|
+
}));
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Priorità:**
|
|
118
|
+
1. index.html/htm (qualsiasi case)
|
|
119
|
+
2. default.html/htm (qualsiasi case)
|
|
120
|
+
3. home.html/htm (qualsiasi case)
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### 6. Configurazione tipo Apache (mixed string + RegExp)
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
// Best practice: Stringhe esatte prima, RegExp dopo
|
|
128
|
+
app.use(koaClassicServer('./public', {
|
|
129
|
+
index: [
|
|
130
|
+
'index.html', // 1. Exact match (più veloce)
|
|
131
|
+
'index.htm', // 2. Exact match
|
|
132
|
+
/INDEX\.HTML/i, // 3. Case-insensitive fallback
|
|
133
|
+
/default\.html/i // 4. Default fallback
|
|
134
|
+
]
|
|
135
|
+
}));
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Perché questo ordine:**
|
|
139
|
+
- String matching è più veloce di RegExp
|
|
140
|
+
- Specifico prima (index.html) → generico dopo (/default\.html/i)
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
### 7. Pattern avanzati con gruppi opzionali
|
|
145
|
+
|
|
146
|
+
```javascript
|
|
147
|
+
// Trova: index, index.html, index.htm, INDEX, INDEX.HTML, etc.
|
|
148
|
+
app.use(koaClassicServer('./public', {
|
|
149
|
+
index: [/index(\.(html|htm))?/i]
|
|
150
|
+
}));
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Cosa matcha:**
|
|
154
|
+
- `index` (senza estensione!)
|
|
155
|
+
- `index.html`
|
|
156
|
+
- `index.htm`
|
|
157
|
+
- `INDEX`
|
|
158
|
+
- `INDEX.HTML`
|
|
159
|
+
- `INDEX.HTM`
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
### 8. Prefissi variabili (multilingua)
|
|
164
|
+
|
|
165
|
+
```javascript
|
|
166
|
+
// Supporto multilingua: index_en.html, index_it.html, INDEX_FR.HTML, etc.
|
|
167
|
+
app.use(koaClassicServer('./public', {
|
|
168
|
+
index: [
|
|
169
|
+
/index_[a-z]{2}\.html/i, // index_en.html, INDEX_IT.HTML
|
|
170
|
+
/index\.html/i // Fallback
|
|
171
|
+
]
|
|
172
|
+
}));
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**Cosa matcha:**
|
|
176
|
+
- `index_en.html`
|
|
177
|
+
- `index_it.html`
|
|
178
|
+
- `INDEX_FR.HTML`
|
|
179
|
+
- `index.html` (fallback)
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
### 9. Configurazione PHP-like
|
|
184
|
+
|
|
185
|
+
```javascript
|
|
186
|
+
// Simula configurazione Apache/PHP con DirectoryIndex
|
|
187
|
+
app.use(koaClassicServer('./public', {
|
|
188
|
+
index: [
|
|
189
|
+
'index.php',
|
|
190
|
+
'index.html',
|
|
191
|
+
'index.htm',
|
|
192
|
+
/INDEX\.(PHP|HTML|HTM)/i,
|
|
193
|
+
'default.php',
|
|
194
|
+
'default.html'
|
|
195
|
+
]
|
|
196
|
+
}));
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
### 10. Solo file che iniziano con "index"
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
204
|
+
// Matcha qualsiasi file che inizia con "index" (index.*, INDEX.*, Index.*)
|
|
205
|
+
app.use(koaClassicServer('./public', {
|
|
206
|
+
index: [/^index\./i]
|
|
207
|
+
}));
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Cosa matcha:**
|
|
211
|
+
- `index.html`
|
|
212
|
+
- `index.php`
|
|
213
|
+
- `index.ejs`
|
|
214
|
+
- `INDEX.CSS` (attenzione!)
|
|
215
|
+
- `Index.Anything`
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Performance Tips
|
|
220
|
+
|
|
221
|
+
### ✅ Best Practice: String prima, RegExp dopo
|
|
222
|
+
|
|
223
|
+
```javascript
|
|
224
|
+
// VELOCE ⚡
|
|
225
|
+
index: [
|
|
226
|
+
'index.html', // String match = O(1)
|
|
227
|
+
'index.htm', // String match = O(1)
|
|
228
|
+
/INDEX\.HTML/i // RegExp match = O(n)
|
|
229
|
+
]
|
|
230
|
+
|
|
231
|
+
// LENTO 🐌
|
|
232
|
+
index: [
|
|
233
|
+
/index\.html/i, // RegExp match = O(n)
|
|
234
|
+
/index\.htm/i, // RegExp match = O(n)
|
|
235
|
+
'index.html' // Mai raggiunto!
|
|
236
|
+
]
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### ✅ Pattern specifici prima, generici dopo
|
|
240
|
+
|
|
241
|
+
```javascript
|
|
242
|
+
// CORRETTO ✓
|
|
243
|
+
index: [
|
|
244
|
+
/^index\.html$/i, // Specifico: solo index.html
|
|
245
|
+
/^index\./i, // Generico: qualsiasi index.*
|
|
246
|
+
/\.(html|htm)$/i // Molto generico: qualsiasi .html/.htm
|
|
247
|
+
]
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Validazione automatica
|
|
253
|
+
|
|
254
|
+
Il middleware filtra automaticamente elementi non validi:
|
|
255
|
+
|
|
256
|
+
```javascript
|
|
257
|
+
app.use(koaClassicServer('./public', {
|
|
258
|
+
index: [
|
|
259
|
+
'index.html', // ✓ Valid: string
|
|
260
|
+
/index\.htm/i, // ✓ Valid: RegExp
|
|
261
|
+
123, // ✗ Filtrato: number
|
|
262
|
+
null, // ✗ Filtrato: null
|
|
263
|
+
undefined, // ✗ Filtrato: undefined
|
|
264
|
+
{}, // ✗ Filtrato: object
|
|
265
|
+
'default.html' // ✓ Valid: string
|
|
266
|
+
]
|
|
267
|
+
}));
|
|
268
|
+
|
|
269
|
+
// Risultato effettivo: ['index.html', /index\.htm/i, 'default.html']
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Testing
|
|
275
|
+
|
|
276
|
+
Per testare le tue configurazioni:
|
|
277
|
+
|
|
278
|
+
```javascript
|
|
279
|
+
const fs = require('fs');
|
|
280
|
+
const path = require('path');
|
|
281
|
+
|
|
282
|
+
// Crea file di test con vari case
|
|
283
|
+
const testDir = './test-index';
|
|
284
|
+
fs.mkdirSync(testDir, { recursive: true });
|
|
285
|
+
fs.writeFileSync(path.join(testDir, 'index.html'), '<h1>Found index.html</h1>');
|
|
286
|
+
fs.writeFileSync(path.join(testDir, 'INDEX.HTML'), '<h1>Found INDEX.HTML</h1>');
|
|
287
|
+
fs.writeFileSync(path.join(testDir, 'Index.Html'), '<h1>Found Index.Html</h1>');
|
|
288
|
+
|
|
289
|
+
// Testa quale viene trovato per primo
|
|
290
|
+
app.use(koaClassicServer(testDir, {
|
|
291
|
+
index: [/index\.html/i]
|
|
292
|
+
}));
|
|
293
|
+
|
|
294
|
+
// Apri http://localhost:3000 e verifica quale file viene servito
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Casi Edge
|
|
300
|
+
|
|
301
|
+
### File multipli con stesso pattern
|
|
302
|
+
|
|
303
|
+
Se ci sono più file che matchano lo stesso pattern, viene servito **il primo trovato nell'ordine di lettura della directory** (dipende dal filesystem):
|
|
304
|
+
|
|
305
|
+
```javascript
|
|
306
|
+
// Directory contiene: index.html, INDEX.HTML, Index.Html
|
|
307
|
+
app.use(koaClassicServer('./public', {
|
|
308
|
+
index: [/index\.html/i]
|
|
309
|
+
}));
|
|
310
|
+
|
|
311
|
+
// Risultato: Uno dei tre file (ordine non garantito)
|
|
312
|
+
// Per controllo deterministico, usa stringhe esatte
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Pattern che matchano troppo
|
|
316
|
+
|
|
317
|
+
```javascript
|
|
318
|
+
// ⚠️ ATTENZIONE: Pattern troppo generico!
|
|
319
|
+
app.use(koaClassicServer('./public', {
|
|
320
|
+
index: [/index/i] // Matcha anche: "my_index.txt", "reindex.html"
|
|
321
|
+
}));
|
|
322
|
+
|
|
323
|
+
// ✓ MEGLIO: Pattern specifico
|
|
324
|
+
app.use(koaClassicServer('./public', {
|
|
325
|
+
index: [/^index\./i] // Matcha solo: "index.*"
|
|
326
|
+
}));
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## Esempio Completo Real-World
|
|
332
|
+
|
|
333
|
+
```javascript
|
|
334
|
+
const Koa = require('koa');
|
|
335
|
+
const koaClassicServer = require('koa-classic-server');
|
|
336
|
+
|
|
337
|
+
const app = new Koa();
|
|
338
|
+
|
|
339
|
+
// Configurazione production-ready
|
|
340
|
+
app.use(koaClassicServer('./public', {
|
|
341
|
+
method: ['GET', 'HEAD'],
|
|
342
|
+
showDirContents: true,
|
|
343
|
+
|
|
344
|
+
// Index configuration con fallback multipli
|
|
345
|
+
index: [
|
|
346
|
+
// 1. Exact matches (fastest)
|
|
347
|
+
'index.html',
|
|
348
|
+
'index.htm',
|
|
349
|
+
|
|
350
|
+
// 2. Case-insensitive fallbacks
|
|
351
|
+
/INDEX\.HTML/i,
|
|
352
|
+
/INDEX\.HTM/i,
|
|
353
|
+
|
|
354
|
+
// 3. Default files
|
|
355
|
+
/default\.(html|htm)/i,
|
|
356
|
+
|
|
357
|
+
// 4. Home fallback
|
|
358
|
+
/home\.html/i
|
|
359
|
+
],
|
|
360
|
+
|
|
361
|
+
// HTTP Caching
|
|
362
|
+
enableCaching: true,
|
|
363
|
+
cacheMaxAge: 3600,
|
|
364
|
+
|
|
365
|
+
// URL configuration
|
|
366
|
+
urlPrefix: '/static',
|
|
367
|
+
urlsReserved: ['/api', '/auth']
|
|
368
|
+
}));
|
|
369
|
+
|
|
370
|
+
app.listen(3000, () => {
|
|
371
|
+
console.log('🚀 Server running on http://localhost:3000');
|
|
372
|
+
console.log('📁 Static files: http://localhost:3000/static');
|
|
373
|
+
});
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## Supporto completo
|
|
379
|
+
|
|
380
|
+
L'opzione `index` supporta:
|
|
381
|
+
|
|
382
|
+
| Tipo | Esempio | Caso d'uso | Stato |
|
|
383
|
+
|------|---------|------------|-------|
|
|
384
|
+
| **Array di stringhe** | `["index.html", "index.htm"]` | Priorità definita, performance ottimale | ✅ **Raccomandato** |
|
|
385
|
+
| **Array di RegExp** | `[/index\.html/i, /default\.htm/i]` | Pattern multipli, case-insensitive | ✅ **Raccomandato** |
|
|
386
|
+
| **Mixed array** | `["index.html", /INDEX\.HTM/i]` | Best of both worlds | ✅ **Raccomandato** |
|
|
387
|
+
| ~~String~~ | ~~`"index.html"`~~ | Singolo file | ⚠️ **DEPRECATO** |
|
|
388
|
+
|
|
389
|
+
**Nota:** Il formato stringa (`"index.html"`) è deprecato e genera un warning. Verrà rimosso in versioni future. Usa il formato array `["index.html"]` invece.
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
**Documentazione completa:** `index.cjs:28-48`
|
|
394
|
+
**Implementazione:** `index.cjs:205-250` (funzione `findIndexFile`)
|
|
395
|
+
**Test suite:** `__tests__/index-option.test.js` (19 test cases)
|