ultimate-express 1.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.
Files changed (200) hide show
  1. package/.github/workflows/test.yml +27 -0
  2. package/EXPRESS_LICENSE +26 -0
  3. package/README.md +269 -0
  4. package/package.json +76 -0
  5. package/src/application.js +295 -0
  6. package/src/index.js +23 -0
  7. package/src/middlewares.js +95 -0
  8. package/src/request.js +324 -0
  9. package/src/response.js +686 -0
  10. package/src/router.js +490 -0
  11. package/src/utils.js +285 -0
  12. package/src/view.js +103 -0
  13. package/src/workers/fs.js +14 -0
  14. package/tests/index.js +64 -0
  15. package/tests/parts/.test/index.html +11 -0
  16. package/tests/parts/big.jpg +0 -0
  17. package/tests/parts/index.art +12 -0
  18. package/tests/parts/index.dot +12 -0
  19. package/tests/parts/index.ejs +12 -0
  20. package/tests/parts/index.handlebars +2 -0
  21. package/tests/parts/index.html +12 -0
  22. package/tests/parts/index.mustache +12 -0
  23. package/tests/parts/index.pug +6 -0
  24. package/tests/parts/index.swig +12 -0
  25. package/tests/parts/layouts/main.handlebars +12 -0
  26. package/tests/preload.cjs +5 -0
  27. package/tests/singular.js +41 -0
  28. package/tests/tests/app/app-engine.js +8 -0
  29. package/tests/tests/app/app-on-mount.js +24 -0
  30. package/tests/tests/app/app-path.js +21 -0
  31. package/tests/tests/app/app-route.js +30 -0
  32. package/tests/tests/app/options.js +16 -0
  33. package/tests/tests/app/setting-inheritance.js +16 -0
  34. package/tests/tests/engines/art-template.js +33 -0
  35. package/tests/tests/engines/dot.js +28 -0
  36. package/tests/tests/engines/ejs.js +25 -0
  37. package/tests/tests/engines/handlebars.js +28 -0
  38. package/tests/tests/engines/mustache.js +28 -0
  39. package/tests/tests/engines/pug.js +25 -0
  40. package/tests/tests/engines/swig.js +28 -0
  41. package/tests/tests/errors/error-handling-middleware.js +22 -0
  42. package/tests/tests/errors/next-error-optimized.js +26 -0
  43. package/tests/tests/errors/next-error.js +26 -0
  44. package/tests/tests/errors/unexpected-error-handling.js +18 -0
  45. package/tests/tests/listen/listen-random.js +11 -0
  46. package/tests/tests/listen/listen-specific.js +17 -0
  47. package/tests/tests/middlewares/body-json.js +31 -0
  48. package/tests/tests/middlewares/body-raw-deflate.js +43 -0
  49. package/tests/tests/middlewares/body-raw-gzip.js +43 -0
  50. package/tests/tests/middlewares/body-raw.js +41 -0
  51. package/tests/tests/middlewares/body-text.js +27 -0
  52. package/tests/tests/middlewares/body-urlencoded.js +30 -0
  53. package/tests/tests/middlewares/cookie-parser-signed.js +31 -0
  54. package/tests/tests/middlewares/cookie-parser.js +28 -0
  55. package/tests/tests/middlewares/cookie-session.js +40 -0
  56. package/tests/tests/middlewares/cors.js +29 -0
  57. package/tests/tests/middlewares/errorhandler.js +26 -0
  58. package/tests/tests/middlewares/express-fileupload-temp.js +46 -0
  59. package/tests/tests/middlewares/express-fileupload.js +28 -0
  60. package/tests/tests/middlewares/express-rate-limit.js +33 -0
  61. package/tests/tests/middlewares/express-session.js +37 -0
  62. package/tests/tests/middlewares/express-static-options.js +72 -0
  63. package/tests/tests/middlewares/express-static.js +40 -0
  64. package/tests/tests/middlewares/method-override.js +33 -0
  65. package/tests/tests/middlewares/multer.js +43 -0
  66. package/tests/tests/middlewares/multiple-middlewares.js +37 -0
  67. package/tests/tests/middlewares/response-time.js +29 -0
  68. package/tests/tests/middlewares/serve-index.js +38 -0
  69. package/tests/tests/middlewares/serve-static.js +38 -0
  70. package/tests/tests/middlewares/vhost.js +50 -0
  71. package/tests/tests/params/array-param.js +30 -0
  72. package/tests/tests/params/nested-params.js +24 -0
  73. package/tests/tests/params/param-errors.js +56 -0
  74. package/tests/tests/params/param-function.js +49 -0
  75. package/tests/tests/params/param-next-route.js +48 -0
  76. package/tests/tests/params/param-optimized.js +38 -0
  77. package/tests/tests/params/param-use.js +39 -0
  78. package/tests/tests/params/param.js +68 -0
  79. package/tests/tests/params/params-regex.js +26 -0
  80. package/tests/tests/params/params-use.js +20 -0
  81. package/tests/tests/params/params.js +35 -0
  82. package/tests/tests/req/req-accepts-charsets.js +40 -0
  83. package/tests/tests/req/req-accepts-encodings.js +36 -0
  84. package/tests/tests/req/req-accepts-languages.js +41 -0
  85. package/tests/tests/req/req-accepts.js +41 -0
  86. package/tests/tests/req/req-app.js +17 -0
  87. package/tests/tests/req/req-baseurl.js +38 -0
  88. package/tests/tests/req/req-connection.js +19 -0
  89. package/tests/tests/req/req-fresh.js +59 -0
  90. package/tests/tests/req/req-get.js +78 -0
  91. package/tests/tests/req/req-headers-distinct.js +72 -0
  92. package/tests/tests/req/req-headers.js +72 -0
  93. package/tests/tests/req/req-host.js +45 -0
  94. package/tests/tests/req/req-hostname.js +45 -0
  95. package/tests/tests/req/req-ip.js +19 -0
  96. package/tests/tests/req/req-is.js +44 -0
  97. package/tests/tests/req/req-original-url.js +29 -0
  98. package/tests/tests/req/req-param.js +29 -0
  99. package/tests/tests/req/req-protocol.js +20 -0
  100. package/tests/tests/req/req-query.js +23 -0
  101. package/tests/tests/req/req-range.js +48 -0
  102. package/tests/tests/req/req-raw-headers.js +72 -0
  103. package/tests/tests/req/req-subdomains.js +48 -0
  104. package/tests/tests/req/req-url-nested.js +27 -0
  105. package/tests/tests/req/req-url-optimized-router.js +26 -0
  106. package/tests/tests/req/req-url-optimized.js +23 -0
  107. package/tests/tests/req/req-url.js +36 -0
  108. package/tests/tests/req/req-xhr.js +23 -0
  109. package/tests/tests/res/head-content-length.js +18 -0
  110. package/tests/tests/res/head.js +47 -0
  111. package/tests/tests/res/injecting.js +25 -0
  112. package/tests/tests/res/piping.js +23 -0
  113. package/tests/tests/res/res-app.js +17 -0
  114. package/tests/tests/res/res-append.js +24 -0
  115. package/tests/tests/res/res-attachment.js +19 -0
  116. package/tests/tests/res/res-clear-cookie.js +18 -0
  117. package/tests/tests/res/res-cookie.js +22 -0
  118. package/tests/tests/res/res-download.js +36 -0
  119. package/tests/tests/res/res-format.js +57 -0
  120. package/tests/tests/res/res-get.js +18 -0
  121. package/tests/tests/res/res-headers-sent.js +18 -0
  122. package/tests/tests/res/res-json.js +17 -0
  123. package/tests/tests/res/res-jsonp.js +25 -0
  124. package/tests/tests/res/res-links.js +21 -0
  125. package/tests/tests/res/res-location.js +34 -0
  126. package/tests/tests/res/res-redirect.js +46 -0
  127. package/tests/tests/res/res-remove-header.js +19 -0
  128. package/tests/tests/res/res-send-file.js +17 -0
  129. package/tests/tests/res/res-send-status.js +17 -0
  130. package/tests/tests/res/res-send.js +69 -0
  131. package/tests/tests/res/res-set.js +28 -0
  132. package/tests/tests/res/res-status.js +18 -0
  133. package/tests/tests/res/res-type.js +19 -0
  134. package/tests/tests/res/res-vary.js +19 -0
  135. package/tests/tests/res/res-write.js +29 -0
  136. package/tests/tests/routers/complex-routers.js +34 -0
  137. package/tests/tests/routers/empty-router.js +25 -0
  138. package/tests/tests/routers/lot-of-routes.js +38 -0
  139. package/tests/tests/routers/mergeparams.js +42 -0
  140. package/tests/tests/routers/nested-routers.js +52 -0
  141. package/tests/tests/routers/router-options.js +68 -0
  142. package/tests/tests/routers/routers.js +45 -0
  143. package/tests/tests/routers/simple-routers.js +35 -0
  144. package/tests/tests/routing/all.js +47 -0
  145. package/tests/tests/routing/array-arguments.js +35 -0
  146. package/tests/tests/routing/array-use.js +33 -0
  147. package/tests/tests/routing/async-use.js +25 -0
  148. package/tests/tests/routing/complex-routes.js +50 -0
  149. package/tests/tests/routing/lot-of-param-routes.js +26 -0
  150. package/tests/tests/routing/lot-of-routes.js +59 -0
  151. package/tests/tests/routing/next-existent-optimized-route.js +29 -0
  152. package/tests/tests/routing/next-existent-route.js +29 -0
  153. package/tests/tests/routing/next-nonexistent-optimized-route.js +19 -0
  154. package/tests/tests/routing/next-nonexistent-route.js +19 -0
  155. package/tests/tests/routing/next-special-cases.js +54 -0
  156. package/tests/tests/routing/next-unoptimized.js +39 -0
  157. package/tests/tests/routing/no-path-use.js +29 -0
  158. package/tests/tests/routing/non-string-routes.js +27 -0
  159. package/tests/tests/routing/req-multiple-mountpaths.js +34 -0
  160. package/tests/tests/routing/simple-routes.js +29 -0
  161. package/tests/tests/routing/simple-use.js +52 -0
  162. package/tests/tests/routing/some-middlewares.js +27 -0
  163. package/tests/tests/routing/special-characters.js +28 -0
  164. package/tests/tests/routing/star.js +31 -0
  165. package/tests/tests/routing/sub-apps.js +32 -0
  166. package/tests/tests/routing/trailing-slash.js +37 -0
  167. package/tests/tests/routing/weird-route-start.js +18 -0
  168. package/tests/tests/send-file/accept-ranges.js +26 -0
  169. package/tests/tests/send-file/callback.js +23 -0
  170. package/tests/tests/send-file/default-error-routing.js +21 -0
  171. package/tests/tests/send-file/dotfiles.js +24 -0
  172. package/tests/tests/send-file/etag.js +19 -0
  173. package/tests/tests/send-file/fs-threads.js +39 -0
  174. package/tests/tests/send-file/head.js +49 -0
  175. package/tests/tests/send-file/headers.js +23 -0
  176. package/tests/tests/send-file/if-match.js +31 -0
  177. package/tests/tests/send-file/if-range.js +37 -0
  178. package/tests/tests/send-file/if-unmodified-since.js +32 -0
  179. package/tests/tests/send-file/immutable.js +22 -0
  180. package/tests/tests/send-file/large-file.js +19 -0
  181. package/tests/tests/send-file/last-modified.js +21 -0
  182. package/tests/tests/send-file/max-age.js +21 -0
  183. package/tests/tests/send-file/path-traversal.js +35 -0
  184. package/tests/tests/send-file/range.js +57 -0
  185. package/tests/tests/send-file/simple.js +18 -0
  186. package/tests/tests/settings/case-sensitive-routing.js +48 -0
  187. package/tests/tests/settings/env-errors.js +38 -0
  188. package/tests/tests/settings/etag.js +36 -0
  189. package/tests/tests/settings/json-escape.js +45 -0
  190. package/tests/tests/settings/json-replacer.js +50 -0
  191. package/tests/tests/settings/json-spaces.js +44 -0
  192. package/tests/tests/settings/query-parser.js +45 -0
  193. package/tests/tests/settings/strict-routing.js +64 -0
  194. package/tests/tests/settings/subdomain-offset.js +38 -0
  195. package/tests/tests/settings/trust-proxy-host.js +58 -0
  196. package/tests/tests/settings/trust-proxy-ip.js +58 -0
  197. package/tests/tests/settings/trust-proxy-ips.js +58 -0
  198. package/tests/tests/settings/trust-proxy-protocol.js +46 -0
  199. package/tests/tests/settings/x-powered-by.js +32 -0
  200. package/tests/uws.js +14 -0
