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
package/README.md
CHANGED
|
@@ -1,149 +1,324 @@
|
|
|
1
|
-
# koa-classic-
|
|
1
|
+
# koa-classic-server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
๐ **Secure Koa middleware for serving static files** with Apache-like directory listing, template engine support, and comprehensive security fixes.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/koa-classic-server)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[]()
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
## โ ๏ธ Version 1.2.0 - Critical Security Update
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
method: an array of supported HTTP methods. Default is ['GET'].
|
|
11
|
-
showDirContents: a boolean value indicating whether the contents of a directory should be shown. Default is true.
|
|
12
|
-
index: the name of the index file. Default is an empty string.
|
|
13
|
-
urlPrefix: the prefix of the path , such as localhost:3000/views. Default is an empty string.
|
|
14
|
-
urlsReserved: an array of reserved URLs that files cannot be read from. Default is an empty array.
|
|
15
|
-
template: an object with two properties:
|
|
16
|
-
render: a function for rendering templates. Default is undefined.
|
|
17
|
-
ext: an array of file extensions for which the render function should be used. Default is an empty array.
|
|
11
|
+
Version 1.2.0 includes **critical security fixes** for path traversal vulnerabilities and other important improvements. **Upgrade immediately** if you're using version 1.1.0 or earlier.
|
|
18
12
|
|
|
19
|
-
|
|
13
|
+
### What's New in 1.2.0
|
|
20
14
|
|
|
21
|
-
|
|
15
|
+
โ
**Fixed Path Traversal Vulnerability** - No more unauthorized file access
|
|
16
|
+
โ
**Proper HTTP 404 Status Codes** - Standards-compliant error handling
|
|
17
|
+
โ
**Template Error Handling** - No more server crashes
|
|
18
|
+
โ
**XSS Protection** - HTML escaping in directory listings
|
|
19
|
+
โ
**Race Condition Fixes** - Robust file access
|
|
20
|
+
โ
**71 Tests Passing** - Comprehensive test coverage
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
[See full changelog](./CHANGELOG.md)
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
## Features
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
koa-classic-server is a middleware for serving static files from a directory with Apache 2-like behavior. The contents of a folder on the server will be shown remotely and if you want to access a file, click on it.
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
**Key Features:**
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
- ๐๏ธ **Directory Listing** - Apache-style browseable directories
|
|
31
|
+
- ๐ **Static File Serving** - Automatic MIME type detection
|
|
32
|
+
- ๐จ **Template Engine Support** - Integrate EJS, Pug, Handlebars, etc.
|
|
33
|
+
- ๐ **Security** - Path traversal protection, XSS prevention
|
|
34
|
+
- โ๏ธ **Configurable** - URL prefixes, reserved paths, index files
|
|
35
|
+
- ๐งช **Well-Tested** - 71 tests with security coverage
|
|
36
|
+
- ๐ฆ **Dual Module Support** - CommonJS and ES Modules
|
|
32
37
|
|
|
33
38
|
## Installation
|
|
34
39
|
|
|
35
|
-
```
|
|
36
|
-
npm
|
|
40
|
+
```bash
|
|
41
|
+
npm install koa-classic-server
|
|
37
42
|
```
|
|
38
43
|
|
|
39
|
-
|
|
44
|
+
## Quick Start
|
|
40
45
|
|
|
41
|
-
```
|
|
46
|
+
```javascript
|
|
47
|
+
const Koa = require('koa');
|
|
42
48
|
const koaClassicServer = require('koa-classic-server');
|
|
49
|
+
|
|
50
|
+
const app = new Koa();
|
|
51
|
+
|
|
52
|
+
// Serve files from "public" directory
|
|
53
|
+
app.use(koaClassicServer(__dirname + '/public'));
|
|
54
|
+
|
|
55
|
+
app.listen(3000);
|
|
56
|
+
console.log('Server running on http://localhost:3000');
|
|
43
57
|
```
|
|
44
|
-
or
|
|
45
|
-
```js
|
|
46
|
-
import koaClassicServer from "koa-classic-server";
|
|
47
|
-
'''
|
|
48
58
|
|
|
49
|
-
##
|
|
59
|
+
## Usage
|
|
50
60
|
|
|
51
|
-
|
|
61
|
+
### Import
|
|
52
62
|
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
urlPrefix: "", // prefix of the URL that will be skipped es "/admin"
|
|
60
|
-
urlsReserved: Array(), //paths on disk that will not be accessible remotely e.g. array('/api','/views') warning nested folders are not allowed
|
|
61
|
-
template: {
|
|
62
|
-
render: undefined, //function that will take care of the rendering if there is a template engine ES --> const templateRender = async ( ctx, next, filePath) => {
|
|
63
|
-
ext: Array(), // template engine file extension ES :Array("ejs", "EJS"),
|
|
64
|
-
}, // emd template
|
|
65
|
-
}; // end optio
|
|
63
|
+
```javascript
|
|
64
|
+
// CommonJS
|
|
65
|
+
const koaClassicServer = require('koa-classic-server');
|
|
66
|
+
|
|
67
|
+
// ES Modules
|
|
68
|
+
import koaClassicServer from 'koa-classic-server';
|
|
66
69
|
```
|
|
67
70
|
|
|
68
|
-
|
|
71
|
+
### Basic Examples
|
|
69
72
|
|
|
70
|
-
|
|
73
|
+
#### Example 1: Simple File Server
|
|
71
74
|
|
|
72
|
-
```
|
|
73
|
-
const Koa = require(
|
|
74
|
-
const koaClassicServer = require(
|
|
75
|
+
```javascript
|
|
76
|
+
const Koa = require('koa');
|
|
77
|
+
const koaClassicServer = require('koa-classic-server');
|
|
75
78
|
|
|
76
79
|
const app = new Koa();
|
|
77
80
|
|
|
78
|
-
app.use(koaClassicServer(__dirname +
|
|
81
|
+
app.use(koaClassicServer(__dirname + '/public', {
|
|
82
|
+
showDirContents: true,
|
|
83
|
+
index: ['index.html'] // Array format (recommended)
|
|
84
|
+
}));
|
|
79
85
|
|
|
80
86
|
app.listen(3000);
|
|
81
87
|
```
|
|
82
88
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
```
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
template: {
|
|
100
|
-
render: async (ctx, next, filePath) => {
|
|
101
|
-
ctx.body = await ejs.renderFile(filePath, {
|
|
102
|
-
filePath: filePath,
|
|
103
|
-
href: ctx.href,
|
|
104
|
-
query: ctx.query,
|
|
105
|
-
});
|
|
106
|
-
},
|
|
107
|
-
ext: Array("ejs", "EJS"),
|
|
108
|
-
},
|
|
109
|
-
})
|
|
110
|
-
)
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
app.listen(port, console.log("server started on port:" + port));
|
|
89
|
+
#### Example 2: With URL Prefix
|
|
90
|
+
|
|
91
|
+
```javascript
|
|
92
|
+
const Koa = require('koa');
|
|
93
|
+
const koaClassicServer = require('koa-classic-server');
|
|
94
|
+
|
|
95
|
+
const app = new Koa();
|
|
96
|
+
|
|
97
|
+
// Files accessible under /static
|
|
98
|
+
// e.g., http://localhost:3000/static/image.png
|
|
99
|
+
app.use(koaClassicServer(__dirname + '/public', {
|
|
100
|
+
urlPrefix: '/static',
|
|
101
|
+
showDirContents: true
|
|
102
|
+
}));
|
|
103
|
+
|
|
104
|
+
app.listen(3000);
|
|
114
105
|
```
|
|
115
106
|
|
|
116
|
-
|
|
107
|
+
#### Example 3: With Template Engine (EJS)
|
|
117
108
|
|
|
118
|
-
```
|
|
119
|
-
const
|
|
120
|
-
const
|
|
121
|
-
const
|
|
109
|
+
```javascript
|
|
110
|
+
const Koa = require('koa');
|
|
111
|
+
const koaClassicServer = require('koa-classic-server');
|
|
112
|
+
const ejs = require('ejs');
|
|
122
113
|
|
|
123
|
-
const
|
|
114
|
+
const app = new Koa();
|
|
124
115
|
|
|
125
|
-
|
|
116
|
+
app.use(koaClassicServer(__dirname + '/views', {
|
|
117
|
+
template: {
|
|
118
|
+
render: async (ctx, next, filePath) => {
|
|
119
|
+
ctx.body = await ejs.renderFile(filePath, {
|
|
120
|
+
title: 'My App',
|
|
121
|
+
user: ctx.state.user
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
ext: ['ejs', 'html']
|
|
125
|
+
}
|
|
126
|
+
}));
|
|
126
127
|
|
|
127
|
-
|
|
128
|
-
|
|
128
|
+
app.listen(3000);
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## API
|
|
132
|
+
|
|
133
|
+
### koaClassicServer(rootDir, options)
|
|
134
|
+
|
|
135
|
+
Creates a Koa middleware for serving static files.
|
|
136
|
+
|
|
137
|
+
**Parameters:**
|
|
138
|
+
|
|
139
|
+
- `rootDir` (String, required): Absolute path to the directory containing static files
|
|
140
|
+
- `options` (Object, optional): Configuration options
|
|
141
|
+
|
|
142
|
+
**Returns:** Koa middleware function
|
|
143
|
+
|
|
144
|
+
## Options
|
|
145
|
+
|
|
146
|
+
```javascript
|
|
147
|
+
const options = {
|
|
148
|
+
// HTTP methods allowed (default: ['GET'])
|
|
149
|
+
method: ['GET', 'HEAD'],
|
|
150
|
+
|
|
151
|
+
// Show directory contents (default: true)
|
|
152
|
+
showDirContents: true,
|
|
153
|
+
|
|
154
|
+
// Index file configuration (default: [])
|
|
155
|
+
// RECOMMENDED: Use array format (string format is deprecated)
|
|
156
|
+
// Formats:
|
|
157
|
+
// - Array of strings: ['index.html', 'index.htm', 'default.html']
|
|
158
|
+
// - Array of RegExp: [/index\.html/i] (case-insensitive)
|
|
159
|
+
// - Mixed array: ['index.html', /INDEX\.HTM/i]
|
|
160
|
+
// Priority: First match wins (array order determines search priority)
|
|
161
|
+
//
|
|
162
|
+
// DEPRECATED: String format 'index.html' still works but will be removed
|
|
163
|
+
// in future versions. Please use array format: ['index.html']
|
|
164
|
+
//
|
|
165
|
+
// See INDEX_OPTION_PRIORITY.md for detailed behavior documentation
|
|
166
|
+
index: ['index.html'],
|
|
167
|
+
|
|
168
|
+
// URL path prefix (default: '')
|
|
169
|
+
// Files will be served under this prefix
|
|
170
|
+
urlPrefix: '/static',
|
|
171
|
+
|
|
172
|
+
// Reserved paths (default: [])
|
|
173
|
+
// These directories won't be accessible
|
|
174
|
+
// Note: Only works for first-level directories
|
|
175
|
+
urlsReserved: ['/admin', '/private'],
|
|
176
|
+
|
|
177
|
+
// Template engine configuration
|
|
178
|
+
template: {
|
|
179
|
+
// Template rendering function
|
|
180
|
+
render: async (ctx, next, filePath) => {
|
|
181
|
+
// Your rendering logic
|
|
182
|
+
ctx.body = await yourTemplateEngine.render(filePath, data);
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
// File extensions to process with template.render
|
|
186
|
+
ext: ['ejs', 'pug', 'hbs']
|
|
187
|
+
}
|
|
129
188
|
};
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Options Details
|
|
192
|
+
|
|
193
|
+
| Option | Type | Default | Description |
|
|
194
|
+
|--------|------|---------|-------------|
|
|
195
|
+
| `method` | Array | `['GET']` | Allowed HTTP methods |
|
|
196
|
+
| `showDirContents` | Boolean | `true` | Show directory listing |
|
|
197
|
+
| `index` | String | `''` | Index file name |
|
|
198
|
+
| `urlPrefix` | String | `''` | URL path prefix |
|
|
199
|
+
| `urlsReserved` | Array | `[]` | Reserved directory paths |
|
|
200
|
+
| `template.render` | Function | `undefined` | Template rendering function |
|
|
201
|
+
| `template.ext` | Array | `[]` | Extensions for template rendering |
|
|
202
|
+
|
|
203
|
+
## Security
|
|
204
|
+
|
|
205
|
+
### Path Traversal Protection
|
|
206
|
+
|
|
207
|
+
koa-classic-server 1.2.0 protects against path traversal attacks:
|
|
208
|
+
|
|
209
|
+
```javascript
|
|
210
|
+
// โ These requests are blocked (return 403 Forbidden)
|
|
211
|
+
GET /../../../etc/passwd
|
|
212
|
+
GET /../config/database.yml
|
|
213
|
+
GET /%2e%2e%2fpackage.json
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Protected Directories
|
|
217
|
+
|
|
218
|
+
Use `urlsReserved` to protect sensitive directories:
|
|
130
219
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
showDirContents: true,
|
|
136
|
-
template: {
|
|
137
|
-
render: templateRender,
|
|
138
|
-
ext: Array("ejs", "EJS"),
|
|
139
|
-
},
|
|
140
|
-
})
|
|
141
|
-
)
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
app.listen(port, console.log("server started on port:" + port));
|
|
220
|
+
```javascript
|
|
221
|
+
app.use(koaClassicServer(__dirname + '/www', {
|
|
222
|
+
urlsReserved: ['/config', '/private', '/.git', '/node_modules']
|
|
223
|
+
}));
|
|
145
224
|
```
|
|
146
225
|
|
|
226
|
+
### XSS Protection
|
|
227
|
+
|
|
228
|
+
All filenames and paths in directory listings are HTML-escaped to prevent XSS attacks.
|
|
229
|
+
|
|
230
|
+
## Error Handling
|
|
231
|
+
|
|
232
|
+
koa-classic-server properly handles errors:
|
|
233
|
+
|
|
234
|
+
- **404** - File/directory not found
|
|
235
|
+
- **403** - Forbidden (path traversal attempts, reserved directories)
|
|
236
|
+
- **500** - Template rendering errors, file access errors
|
|
237
|
+
|
|
238
|
+
## Testing
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
# Run all tests
|
|
242
|
+
npm test
|
|
243
|
+
|
|
244
|
+
# Run security tests only
|
|
245
|
+
npm run test:security
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Middleware Behavior
|
|
249
|
+
|
|
250
|
+
### Directory Handling
|
|
251
|
+
|
|
252
|
+
1. If `index` file exists โ serve index file
|
|
253
|
+
2. If `showDirContents: true` โ show directory listing
|
|
254
|
+
3. If `showDirContents: false` โ return 404
|
|
255
|
+
|
|
256
|
+
### File Handling
|
|
257
|
+
|
|
258
|
+
1. Check if file extension matches `template.ext`
|
|
259
|
+
2. If yes โ call `template.render()`
|
|
260
|
+
3. If no โ serve static file with appropriate MIME type
|
|
261
|
+
|
|
262
|
+
### Reserved URLs
|
|
263
|
+
|
|
264
|
+
Requests to reserved paths are passed to the next middleware.
|
|
265
|
+
|
|
266
|
+
## Migration from 1.1.0
|
|
267
|
+
|
|
268
|
+
Upgrading is simple! No code changes required:
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
npm update koa-classic-server
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
**What changed:**
|
|
275
|
+
- 404 status codes now correct (was 200)
|
|
276
|
+
- Path traversal blocked (was allowed)
|
|
277
|
+
- Template errors return 500 (was crash)
|
|
278
|
+
|
|
279
|
+
See [CHANGELOG.md](./CHANGELOG.md) for detailed information.
|
|
280
|
+
|
|
281
|
+
## Complete Documentation
|
|
282
|
+
|
|
283
|
+
For complete documentation with all features, examples, troubleshooting, and best practices, see:
|
|
284
|
+
|
|
285
|
+
- **[DOCUMENTATION.md](./DOCUMENTATION.md)** - Complete API reference and usage guide
|
|
286
|
+
- **[INDEX_OPTION_PRIORITY.md](./INDEX_OPTION_PRIORITY.md)** - Detailed priority behavior for `index` option (string, array, RegExp)
|
|
287
|
+
- **[EXAMPLES_INDEX_OPTION.md](./EXAMPLES_INDEX_OPTION.md)** - 10 practical examples of `index` option with RegExp
|
|
288
|
+
- **[PERFORMANCE_ANALYSIS.md](./PERFORMANCE_ANALYSIS.md)** - Performance optimization analysis
|
|
289
|
+
- **[PERFORMANCE_COMPARISON.md](./PERFORMANCE_COMPARISON.md)** - Before/after performance benchmarks
|
|
290
|
+
|
|
291
|
+
## Contributing
|
|
292
|
+
|
|
293
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
294
|
+
|
|
295
|
+
## Known Limitations
|
|
296
|
+
|
|
297
|
+
- Reserved URLs only work for first-level directories
|
|
298
|
+
- Single index file name (no fallback array)
|
|
299
|
+
|
|
300
|
+
See [DEBUG_REPORT.md](./DEBUG_REPORT.md) for technical details.
|
|
301
|
+
|
|
147
302
|
## License
|
|
148
303
|
|
|
149
304
|
MIT
|
|
305
|
+
|
|
306
|
+
## Author
|
|
307
|
+
|
|
308
|
+
Italo Paesano
|
|
309
|
+
|
|
310
|
+
## Changelog
|
|
311
|
+
|
|
312
|
+
See [CHANGELOG.md](./CHANGELOG.md)
|
|
313
|
+
|
|
314
|
+
## Links
|
|
315
|
+
|
|
316
|
+
- [Full Documentation](./DOCUMENTATION.md)
|
|
317
|
+
- [Debug Report](./DEBUG_REPORT.md)
|
|
318
|
+
- [Changelog](./CHANGELOG.md)
|
|
319
|
+
- [Repository](https://github.com/italopaesano/koa-classic-server)
|
|
320
|
+
- [npm Package](https://www.npmjs.com/package/koa-classic-server)
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
**โ ๏ธ Security Notice:** Version 1.2.0 fixes critical vulnerabilities. Update immediately if using 1.1.0 or earlier.
|