@@ -0,0 +1,28 @@
1
+ // must support . and - in routes
2
+
3
+ const express = require("express");
4
+
5
+ const app = express();
6
+
7
+ app.get('/test/hi.bye*a', (req, res) => {
8
+ res.send('hi.bye');
9
+ });
10
+
11
+ app.get('/hi-bye*a', (req, res) => {
12
+ res.send('hi-bye');
13
+ });
14
+
15
+ app.listen(13333, async () => {
16
+ console.log('Server is running on port 13333');
17
+
18
+ let res = await fetch('http://localhost:13333/test/hi.byeaa');
19
+ console.log(await res.text());
20
+
21
+ res = await fetch('http://localhost:13333/hi-byeaa');
22
+ console.log(await res.text());
23
+
24
+ res = await fetch('http://localhost:13333/test/hiAbyeaa');
25
+ console.log(await res.text());
26
+
27
+ process.exit(0);
28
+ })
@@ -0,0 +1,31 @@
1
+ // must support /* in routes
2
+
3
+ const express = require("express");
4
+
5
+ const app = express();
6
+
7
+ app.get('/test/*', (req, res) => {
8
+ res.send('test');
9
+ });
10
+
11
+ app.get('/*', (req, res) => {
12
+ res.send('*');
13
+ });
14
+
15
+ app.listen(13333, async () => {
16
+ console.log('Server is running on port 13333');
17
+
18
+ let res = await fetch('http://localhost:13333/test/999');
19
+ console.log(await res.text());
20
+
21
+ res = await fetch('http://localhost:13333/test/sdfs/1999');
22
+ console.log(await res.text());
23
+
24
+ res = await fetch('http://localhost:13333/999');
25
+ console.log(await res.text());
26
+
27
+ res = await fetch('http://localhost:13333/sdfs/1999');
28
+ console.log(await res.text());
29
+
30
+ process.exit(0);
31
+ })
@@ -0,0 +1,32 @@
1
+ // must support sub-apps
2
+
3
+ const express = require("express");
4
+
5
+ const app = express();
6
+ const app2 = express();
7
+
8
+ app.get('/test', (req, res) => {
9
+ res.send('test1');
10
+ });
11
+
12
+ app2.get('/test', (req, res) => {
13
+ res.send('test2');
14
+ });
15
+
16
+ app.use('/asdf', app2);
17
+
18
+ app.use((req, res, next) => {
19
+ res.send('404');
20
+ });
21
+
22
+ app.listen(13333, async () => {
23
+ console.log('Server is running on port 13333');
24
+
25
+ const outputs = await Promise.all([
26
+ fetch('http://localhost:13333/test').then(res => res.text()),
27
+ fetch('http://localhost:13333/asdf/test').then(res => res.text()),
28
+ ]);
29
+
30
+ console.log(outputs.join(' '));
31
+ process.exit(0);
32
+ });
@@ -0,0 +1,37 @@
1
+ // must support trailing slash in routes
2
+
3
+ const express = require("express");
4
+
5
+ const app = express();
6
+
7
+ app.get('/test', (req, res) => {
8
+ res.send('test');
9
+ });
10
+
11
+ app.get("/baba/", (req, res) => {
12
+ res.send("baba");
13
+ });
14
+
15
+ app.listen(13333, async () => {
16
+ console.log('Server is running on port 13333');
17
+
18
+ let res = await fetch('http://localhost:13333/test');
19
+ console.log(await res.text());
20
+
21
+ res = await fetch('http://localhost:13333/test/');
22
+ console.log(await res.text());
23
+
24
+ res = await fetch('http://localhost:13333/test/test');
25
+ console.log(await res.text());
26
+
27
+ res = await fetch('http://localhost:13333/baba');
28
+ console.log(await res.text());
29
+
30
+ res = await fetch('http://localhost:13333/baba/');
31
+ console.log(await res.text());
32
+
33
+ res = await fetch('http://localhost:13333/test/?test=1');
34
+ console.log(await res.text());
35
+
36
+ process.exit(0);
37
+ })
@@ -0,0 +1,18 @@
1
+ // must match express behavior for non-slash route start
2
+
3
+ const express = require("express");
4
+
5
+ const app = express();
6
+
7
+ app.get("test", (req, res) => {
8
+ res.send("test");
9
+ });
10
+
11
+ app.listen(13333, async () => {
12
+ console.log('Server is running on port 13333');
13
+
14
+ let res = await fetch('http://localhost:13333/test');
15
+ console.log(await res.text());
16
+
17
+ process.exit(0);
18
+ })
@@ -0,0 +1,26 @@
1
+ // must support acceptRanges option
2
+
3
+ const express = require("express");
4
+ const path = require("path");
5
+
6
+ const app = express();
7
+
8
+ app.get('/test', (req, res) => {
9
+ res.sendFile('src/index.js', { root: '.', acceptRanges: false });
10
+ });
11
+
12
+ app.use((err, req, res, next) => {
13
+ res.status(500).send(err.message);
14
+ });
15
+
16
+ app.listen(13333, async () => {
17
+ console.log('Server is running on port 13333');
18
+
19
+ const response = await fetch('http://localhost:13333/test', {
20
+ headers: {
21
+ Range: 'bytes=0-10'
22
+ }
23
+ });
24
+ console.log(await response.text(), response.headers.get('Content-Range'), response.headers.get('Content-Length'), response.status);
25
+ process.exit(0);
26
+ });
@@ -0,0 +1,23 @@
1
+ // must support callback
2
+
3
+ const express = require("express");
4
+
5
+ const app = express();
6
+
7
+ app.get('/test', (req, res) => {
8
+ res.sendFile('src/asdf.js', { root: '.' }, (err) => {
9
+ res.status(500).send(err?.message ? `caught error: ${err.message}` : 'no error');
10
+ });
11
+ });
12
+
13
+ app.use((err, req, res, next) => {
14
+ res.status(500).send(`uncaught error: ${err.message}`);
15
+ });
16
+
17
+ app.listen(13333, async () => {
18
+ console.log('Server is running on port 13333');
19
+
20
+ const response = await fetch('http://localhost:13333/test');
21
+ console.log(await response.text());
22
+ process.exit(0);
23
+ });
@@ -0,0 +1,21 @@
1
+ // must continue routing by default
2
+
3
+ const express = require("express");
4
+
5
+ const app = express();
6
+
7
+ app.get('/test', (req, res) => {
8
+ res.sendFile('src/asdf.js', { root: '.' });
9
+ });
10
+
11
+ app.use((err, req, res, next) => {
12
+ res.status(404).send('404: File not found');
13
+ });
14
+
15
+ app.listen(13333, async () => {
16
+ console.log('Server is running on port 13333');
17
+
18
+ const response = await fetch('http://localhost:13333/test');
19
+ console.log(await response.text());
20
+ process.exit(0);
21
+ });
@@ -0,0 +1,24 @@
1
+ // must support dotfiles
2
+
3
+ const express = require("express");
4
+ const path = require("path");
5
+
6
+ const app = express();
7
+
8
+ app.get('/test', (req, res) => {
9
+ res.sendFile(path.join(process.cwd(), 'src/.src/index.js'), {
10
+ dotfiles: 'deny'
11
+ });
12
+ });
13
+
14
+ app.use((err, req, res, next) => {
15
+ res.status(500).send(err.message);
16
+ });
17
+
18
+ app.listen(13333, async () => {
19
+ console.log('Server is running on port 13333');
20
+
21
+ const response = await fetch('http://localhost:13333/test');
22
+ console.log(await response.text(), response.headers.get('Content-Type').split(';')[0]);
23
+ process.exit(0);
24
+ });
@@ -0,0 +1,19 @@
1
+ // must support setting etag
2
+
3
+ const express = require("express");
4
+
5
+ const app = express();
6
+
7
+ app.get('/test', (req, res) => {
8
+ res.sendFile('src/index.js', {
9
+ root: '.'
10
+ });
11
+ });
12
+
13
+ app.listen(13333, async () => {
14
+ console.log('Server is running on port 13333');
15
+
16
+ const response = await fetch('http://localhost:13333/test');
17
+ console.log(await response.text(), response.headers.get('etag'));
18
+ process.exit(0);
19
+ });
@@ -0,0 +1,39 @@
1
+ // must support fs threads
2
+
3
+ const express = require("express");
4
+
5
+ const app = express({ fsThreads: 0 });
6
+ const app2 = express({ fsThreads: 2 });
7
+ const app3 = express({ fsThreads: 4 });
8
+
9
+ app.get('/test', (req, res) => {
10
+ res.sendFile('tests/parts/big.jpg', {
11
+ root: '.'
12
+ });
13
+ });
14
+
15
+ app2.get('/test', (req, res) => {
16
+ res.sendFile('tests/parts/big.jpg', {
17
+ root: '.'
18
+ });
19
+ });
20
+
21
+ app3.get('/test', (req, res) => {
22
+ res.sendFile('tests/parts/big.jpg', {
23
+ root: '.'
24
+ });
25
+ });
26
+ app.listen(13333, async () => {
27
+ app2.listen(13334, async () => {
28
+ app3.listen(13335, async () => {
29
+ console.log('Server is running on port 13333, 13334, 13335');
30
+ const response = await fetch('http://localhost:13333/test');
31
+ console.log(response.status, response.headers.get('Content-Length'));
32
+ const response2 = await fetch('http://localhost:13334/test');
33
+ console.log(response2.status, response2.headers.get('Content-Length'));
34
+ const response3 = await fetch('http://localhost:13335/test');
35
+ console.log(response3.status, response3.headers.get('Content-Length'));
36
+ process.exit(0);
37
+ });
38
+ });
39
+ });
@@ -0,0 +1,49 @@
1
+ // must support HEAD method
2
+
3
+ const express = require("express");
4
+ const path = require("path");
5
+ const net = require("net");
6
+
7
+ async function sendRequest(method, url, arrayHeaders) {
8
+ // arrayHeaders is an array of [key, value] pairs
9
+ return new Promise((resolve, reject) => {
10
+ const client = new net.Socket();
11
+ const [host, port] = url.split('://')[1].split('/')[0].split(':');
12
+ const path = '/' + url.split('/').slice(3).join('/');
13
+
14
+ client.connect(parseInt(port), host, () => {
15
+ let request = `${method} ${path} HTTP/1.1\r\n`;
16
+ request += `Host: ${host}:${port}\r\n`;
17
+
18
+ for (const [key, value] of arrayHeaders) {
19
+ request += `${key}: ${value}\r\n`;
20
+ }
21
+
22
+ request += '\r\n';
23
+
24
+ client.on('data', (data) => {
25
+ resolve(data.toString());
26
+ });
27
+
28
+ client.write(request);
29
+
30
+ });
31
+ });
32
+ }
33
+
34
+ const app = express();
35
+
36
+ app.get('/test', (req, res) => {
37
+ res.sendFile(path.join(process.cwd(), 'src/index.js'));
38
+ });
39
+
40
+ app.listen(13333, async () => {
41
+ console.log('Server is running on port 13333');
42
+
43
+ const response = await sendRequest('HEAD', 'http://localhost:13333/test', []);
44
+ const body = response.split('\r\n\r\n')[1];
45
+ const contentLength = response.match(/Content-Length: (\d+)/)[1];
46
+ console.log([contentLength, body.length]);
47
+
48
+ process.exit(0);
49
+ });
@@ -0,0 +1,23 @@
1
+ // must support headers option
2
+
3
+ const express = require("express");
4
+ const path = require("path");
5
+
6
+ const app = express();
7
+
8
+ app.get('/test', (req, res) => {
9
+ res.sendFile('src/index.js', {
10
+ root: '.',
11
+ headers: {
12
+ 'X-Custom-Header': 'custom-value'
13
+ }
14
+ });
15
+ });
16
+
17
+ app.listen(13333, async () => {
18
+ console.log('Server is running on port 13333');
19
+
20
+ const response = await fetch('http://localhost:13333/test');
21
+ console.log(await response.text(), response.headers.get('X-Custom-Header'));
22
+ process.exit(0);
23
+ });
@@ -0,0 +1,31 @@
1
+ // must support If-Match header
2
+
3
+ const express = require("express");
4
+
5
+ const app = express();
6
+
7
+ app.get('/test', (req, res) => {
8
+ res.sendFile('src/index.js', { root: '.' });
9
+ });
10
+
11
+ app.use((err, req, res, next) => {
12
+ res.status(500).send(err.message);
13
+ });
14
+
15
+ app.listen(13333, async () => {
16
+ console.log('Server is running on port 13333');
17
+
18
+ const response = await fetch('http://localhost:13333/test', {
19
+ headers: {
20
+ 'If-Unmodified-Since': new Date(0).toUTCString()
21
+ }
22
+ });
23
+ console.log(response.status, response.headers.get('ETag'));
24
+ const response2 = await fetch('http://localhost:13333/test', {
25
+ headers: {
26
+ 'If-Match': '"' + response.headers.get('ETag') + '"'
27
+ }
28
+ });
29
+ console.log((await response2.text()).slice(0, 50), response2.status);
30
+ process.exit(0);
31
+ });
@@ -0,0 +1,37 @@
1
+ // must support If-Range header
2
+
3
+ const express = require("express");
4
+ const path = require("path");
5
+
6
+ const app = express();
7
+
8
+ app.get('/test', (req, res) => {
9
+ res.sendFile('src/index.js', { root: '.' });
10
+ });
11
+
12
+ app.use((err, req, res, next) => {
13
+ res.status(500).send(err.message);
14
+ });
15
+
16
+ app.listen(13333, async () => {
17
+ console.log('Server is running on port 13333');
18
+
19
+ const response = await fetch('http://localhost:13333/test', {
20
+ headers: {
21
+ 'Range': 'bytes=0-10',
22
+ 'If-Range': new Date(0).toISOString()
23
+ }
24
+ });
25
+ console.log(response.headers.get('Content-Range'), response.headers.get('Content-Length'), response.status);
26
+
27
+ const response2 = await fetch('http://localhost:13333/test', {
28
+
29
+ headers: {
30
+ 'Range': 'bytes=0-10',
31
+ 'If-Range': new Date().toISOString()
32
+ }
33
+ });
34
+ console.log(response2.headers.get('Content-Range'), response2.headers.get('Content-Length'), response2.status);
35
+
36
+ process.exit(0);
37
+ });
@@ -0,0 +1,32 @@
1
+ // must support If-Unmodified-Since header
2
+
3
+ const express = require("express");
4
+ const path = require("path");
5
+
6
+ const app = express();
7
+
8
+ app.get('/test', (req, res) => {
9
+ res.sendFile('src/index.js', { root: '.' });
10
+ });
11
+
12
+ app.use((err, req, res, next) => {
13
+ res.status(500).send(err.message);
14
+ });
15
+
16
+ app.listen(13333, async () => {
17
+ console.log('Server is running on port 13333');
18
+
19
+ const response = await fetch('http://localhost:13333/test', {
20
+ headers: {
21
+ 'If-Unmodified-Since': new Date(0).toUTCString()
22
+ }
23
+ });
24
+ console.log(await response.text(), response.status);
25
+ const response2 = await fetch('http://localhost:13333/test', {
26
+ headers: {
27
+ 'If-Unmodified-Since': new Date().toUTCString()
28
+ }
29
+ });
30
+ console.log((await response2.text()).slice(0, 50), response2.status);
31
+ process.exit(0);
32
+ });
@@ -0,0 +1,22 @@
1
+ // must support immutable option
2
+
3
+ const express = require("express");
4
+ const path = require("path");
5
+
6
+ const app = express();
7
+
8
+ app.get('/test', (req, res) => {
9
+ res.sendFile('src/index.js', {
10
+ root: '.',
11
+ maxAge: '1d',
12
+ immutable: true
13
+ });
14
+ });
15
+
16
+ app.listen(13333, async () => {
17
+ console.log('Server is running on port 13333');
18
+
19
+ const response = await fetch('http://localhost:13333/test');
20
+ console.log(await response.text(), response.headers.get('Cache-Control'));
21
+ process.exit(0);
22
+ });
@@ -0,0 +1,19 @@
1
+ // must support larger files
2
+
3
+ const express = require("express");
4
+
5
+ const app = express();
6
+
7
+ app.get('/test', (req, res) => {
8
+ res.sendFile('tests/parts/big.jpg', {
9
+ root: '.'
10
+ });
11
+ });
12
+
13
+ app.listen(13333, async () => {
14
+ console.log('Server is running on port 13333');
15
+
16
+ const response = await fetch('http://localhost:13333/test');
17
+ console.log(response.status, response.headers.get('Content-Length'));
18
+ process.exit(0);
19
+ });
@@ -0,0 +1,21 @@
1
+ // must support lastModified option
2
+
3
+ const express = require("express");
4
+ const path = require("path");
5
+
6
+ const app = express();
7
+
8
+ app.get('/test', (req, res) => {
9
+ res.sendFile('src/index.js', {
10
+ root: '.',
11
+ lastModified: true
12
+ });
13
+ });
14
+
15
+ app.listen(13333, async () => {
16
+ console.log('Server is running on port 13333');
17
+
18
+ const response = await fetch('http://localhost:13333/test');
19
+ console.log(await response.text(), response.headers.get('Last-Modified'));
20
+ process.exit(0);
21
+ });
@@ -0,0 +1,21 @@
1
+ // must support maxAge option
2
+
3
+ const express = require("express");
4
+ const path = require("path");
5
+
6
+ const app = express();
7
+
8
+ app.get('/test', (req, res) => {
9
+ res.sendFile('src/index.js', {
10
+ root: '.',
11
+ maxAge: '1d'
12
+ });
13
+ });
14
+
15
+ app.listen(13333, async () => {
16
+ console.log('Server is running on port 13333');
17
+
18
+ const response = await fetch('http://localhost:13333/test');
19
+ console.log(await response.text(), response.headers.get('Cache-Control'));
20
+ process.exit(0);
21
+ });
@@ -0,0 +1,35 @@
1
+ // must prevent path traversal attacks
2
+
3
+ const express = require("express");
4
+ const path = require("path");
5
+
6
+ const app = express();
7
+
8
+ app.get('/test', (req, res) => {
9
+ res.sendFile('src/../../index.js', { root: '.' });
10
+ });
11
+
12
+ app.get('/test2', (req, res) => {
13
+ res.sendFile(process.cwd() + '/src/../src/index.js');
14
+ });
15
+
16
+ app.get('/test3', (req, res) => {
17
+ res.sendFile(process.cwd() + '/src/index.js\0');
18
+ });
19
+
20
+
21
+ app.use((err, req, res, next) => {
22
+ res.status(500).send(err.message);
23
+ });
24
+
25
+ app.listen(13333, async () => {
26
+ console.log('Server is running on port 13333');
27
+
28
+ const response = await fetch('http://localhost:13333/test');
29
+ console.log(await response.text(), response.headers.get('Content-Type').split(';')[0]);
30
+ const response2 = await fetch('http://localhost:13333/test2');
31
+ console.log(await response2.text(), response2.headers.get('Content-Type').split(';')[0]);
32
+ const response3 = await fetch('http://localhost:13333/test3');
33
+ console.log(await response3.text(), response3.headers.get('Content-Type').split(';')[0]);
34
+ process.exit(0);
35
+ });
@@ -0,0 +1,57 @@
1
+ // must support Range header
2
+
3
+ const express = require("express");
4
+ const path = require("path");
5
+
6
+ const app = express();
7
+
8
+ app.get('/test', (req, res) => {
9
+ res.sendFile('src/index.js', { root: '.' });
10
+ });
11
+
12
+ app.use((err, req, res, next) => {
13
+ res.status(500).send(err.message);
14
+ });
15
+
16
+ app.listen(13333, async () => {
17
+ console.log('Server is running on port 13333');
18
+
19
+ const response = await fetch('http://localhost:13333/test', {
20
+ headers: {
21
+ Range: 'bytes=0-10'
22
+ }
23
+ });
24
+ console.log(await response.text(), response.headers.get('Content-Range'), response.headers.get('Content-Length'), response.status);
25
+ const response2 = await fetch('http://localhost:13333/test', {
26
+ headers: {
27
+ Range: 'bytes=11-20'
28
+ }
29
+ });
30
+ console.log(await response2.text(), response2.headers.get('Content-Range'), response2.headers.get('Content-Length'), response2.status);
31
+ const response3 = await fetch('http://localhost:13333/test', {
32
+ headers: {
33
+ Range: 'bytes=0-10, 21-30'
34
+ }
35
+ });
36
+ console.log((await response3.text()).slice(0, 10), response3.headers.get('Content-Range'), response3.headers.get('Content-Length'), response3.status);
37
+ const response4 = await fetch('http://localhost:13333/test', {
38
+ headers: {
39
+ Range: 'bytes=500-10000'
40
+ }
41
+ });
42
+ console.log((await response4.text()).slice(0, 10), response4.headers.get('Content-Range'), response4.headers.get('Content-Length'), response4.status);
43
+ const response5 = await fetch('http://localhost:13333/test', {
44
+ headers: {
45
+ Range: 'bytes=-10'
46
+ }
47
+ });
48
+ console.log((await response5.text()).slice(0, 10), response5.headers.get('Content-Range'), response5.headers.get('Content-Length'), response5.status);
49
+
50
+ const response6 = await fetch('http://localhost:13333/test', {
51
+ headers: {
52
+ Range: 'bytes=99999999999999999999999999-999999999999999999999999999999'
53
+ }
54
+ });
55
+ console.log((await response6.text()).slice(0, 10), response6.headers.get('Content-Range'), response6.headers.get('Content-Length'), response6.status);
56
+ process.exit(0);
57
+ });