mirror of
https://github.com/expressjs/express.git
synced 2026-02-26 08:45:36 +00:00
Compare commits
659 Commits
3.0.0alpha
...
3.12.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9bb47fba30 | ||
|
|
78d489d730 | ||
|
|
8ffb9f9477 | ||
|
|
9cb147370e | ||
|
|
75422c16bf | ||
|
|
e66667e465 | ||
|
|
7d6208e0af | ||
|
|
2a105df9f2 | ||
|
|
9c731f1883 | ||
|
|
5a4e9125de | ||
|
|
9db1367c2d | ||
|
|
73c5533e66 | ||
|
|
3b1f747f96 | ||
|
|
9e9827d236 | ||
|
|
a76d508424 | ||
|
|
f881784e9b | ||
|
|
5af625903f | ||
|
|
dc94f305cc | ||
|
|
8060a49c6c | ||
|
|
2fd31f6ea6 | ||
|
|
9cf7bba8f0 | ||
|
|
2e257d1cf7 | ||
|
|
56831d7799 | ||
|
|
6d65ae5ba6 | ||
|
|
c919b4a573 | ||
|
|
fe6f392c2d | ||
|
|
3b34a537ee | ||
|
|
ad79ce9c4b | ||
|
|
721f6388c3 | ||
|
|
298ac11018 | ||
|
|
bb6e207336 | ||
|
|
f433b7c7cf | ||
|
|
a94278abd1 | ||
|
|
a7cd5a2553 | ||
|
|
0dc5836d5e | ||
|
|
8751d7ecf8 | ||
|
|
c21226aa7c | ||
|
|
3e358458f4 | ||
|
|
766b3aecf7 | ||
|
|
8ab96ab80d | ||
|
|
1f2e00ef8d | ||
|
|
b49453cf0d | ||
|
|
faffcb889c | ||
|
|
3c0ec59432 | ||
|
|
d4a2843500 | ||
|
|
e7ad49bbbe | ||
|
|
ad9a414fae | ||
|
|
c18c2a8e68 | ||
|
|
1d54868c12 | ||
|
|
f7e73e2da0 | ||
|
|
867728b5ab | ||
|
|
f6bbeafd26 | ||
|
|
f14e39d451 | ||
|
|
084f5d891b | ||
|
|
b0f72e13d9 | ||
|
|
8d7d80ef9d | ||
|
|
cf5de082b5 | ||
|
|
1944451082 | ||
|
|
602e5a8200 | ||
|
|
83b8b7acb7 | ||
|
|
e660f19507 | ||
|
|
ff412b927d | ||
|
|
392ef1eb06 | ||
|
|
dcecdc9be6 | ||
|
|
ed69b68892 | ||
|
|
42b982e13c | ||
|
|
359f12791a | ||
|
|
b91cd66fc5 | ||
|
|
787d630157 | ||
|
|
1f938c560a | ||
|
|
a96924a555 | ||
|
|
33dc6629ff | ||
|
|
1b3fb0af8c | ||
|
|
12da523ff7 | ||
|
|
0f49d80623 | ||
|
|
1717516a78 | ||
|
|
328c6d3060 | ||
|
|
566720be15 | ||
|
|
65f13c3cc6 | ||
|
|
d98e2e7498 | ||
|
|
f7be983a77 | ||
|
|
a2553126dd | ||
|
|
0639c45acd | ||
|
|
920f46ad65 | ||
|
|
35a66d8a14 | ||
|
|
4e1e252e17 | ||
|
|
0461e55380 | ||
|
|
8dc4ff26f9 | ||
|
|
6f9e927633 | ||
|
|
40a43eb753 | ||
|
|
a8bb4bab2b | ||
|
|
417999884b | ||
|
|
17a739e35f | ||
|
|
66b38b58bc | ||
|
|
dc31ea34b8 | ||
|
|
d58ca520c8 | ||
|
|
4b646c2f8d | ||
|
|
35757ed1f5 | ||
|
|
fed0d5df5c | ||
|
|
c99fa6a192 | ||
|
|
0d468cbe6c | ||
|
|
f92ba6d0cf | ||
|
|
0408e3727e | ||
|
|
d5815922ca | ||
|
|
972c01afc9 | ||
|
|
8894e30869 | ||
|
|
5d8dba5fe0 | ||
|
|
90fbc1a33e | ||
|
|
55dea47b94 | ||
|
|
c7791a207b | ||
|
|
30d18888b9 | ||
|
|
df50669092 | ||
|
|
abd6b7c5c3 | ||
|
|
87912103c9 | ||
|
|
4ce1ee458e | ||
|
|
8aff64f89a | ||
|
|
ff23423d34 | ||
|
|
1d97599f8b | ||
|
|
e465624fd0 | ||
|
|
dc5932d177 | ||
|
|
cfd93b7529 | ||
|
|
8b2208f394 | ||
|
|
00a3b01f39 | ||
|
|
3baca251f0 | ||
|
|
72daae1d92 | ||
|
|
fcbe53ddb5 | ||
|
|
e9851672eb | ||
|
|
9a45f7bd3d | ||
|
|
85834fd146 | ||
|
|
a0c1ac7b45 | ||
|
|
7b0dca0f9c | ||
|
|
34c83d7d29 | ||
|
|
7c6882234e | ||
|
|
2e68ddbae9 | ||
|
|
7724fc6af7 | ||
|
|
2939075f03 | ||
|
|
606f68de02 | ||
|
|
863160ae49 | ||
|
|
edd39fb194 | ||
|
|
a71d264d45 | ||
|
|
8a7a695836 | ||
|
|
de54af4061 | ||
|
|
2f2a652bc9 | ||
|
|
1e638663de | ||
|
|
1684a8792a | ||
|
|
f47c0d9774 | ||
|
|
89e7264e53 | ||
|
|
cada9f61c8 | ||
|
|
373fa55981 | ||
|
|
2bc703cfc2 | ||
|
|
c9865b821d | ||
|
|
9c0de23645 | ||
|
|
b7a38af41d | ||
|
|
661914781e | ||
|
|
6e3f3887e9 | ||
|
|
a66d6bb034 | ||
|
|
2e197e2b98 | ||
|
|
55d1a4f964 | ||
|
|
82a7d7a977 | ||
|
|
dae54b456f | ||
|
|
1b7a044f33 | ||
|
|
18264403b1 | ||
|
|
04d43b7039 | ||
|
|
2dfecfb661 | ||
|
|
250f1f5f6e | ||
|
|
3ac718763f | ||
|
|
05e1555c0d | ||
|
|
855d1e2bf5 | ||
|
|
f0bfb3b2b2 | ||
|
|
4b4db0f7fb | ||
|
|
9bed2b80ee | ||
|
|
bb157c0cbf | ||
|
|
1ef05d4a28 | ||
|
|
0b88208022 | ||
|
|
c9d9ed3493 | ||
|
|
bd8b9f5781 | ||
|
|
9cbcf23df0 | ||
|
|
36e42db05b | ||
|
|
2bf6a1d813 | ||
|
|
e8373d3564 | ||
|
|
e218377a3d | ||
|
|
7d1aed4955 | ||
|
|
b4acbcf1fe | ||
|
|
50cb62c5d2 | ||
|
|
4cf868bd74 | ||
|
|
baa5a7c3e9 | ||
|
|
ee228f7aea | ||
|
|
d5b11c7d1b | ||
|
|
ed7db34bab | ||
|
|
57e45e3af8 | ||
|
|
1dc46478cb | ||
|
|
113ed0927d | ||
|
|
ab8be2d741 | ||
|
|
3b53b11fcd | ||
|
|
9fb661559b | ||
|
|
04882cf72c | ||
|
|
288176bbc9 | ||
|
|
5638a4fc62 | ||
|
|
3b4ce91fa3 | ||
|
|
1c87e5e9a8 | ||
|
|
a887e6a881 | ||
|
|
69290cad6f | ||
|
|
b66c7da05f | ||
|
|
92ddf77453 | ||
|
|
8e2f538983 | ||
|
|
2817d8caf2 | ||
|
|
b7f08fb159 | ||
|
|
0c2768f5bd | ||
|
|
09bede1a92 | ||
|
|
7059d3b71e | ||
|
|
e5de08faa1 | ||
|
|
e43ff076fd | ||
|
|
3ea7381dea | ||
|
|
f1c46f51e5 | ||
|
|
297fb4e0b0 | ||
|
|
9e406dfee2 | ||
|
|
30b7aa8a17 | ||
|
|
c1d16e0016 | ||
|
|
929ffb8d77 | ||
|
|
197a2e3b54 | ||
|
|
6cf6c8b918 | ||
|
|
058d7ec2ea | ||
|
|
752b5f705e | ||
|
|
e7fa579637 | ||
|
|
97781d4112 | ||
|
|
3ddd8e66a7 | ||
|
|
8a1e865e37 | ||
|
|
e850cb3ea3 | ||
|
|
13d3efe8df | ||
|
|
d6ecf785a2 | ||
|
|
19cb39869f | ||
|
|
a38bdf6758 | ||
|
|
bdbdab7fcc | ||
|
|
5aa9670120 | ||
|
|
8ad8cb93cc | ||
|
|
610e172fcf | ||
|
|
6942070a21 | ||
|
|
e283200511 | ||
|
|
54a192a5c5 | ||
|
|
c3bd65eda2 | ||
|
|
7c2ed1d2d6 | ||
|
|
3de81e0147 | ||
|
|
8fe1e2a5b4 | ||
|
|
909dbb81d5 | ||
|
|
26802a689c | ||
|
|
37239fb67f | ||
|
|
018dc40b32 | ||
|
|
52440955e6 | ||
|
|
c2f3d6ce2b | ||
|
|
be858f5d07 | ||
|
|
1f14734f91 | ||
|
|
6d1d694dbb | ||
|
|
ba5c48aa86 | ||
|
|
320d7807a9 | ||
|
|
6650a312b7 | ||
|
|
832c3b3744 | ||
|
|
76691bfd6b | ||
|
|
29fe5ea785 | ||
|
|
7a31a1d311 | ||
|
|
52a820113f | ||
|
|
aec3428489 | ||
|
|
a10f695b6f | ||
|
|
a3c9eacaf1 | ||
|
|
19d685b152 | ||
|
|
8ab44081d4 | ||
|
|
0431d22822 | ||
|
|
138d74aefa | ||
|
|
28562b2cf8 | ||
|
|
e0afda444f | ||
|
|
5a4cac58af | ||
|
|
545dca6c4d | ||
|
|
e59a882389 | ||
|
|
ccd9828535 | ||
|
|
41f0d32355 | ||
|
|
2f19b4fefc | ||
|
|
cd31cecfd1 | ||
|
|
2fe46b3905 | ||
|
|
24974f1f8f | ||
|
|
fd73bd006e | ||
|
|
7388c2c223 | ||
|
|
e2210b0b92 | ||
|
|
30919be2a0 | ||
|
|
10b21b41f7 | ||
|
|
28b8a3b5f7 | ||
|
|
8b2f1bba95 | ||
|
|
c805d80a9b | ||
|
|
d876778d22 | ||
|
|
412e571600 | ||
|
|
3296ed9cb3 | ||
|
|
91835e6816 | ||
|
|
f976625281 | ||
|
|
028d9d8a0c | ||
|
|
8559c0e2a4 | ||
|
|
06ead58240 | ||
|
|
28ca1b5221 | ||
|
|
6d872e6693 | ||
|
|
0b09c8981f | ||
|
|
a1d5676ecb | ||
|
|
f862ad29f5 | ||
|
|
15496da8fd | ||
|
|
802fb1632c | ||
|
|
69453ff889 | ||
|
|
28752cc3c0 | ||
|
|
9f06d9b03f | ||
|
|
3fb7c4e1db | ||
|
|
5fa685b602 | ||
|
|
eb1bbb92c0 | ||
|
|
d0e49f1a8a | ||
|
|
ea2664a4b8 | ||
|
|
da6524bd06 | ||
|
|
a231406931 | ||
|
|
6d39ed8ef7 | ||
|
|
f2563f4dde | ||
|
|
3df265b36a | ||
|
|
e382e6adc7 | ||
|
|
91c71d6c2e | ||
|
|
0d40c65b7f | ||
|
|
58f2057ba7 | ||
|
|
37179109db | ||
|
|
579857cfaa | ||
|
|
0b4e2df480 | ||
|
|
49cc1a70b1 | ||
|
|
f8a33d137a | ||
|
|
2db135dfc7 | ||
|
|
99bc628ad1 | ||
|
|
5ba6c301d7 | ||
|
|
88273a59f8 | ||
|
|
2e53cb72ec | ||
|
|
3b1597d79e | ||
|
|
776ee26bc3 | ||
|
|
ed273448b9 | ||
|
|
4bb91b3f67 | ||
|
|
c5f866098e | ||
|
|
6cfd01be6b | ||
|
|
53b8e25731 | ||
|
|
9e684d45bc | ||
|
|
09d9201787 | ||
|
|
a732d6d471 | ||
|
|
ee9d50c128 | ||
|
|
d1bafa0685 | ||
|
|
2604be5491 | ||
|
|
c52d9cdfbe | ||
|
|
aab6b7e721 | ||
|
|
d13cea46d5 | ||
|
|
82731dae6e | ||
|
|
476fba3e8b | ||
|
|
a566624f2d | ||
|
|
c6d7352f5c | ||
|
|
771573be30 | ||
|
|
b7afa4f0f4 | ||
|
|
4a1fa58704 | ||
|
|
6654b7162c | ||
|
|
f26a3cc806 | ||
|
|
57e48c4767 | ||
|
|
66d9a4ad43 | ||
|
|
78d9c98187 | ||
|
|
b686ec1182 | ||
|
|
158f452b50 | ||
|
|
916acd1dd3 | ||
|
|
b4f612474b | ||
|
|
9a884aa9ee | ||
|
|
db5636199e | ||
|
|
8211562cf6 | ||
|
|
9df93d6dec | ||
|
|
1e251af8d3 | ||
|
|
eed0f598a0 | ||
|
|
ec4d4a792a | ||
|
|
84e745f67c | ||
|
|
97edb23dba | ||
|
|
856782c81c | ||
|
|
a7266392f9 | ||
|
|
04b0c44bdf | ||
|
|
99c9eecde5 | ||
|
|
4d65bbf612 | ||
|
|
956aa0cfff | ||
|
|
d874476f0b | ||
|
|
30f9805539 | ||
|
|
46536dee39 | ||
|
|
24087d94df | ||
|
|
d02df2ebd5 | ||
|
|
16ba1f62a3 | ||
|
|
684dd1a3c6 | ||
|
|
8bcdcfeedd | ||
|
|
3bc372aa33 | ||
|
|
fc1c024041 | ||
|
|
89427228d1 | ||
|
|
420225f370 | ||
|
|
44a3fa6359 | ||
|
|
d853c833f0 | ||
|
|
03a796c460 | ||
|
|
75e47f2883 | ||
|
|
a4b2e48dfe | ||
|
|
57cda1578d | ||
|
|
6b1d7a94ff | ||
|
|
49abd7bec1 | ||
|
|
0ebebd80fe | ||
|
|
d157d47c6e | ||
|
|
e3ac2c5b02 | ||
|
|
cd54faa4af | ||
|
|
5beb1c4e30 | ||
|
|
4031aaa591 | ||
|
|
ba00e23630 | ||
|
|
8beb1f21ef | ||
|
|
fa8eec449b | ||
|
|
ab75fa048e | ||
|
|
bb29da5980 | ||
|
|
a4d7b75129 | ||
|
|
0fdceb3de3 | ||
|
|
480d0064e1 | ||
|
|
17bf04d1ef | ||
|
|
3ab30210a2 | ||
|
|
14fcfdee7e | ||
|
|
d4e56c1fa2 | ||
|
|
39ee6f8e79 | ||
|
|
8d21f1e45c | ||
|
|
618484a4fe | ||
|
|
64a234958a | ||
|
|
e4907ce8e8 | ||
|
|
33eaa8329c | ||
|
|
3c4fd57e51 | ||
|
|
a1e42ac33f | ||
|
|
ce7d7bfd8d | ||
|
|
9bd86cdddc | ||
|
|
0117464ac2 | ||
|
|
6f6eec7d8d | ||
|
|
a4e93c0fb8 | ||
|
|
e2ad0d3d6e | ||
|
|
763be5e631 | ||
|
|
c8526932f3 | ||
|
|
5cf29a3d29 | ||
|
|
18a3cc03ee | ||
|
|
ea5e254c7d | ||
|
|
060653bd4c | ||
|
|
b709009bc9 | ||
|
|
b80d7ec257 | ||
|
|
ff0384e610 | ||
|
|
ab9c275bde | ||
|
|
c70db96b06 | ||
|
|
1c616e29e2 | ||
|
|
cb7518435f | ||
|
|
79f81c0a25 | ||
|
|
72b9e48331 | ||
|
|
eba6aa1767 | ||
|
|
534fbdb307 | ||
|
|
6b309a4457 | ||
|
|
af5e38c31a | ||
|
|
4283f38698 | ||
|
|
2d49c0d1f3 | ||
|
|
a7ca3817db | ||
|
|
1f044547ee | ||
|
|
612fc47044 | ||
|
|
8959ff155b | ||
|
|
dadf57cc8b | ||
|
|
764b6c61d9 | ||
|
|
582dadf787 | ||
|
|
12d97169d7 | ||
|
|
c29cfa823d | ||
|
|
e183a9694e | ||
|
|
d6cb449011 | ||
|
|
7bf4ad30fc | ||
|
|
b3936b96e5 | ||
|
|
44d0625e91 | ||
|
|
c492cde048 | ||
|
|
c2fa6cc94d | ||
|
|
464608025b | ||
|
|
d653d2308b | ||
|
|
a52b1f121c | ||
|
|
9edd8be520 | ||
|
|
aa1d47600a | ||
|
|
be7ec8b40e | ||
|
|
8e12dd9c17 | ||
|
|
fee0f0dce0 | ||
|
|
0dd80e7b50 | ||
|
|
78d5b72081 | ||
|
|
e0df865401 | ||
|
|
2abcbed67a | ||
|
|
02b9d0b2e6 | ||
|
|
927e181db7 | ||
|
|
dc411b3175 | ||
|
|
1e870f0f0d | ||
|
|
3cd01598a5 | ||
|
|
3b6d683b7f | ||
|
|
eeef763f6d | ||
|
|
76d3ec583d | ||
|
|
077d8b9247 | ||
|
|
92840b9f68 | ||
|
|
bf60d5a041 | ||
|
|
56ffab045e | ||
|
|
496ee401d7 | ||
|
|
f0d5b3b368 | ||
|
|
88072a56ea | ||
|
|
0d3a637389 | ||
|
|
dc44f3c226 | ||
|
|
1029b0b97f | ||
|
|
84f8228b8c | ||
|
|
968e8f0121 | ||
|
|
9eb1da4568 | ||
|
|
315e79e9f0 | ||
|
|
363d0d4f41 | ||
|
|
5ac631a270 | ||
|
|
75fc882001 | ||
|
|
d7cb213eeb | ||
|
|
568e0d297a | ||
|
|
8edf358739 | ||
|
|
40be3ed05d | ||
|
|
2c174d6b3b | ||
|
|
60ee465bf7 | ||
|
|
51210d6b95 | ||
|
|
a6caa267bd | ||
|
|
cdb3e9dc0d | ||
|
|
f2f09767fb | ||
|
|
eec31d7126 | ||
|
|
3c5ad753b6 | ||
|
|
dd338b5567 | ||
|
|
1b15af713c | ||
|
|
89c5affc3b | ||
|
|
2bba69f633 | ||
|
|
4403f136b7 | ||
|
|
f7c1c638bb | ||
|
|
f2d7bbe0e9 | ||
|
|
87468cffce | ||
|
|
3f7e3a714e | ||
|
|
38a9caf159 | ||
|
|
500c8ab4b3 | ||
|
|
c4ad97d555 | ||
|
|
b96401ac83 | ||
|
|
32a5c9cba5 | ||
|
|
0217e6ce96 | ||
|
|
6bebe0837f | ||
|
|
ff1c6f0cfa | ||
|
|
8ac3e80bf0 | ||
|
|
3923ec89f7 | ||
|
|
fd8ca32ab2 | ||
|
|
ba2f66d765 | ||
|
|
056c840a06 | ||
|
|
20e8f08cb2 | ||
|
|
bac0c64633 | ||
|
|
48923055eb | ||
|
|
0f20a5e06a | ||
|
|
56bfb9249f | ||
|
|
5ed1544cab | ||
|
|
e5c7be9364 | ||
|
|
73ce9d028c | ||
|
|
75debbe5bc | ||
|
|
5f33d89ea5 | ||
|
|
42fd29efe8 | ||
|
|
2d91eac811 | ||
|
|
a50f02e87d | ||
|
|
214f913b0c | ||
|
|
1021c86300 | ||
|
|
386516815a | ||
|
|
d5e5647bba | ||
|
|
a861ea7eaf | ||
|
|
cb844132e6 | ||
|
|
8050308706 | ||
|
|
e79f72bf88 | ||
|
|
07b6c9f563 | ||
|
|
8f4e61a474 | ||
|
|
54d37c60f5 | ||
|
|
a93d375acc | ||
|
|
d66f0e5eb9 | ||
|
|
e84db12783 | ||
|
|
1ad2ecefe8 | ||
|
|
08b68ec8cd | ||
|
|
48be9233d8 | ||
|
|
a512d9b47d | ||
|
|
62234cc106 | ||
|
|
ab61837885 | ||
|
|
7a5041bf9c | ||
|
|
4d219135b2 | ||
|
|
26eeb64640 | ||
|
|
5426eb0b62 | ||
|
|
b9e32ec2c4 | ||
|
|
32b8613708 | ||
|
|
90eddb3439 | ||
|
|
accd6180c1 | ||
|
|
e770b674ff | ||
|
|
4f7c4d1051 | ||
|
|
78845e7d23 | ||
|
|
93f1cecc92 | ||
|
|
8ccd89f6ad | ||
|
|
0a210cce7a | ||
|
|
f110248462 | ||
|
|
96e4014a70 | ||
|
|
2173d00829 | ||
|
|
3827f5ef8b | ||
|
|
73bed61afa | ||
|
|
ee89ff5026 | ||
|
|
8df9e745d5 | ||
|
|
c76e954504 | ||
|
|
136f054614 | ||
|
|
e9a4b4f8ff | ||
|
|
5415c98ff9 | ||
|
|
39efa452fc | ||
|
|
bddcdee3fe | ||
|
|
2e8d44b444 | ||
|
|
70d68419b0 | ||
|
|
26fab2a27d | ||
|
|
0f5560eebd | ||
|
|
170dcc2907 | ||
|
|
18d6c78ef4 | ||
|
|
1248f0338b | ||
|
|
b400814d00 | ||
|
|
a934929bb3 | ||
|
|
140efb574c | ||
|
|
3c0c96114f | ||
|
|
362c96c8c1 | ||
|
|
5db3d0f9fc | ||
|
|
80c814c393 | ||
|
|
bf66465937 | ||
|
|
72eea7e6cd | ||
|
|
8f4cd13c89 | ||
|
|
6556cefc71 | ||
|
|
7bfb58920a | ||
|
|
2e324ccf5f | ||
|
|
1a10ee76b3 | ||
|
|
619e6349f6 | ||
|
|
b1ff68548f | ||
|
|
376b6c3bad | ||
|
|
f4c8a59b17 | ||
|
|
e6129d8ba5 | ||
|
|
d2baf11b8a | ||
|
|
82b5b12ca7 | ||
|
|
c145ab9b81 | ||
|
|
c10223b803 | ||
|
|
1e09b54ad2 | ||
|
|
d073e0aeb5 | ||
|
|
ce7293de13 | ||
|
|
108e66c24b | ||
|
|
f90401b8c0 | ||
|
|
a32e705d49 | ||
|
|
640cf4ca21 | ||
|
|
442e782692 | ||
|
|
0a874ad8b3 | ||
|
|
18083f0c13 | ||
|
|
f25aaf11e9 | ||
|
|
9b09257b28 | ||
|
|
f895516a2c | ||
|
|
76aa718b75 | ||
|
|
0acee67339 | ||
|
|
4475e335ef | ||
|
|
895673141d | ||
|
|
e4cd99ae1c | ||
|
|
c39a398d83 | ||
|
|
2787bd5bf0 | ||
|
|
6aaa7dc26d | ||
|
|
ebf60d2340 | ||
|
|
02d43846f6 | ||
|
|
8930cd563c | ||
|
|
2b90cd7d51 | ||
|
|
d5fde6a4b9 | ||
|
|
99b2e0fa08 | ||
|
|
ebcb1ca90e | ||
|
|
1763b073f9 | ||
|
|
908e467548 | ||
|
|
3c6ad5350b | ||
|
|
0ff3aa4b20 | ||
|
|
fd42b5c42c | ||
|
|
1311f2ac25 |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,6 +1,5 @@
|
||||
coverage.html
|
||||
coverage/
|
||||
.DS_Store
|
||||
lib-cov
|
||||
*.seed
|
||||
*.log
|
||||
*.csv
|
||||
@@ -13,6 +12,5 @@ benchmarks/graphs
|
||||
testing
|
||||
node_modules/
|
||||
testing
|
||||
.coverage_data
|
||||
cover_html
|
||||
test.js
|
||||
.idea
|
||||
|
||||
0
.gitmodules
vendored
0
.gitmodules
vendored
@@ -1,9 +1,10 @@
|
||||
.git*
|
||||
benchmarks/
|
||||
coverage/
|
||||
docs/
|
||||
examples/
|
||||
support/
|
||||
test/
|
||||
testing.js
|
||||
.DS_Store
|
||||
coverage.html
|
||||
lib-cov
|
||||
.travis.yml
|
||||
|
||||
10
.travis.yml
10
.travis.yml
@@ -1,3 +1,11 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- "0.8"
|
||||
- "0.10"
|
||||
- "0.11"
|
||||
matrix:
|
||||
allow_failures:
|
||||
- node_js: "0.11"
|
||||
fast_finish: true
|
||||
script: "npm run-script test-travis"
|
||||
after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls"
|
||||
|
||||
716
History.md
716
History.md
File diff suppressed because it is too large
Load Diff
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2009-2011 TJ Holowaychuk <tj@vision-media.ca>
|
||||
Copyright (c) 2009-2013 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
36
Makefile
36
Makefile
@@ -1,36 +0,0 @@
|
||||
|
||||
REPORTER = dot
|
||||
|
||||
docs: docs/express.md
|
||||
|
||||
docs/express.md: docs/application.md docs/request.md docs/response.md
|
||||
cat $^ > $@
|
||||
|
||||
docs/%.md: lib/%.js
|
||||
@mkdir -p docs
|
||||
dox --raw < $< | ./support/docs > $@
|
||||
|
||||
test: test-unit test-acceptance
|
||||
|
||||
test-unit:
|
||||
@NODE_ENV=test ./node_modules/.bin/mocha \
|
||||
--reporter $(REPORTER)
|
||||
|
||||
test-acceptance:
|
||||
@NODE_ENV=test ./node_modules/.bin/mocha \
|
||||
--reporter $(REPORTER) \
|
||||
test/acceptance/*.js
|
||||
|
||||
test-cov: lib-cov
|
||||
@EXPRESS_COV=1 $(MAKE) test REPORTER=html-cov > coverage.html
|
||||
|
||||
lib-cov:
|
||||
@jscoverage lib lib-cov
|
||||
|
||||
docclean:
|
||||
rm -fr docs
|
||||
|
||||
benchmark:
|
||||
@./support/bench
|
||||
|
||||
.PHONY: docs docclean test test-unit test-acceptance benchmark
|
||||
105
Readme.md
105
Readme.md
@@ -1,7 +1,8 @@
|
||||
[](http://expressjs.com/)
|
||||
|
||||

|
||||
Fast, unopinionated, minimalist web framework for [node](http://nodejs.org).
|
||||
|
||||
Fast, unopinionated, minimalist web framework for [node](http://nodejs.org). [](http://travis-ci.org/visionmedia/express)
|
||||
[](http://badge.fury.io/js/express) [](https://travis-ci.org/visionmedia/express) [](https://coveralls.io/r/visionmedia/express) [](https://www.gittip.com/visionmedia/)
|
||||
|
||||
```js
|
||||
var express = require('express');
|
||||
@@ -18,10 +19,6 @@ app.listen(3000);
|
||||
|
||||
$ npm install -g express
|
||||
|
||||
To install the 3.0 alpha:
|
||||
|
||||
$ npm install -g express@3.0
|
||||
|
||||
## Quick Start
|
||||
|
||||
The quickest way to get started with express is to utilize the executable `express(1)` to generate an application as shown below:
|
||||
@@ -53,111 +50,59 @@ app.listen(3000);
|
||||
|
||||
## Philosophy
|
||||
|
||||
The Express philosophy is to provide small, robust tooling for HTTP servers. Making
|
||||
The Express philosophy is to provide small, robust tooling for HTTP servers, making
|
||||
it a great solution for single page applications, web sites, hybrids, or public
|
||||
HTTP APIs.
|
||||
|
||||
Built on Connect you can use _only_ what you need, and nothing more, applications
|
||||
|
||||
Built on Connect, you can use _only_ what you need, and nothing more. Applications
|
||||
can be as big or as small as you like, even a single file. Express does
|
||||
not force you to use any specific ORM or template engine. With support for over
|
||||
14 template engines via [Consolidate.js](http://github.com/visionmedia/consolidate.js)
|
||||
14 template engines via [Consolidate.js](http://github.com/visionmedia/consolidate.js),
|
||||
you can quickly craft your perfect framework.
|
||||
|
||||
## More Information
|
||||
|
||||
* [Website and Documentation](http://expressjs.com/) stored at [visionmedia/expressjs.com](https://github.com/visionmedia/expressjs.com)
|
||||
* Join #express on freenode
|
||||
* [Google Group](http://groups.google.com/group/express-js) for discussion
|
||||
* Follow [tjholowaychuk](http://twitter.com/tjholowaychuk) on twitter for updates
|
||||
* Visit the [Wiki](http://github.com/visionmedia/express/wiki)
|
||||
* [日本語ドキュメンテーション](http://hideyukisaito.com/doc/expressjs/) by [hideyukisaito](https://github.com/hideyukisaito)
|
||||
* [Русскоязычная документация](http://express-js.ru/)
|
||||
* [Русскоязычная документация](http://jsman.ru/express/)
|
||||
* Run express examples [online](https://runnable.com/express)
|
||||
|
||||
## Viewing Examples
|
||||
|
||||
First install the dev dependencies to install all the example / test suite deps:
|
||||
Clone the Express repo, then install the dev dependencies to install all the example / test suite dependencies:
|
||||
|
||||
$ git clone git://github.com/visionmedia/express.git --depth 1
|
||||
$ cd express
|
||||
$ npm install -d
|
||||
$ npm install
|
||||
|
||||
then run whichever tests you want:
|
||||
Then run whichever tests you want:
|
||||
|
||||
$ node examples/content-negotiation
|
||||
|
||||
You can also view live examples here:
|
||||
|
||||
<a href="https://runnable.com/express" target="_blank"><img src="https://runnable.com/external/styles/assets/runnablebtn.png" style="width:67px;height:25px;"></a>
|
||||
|
||||
## Running Tests
|
||||
|
||||
To run the test suite first invoke the following command within the repo, installing the development dependencies:
|
||||
To run the test suite, first invoke the following command within the repo, installing the development dependencies:
|
||||
|
||||
$ npm install
|
||||
|
||||
then run the tests:
|
||||
Then run the tests:
|
||||
|
||||
$ make test
|
||||
```sh
|
||||
$ npm test
|
||||
```
|
||||
|
||||
## Contributors
|
||||
|
||||
```
|
||||
project: express
|
||||
commits: 3559
|
||||
active : 468 days
|
||||
files : 237
|
||||
authors:
|
||||
1891 Tj Holowaychuk 53.1%
|
||||
1285 visionmedia 36.1%
|
||||
182 TJ Holowaychuk 5.1%
|
||||
54 Aaron Heckmann 1.5%
|
||||
34 csausdev 1.0%
|
||||
26 ciaranj 0.7%
|
||||
21 Robert Sköld 0.6%
|
||||
6 Guillermo Rauch 0.2%
|
||||
3 Dav Glass 0.1%
|
||||
3 Nick Poulden 0.1%
|
||||
2 Randy Merrill 0.1%
|
||||
2 Benny Wong 0.1%
|
||||
2 Hunter Loftis 0.1%
|
||||
2 Jake Gordon 0.1%
|
||||
2 Brian McKinney 0.1%
|
||||
2 Roman Shtylman 0.1%
|
||||
2 Ben Weaver 0.1%
|
||||
2 Dave Hoover 0.1%
|
||||
2 Eivind Fjeldstad 0.1%
|
||||
2 Daniel Shaw 0.1%
|
||||
1 Matt Colyer 0.0%
|
||||
1 Pau Ramon 0.0%
|
||||
1 Pero Pejovic 0.0%
|
||||
1 Peter Rekdal Sunde 0.0%
|
||||
1 Raynos 0.0%
|
||||
1 Teng Siong Ong 0.0%
|
||||
1 Viktor Kelemen 0.0%
|
||||
1 ctide 0.0%
|
||||
1 8bitDesigner 0.0%
|
||||
1 isaacs 0.0%
|
||||
1 mgutz 0.0%
|
||||
1 pikeas 0.0%
|
||||
1 shuwatto 0.0%
|
||||
1 tstrimple 0.0%
|
||||
1 ewoudj 0.0%
|
||||
1 Adam Sanderson 0.0%
|
||||
1 Andrii Kostenko 0.0%
|
||||
1 Andy Hiew 0.0%
|
||||
1 Arpad Borsos 0.0%
|
||||
1 Ashwin Purohit 0.0%
|
||||
1 Benjen 0.0%
|
||||
1 Darren Torpey 0.0%
|
||||
1 Greg Ritter 0.0%
|
||||
1 Gregory Ritter 0.0%
|
||||
1 James Herdman 0.0%
|
||||
1 Jim Snodgrass 0.0%
|
||||
1 Joe McCann 0.0%
|
||||
1 Jonathan Dumaine 0.0%
|
||||
1 Jonathan Palardy 0.0%
|
||||
1 Jonathan Zacsh 0.0%
|
||||
1 Justin Lilly 0.0%
|
||||
1 Ken Sato 0.0%
|
||||
1 Maciej Małecki 0.0%
|
||||
1 Masahiro Hayashi 0.0%
|
||||
```
|
||||
https://github.com/visionmedia/express/graphs/contributors
|
||||
|
||||
## License
|
||||
## License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
|
||||
13
benchmarks/Makefile
Normal file
13
benchmarks/Makefile
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
all:
|
||||
@./run 1 middleware
|
||||
@./run 5 middleware
|
||||
@./run 10 middleware
|
||||
@./run 15 middleware
|
||||
@./run 20 middleware
|
||||
@./run 30 middleware
|
||||
@./run 50 middleware
|
||||
@./run 100 middleware
|
||||
@echo
|
||||
|
||||
.PHONY: all
|
||||
23
benchmarks/middleware.js
Normal file
23
benchmarks/middleware.js
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
var http = require('http');
|
||||
var express = require('..');
|
||||
var app = express();
|
||||
|
||||
// number of middleware
|
||||
|
||||
var n = parseInt(process.env.MW || '1', 10);
|
||||
console.log(' %s middleware', n);
|
||||
|
||||
while (n--) {
|
||||
app.use(function(req, res, next){
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
var body = new Buffer('Hello World');
|
||||
|
||||
app.use(function(req, res, next){
|
||||
res.send(body);
|
||||
});
|
||||
|
||||
app.listen(3333);
|
||||
16
benchmarks/run
Executable file
16
benchmarks/run
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo
|
||||
MW=$1 node $2 &
|
||||
pid=$!
|
||||
|
||||
sleep 2
|
||||
|
||||
wrk 'http://localhost:3333/?foo[bar]=baz' \
|
||||
-d 3 \
|
||||
-c 50 \
|
||||
-t 8 \
|
||||
| grep 'Requests/sec' \
|
||||
| awk '{ print " " $2 }'
|
||||
|
||||
kill $pid
|
||||
94
bin/express
94
bin/express
@@ -4,8 +4,7 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var exec = require('child_process').exec
|
||||
, program = require('commander')
|
||||
var program = require('commander')
|
||||
, mkdirp = require('mkdirp')
|
||||
, pkg = require('../package.json')
|
||||
, version = pkg.version
|
||||
@@ -16,9 +15,11 @@ var exec = require('child_process').exec
|
||||
|
||||
program
|
||||
.version(version)
|
||||
.usage('[options] [dir]')
|
||||
.option('-s, --sessions', 'add session support')
|
||||
.option('-e, --ejs', 'add ejs engine support (defaults to jade)')
|
||||
.option('-J, --jshtml', 'add jshtml engine support (defaults to jade)')
|
||||
.option('-H, --hogan', 'add hogan.js engine support')
|
||||
.option('-c, --css <engine>', 'add stylesheet <engine> support (less|stylus) (defaults to plain css)')
|
||||
.option('-f, --force', 'force on non-empty directory')
|
||||
.parse(process.argv);
|
||||
@@ -29,13 +30,14 @@ var path = program.args.shift() || '.';
|
||||
|
||||
// end-of-line code
|
||||
|
||||
var eol = 'win32' == os.platform() ? '\r\n' : '\n'
|
||||
var eol = os.EOL
|
||||
|
||||
// Template engine
|
||||
|
||||
program.template = 'jade';
|
||||
if (program.ejs) program.template = 'ejs';
|
||||
if (program.jshtml) program.template = 'jshtml';
|
||||
if (program.hogan) program.template = 'hjs';
|
||||
|
||||
/**
|
||||
* Routes index template.
|
||||
@@ -52,12 +54,27 @@ var index = [
|
||||
, '};'
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* Routes users template.
|
||||
*/
|
||||
|
||||
var users = [
|
||||
''
|
||||
, '/*'
|
||||
, ' * GET users listing.'
|
||||
, ' */'
|
||||
, ''
|
||||
, 'exports.list = function(req, res){'
|
||||
, ' res.send("respond with a resource");'
|
||||
, '};'
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* Jade layout template.
|
||||
*/
|
||||
|
||||
var jadeLayout = [
|
||||
'doctype 5'
|
||||
'doctype html'
|
||||
, 'html'
|
||||
, ' head'
|
||||
, ' title= title'
|
||||
@@ -122,6 +139,23 @@ var jshtmlIndex = [
|
||||
, '<p>Welcome to @write(title)</p>'
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* Hogan.js index template.
|
||||
*/
|
||||
var hoganIndex = [
|
||||
'<!DOCTYPE html>'
|
||||
, '<html>'
|
||||
, ' <head>'
|
||||
, ' <title>{{ title }}</title>'
|
||||
, ' <link rel=\'stylesheet\' href=\'/stylesheets/style.css\' />'
|
||||
, ' </head>'
|
||||
, ' <body>'
|
||||
, ' <h1>{{ title }}</h1>'
|
||||
, ' <p>Welcome to {{ title }}</p>'
|
||||
, ' </body>'
|
||||
, '</html>'
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* Default css template.
|
||||
*/
|
||||
@@ -174,32 +208,36 @@ var app = [
|
||||
, ' * Module dependencies.'
|
||||
, ' */'
|
||||
, ''
|
||||
, 'var express = require(\'express\')'
|
||||
, ' , routes = require(\'./routes\')'
|
||||
, ' , http = require(\'http\');'
|
||||
, 'var express = require(\'express\');'
|
||||
, 'var routes = require(\'./routes\');'
|
||||
, 'var user = require(\'./routes/user\');'
|
||||
, 'var http = require(\'http\');'
|
||||
, 'var path = require(\'path\');'
|
||||
, ''
|
||||
, 'var app = express();'
|
||||
, ''
|
||||
, 'app.configure(function(){'
|
||||
, ' app.set(\'port\', process.env.PORT || 3000);'
|
||||
, ' app.set(\'views\', __dirname + \'/views\');'
|
||||
, ' app.set(\'view engine\', \':TEMPLATE\');'
|
||||
, ' app.use(express.favicon());'
|
||||
, ' app.use(express.logger(\'dev\'));'
|
||||
, ' app.use(express.bodyParser());'
|
||||
, ' app.use(express.methodOverride());{sess}'
|
||||
, ' app.use(app.router);{css}'
|
||||
, ' app.use(express.static(__dirname + \'/public\'));'
|
||||
, '});'
|
||||
, '// all environments'
|
||||
, 'app.set(\'port\', process.env.PORT || 3000);'
|
||||
, 'app.set(\'views\', path.join(__dirname, \'views\'));'
|
||||
, 'app.set(\'view engine\', \':TEMPLATE\');'
|
||||
, 'app.use(express.favicon());'
|
||||
, 'app.use(express.logger(\'dev\'));'
|
||||
, 'app.use(express.json());'
|
||||
, 'app.use(express.urlencoded());'
|
||||
, 'app.use(express.methodOverride());{sess}'
|
||||
, 'app.use(app.router);{css}'
|
||||
, 'app.use(express.static(path.join(__dirname, \'public\')));'
|
||||
, ''
|
||||
, 'app.configure(\'development\', function(){'
|
||||
, '// development only'
|
||||
, 'if (\'development\' == app.get(\'env\')) {'
|
||||
, ' app.use(express.errorHandler());'
|
||||
, '});'
|
||||
, '}'
|
||||
, ''
|
||||
, 'app.get(\'/\', routes.index);'
|
||||
, 'app.get(\'/users\', user.list);'
|
||||
, ''
|
||||
, 'http.createServer(app).listen(app.get(\'port\'), function(){'
|
||||
, ' console.log("Express server listening on port " + app.get(\'port\'));'
|
||||
, ' console.log(\'Express server listening on port \' + app.get(\'port\'));'
|
||||
, '});'
|
||||
, ''
|
||||
].join(eol);
|
||||
@@ -260,6 +298,7 @@ function createApplicationAt(path) {
|
||||
|
||||
mkdir(path + '/routes', function(){
|
||||
write(path + '/routes/index.js', index);
|
||||
write(path + '/routes/user.js', users);
|
||||
});
|
||||
|
||||
mkdir(path + '/views', function(){
|
||||
@@ -275,6 +314,9 @@ function createApplicationAt(path) {
|
||||
write(path + '/views/layout.jshtml', jshtmlLayout);
|
||||
write(path + '/views/index.jshtml', jshtmlIndex);
|
||||
break;
|
||||
case 'hjs':
|
||||
write(path + '/views/index.hjs', hoganIndex);
|
||||
break;
|
||||
|
||||
}
|
||||
});
|
||||
@@ -282,10 +324,10 @@ function createApplicationAt(path) {
|
||||
// CSS Engine support
|
||||
switch (program.css) {
|
||||
case 'less':
|
||||
app = app.replace('{css}', eol + ' app.use(require(\'less-middleware\')({ src: __dirname + \'/public\' }));');
|
||||
app = app.replace('{css}', eol + 'app.use(require(\'less-middleware\')({ src: path.join(__dirname, \'public\') }));');
|
||||
break;
|
||||
case 'stylus':
|
||||
app = app.replace('{css}', eol + ' app.use(require(\'stylus\').middleware(__dirname + \'/public\'));');
|
||||
app = app.replace('{css}', eol + 'app.use(require(\'stylus\').middleware(path.join(__dirname, \'public\')));');
|
||||
break;
|
||||
default:
|
||||
app = app.replace('{css}', '');
|
||||
@@ -293,7 +335,7 @@ function createApplicationAt(path) {
|
||||
|
||||
// Session support
|
||||
app = app.replace('{sess}', program.sessions
|
||||
? eol + ' app.use(express.cookieParser(\'your secret here\'));' + eol + ' app.use(express.session());'
|
||||
? eol + 'app.use(express.session({ secret: \'your secret here\' }));'
|
||||
: '');
|
||||
|
||||
// Template support
|
||||
@@ -304,7 +346,7 @@ function createApplicationAt(path) {
|
||||
name: 'application-name'
|
||||
, version: '0.0.1'
|
||||
, private: true
|
||||
, scripts: { start: 'node app' }
|
||||
, scripts: { start: 'node app.js' }
|
||||
, dependencies: {
|
||||
express: version
|
||||
}
|
||||
@@ -315,7 +357,7 @@ function createApplicationAt(path) {
|
||||
// CSS Engine support
|
||||
switch (program.css) {
|
||||
case 'less':
|
||||
pkg.dependencies['less-middleware'] = '*';
|
||||
pkg.dependencies['less-middleware'] = '~0.1.15';
|
||||
break;
|
||||
default:
|
||||
if (program.css) {
|
||||
|
||||
25
client.js
25
client.js
@@ -1,25 +0,0 @@
|
||||
|
||||
var http = require('http');
|
||||
|
||||
var times = 50;
|
||||
|
||||
while (times--) {
|
||||
var req = http.request({
|
||||
port: 3000
|
||||
, method: 'POST'
|
||||
, headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
|
||||
});
|
||||
|
||||
req.on('response', function(res){
|
||||
console.log(res.statusCode);
|
||||
});
|
||||
|
||||
var n = 500000;
|
||||
while (n--) {
|
||||
req.write('foo=bar&bar=baz&');
|
||||
}
|
||||
|
||||
req.write('foo=bar&bar=baz');
|
||||
|
||||
req.end();
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
|
||||
# app
|
||||
|
||||
Application prototype.
|
||||
|
||||
# app.use()
|
||||
|
||||
Proxy `connect#use()` to apply settings to
|
||||
mounted applications.
|
||||
|
||||
# app.engine()
|
||||
|
||||
Register the given template engine callback `fn`
|
||||
as `ext`.
|
||||
|
||||
By default will `require()` the engine based on the
|
||||
file extension. For example if you try to render
|
||||
a "foo.jade" file Express will invoke the following internally:
|
||||
|
||||
app.engine('jade', require('jade').__express);
|
||||
|
||||
For engines that do not provide `.__express` out of the box,
|
||||
or if you wish to "map" a different extension to the template engine
|
||||
you may use this method. For example mapping the EJS template engine to
|
||||
".html" files
|
||||
|
||||
app.engine('html', require('ejs').renderFile);
|
||||
|
||||
In this case EJS provides a `.renderFile()` method with
|
||||
the same signature that Express expects: `(path, options, callback)`,
|
||||
though note that it aliases this method as `ejs.__express` internally
|
||||
so if you're using ".ejs" extensions you dont need to do anything.
|
||||
|
||||
Some template engines do not follow this convention, the
|
||||
[Consolidate.js](https://github.com/visionmedia/consolidate.js)
|
||||
library was created to map all of node's popular template
|
||||
engines to follow this convention, thus allowing them to
|
||||
work seemlessly within Express.
|
||||
|
||||
# app.param()
|
||||
|
||||
Map the given param placeholder `name`(s) to the given callback(s).
|
||||
|
||||
Parameter mapping is used to provide pre-conditions to routes
|
||||
which use normalized placeholders. For example a _:user_id_ parameter
|
||||
could automatically load a user's information from the database without
|
||||
any additional code,
|
||||
|
||||
The callback uses the samesignature as middleware, the only differencing
|
||||
being that the value of the placeholder is passed, in this case the _id_
|
||||
of the user. Once the `next()` function is invoked, just like middleware
|
||||
it will continue on to execute the route, or subsequent parameter functions.
|
||||
|
||||
app.param('user_id', function(req, res, next, id){
|
||||
User.find(id, function(err, user){
|
||||
if (err) {
|
||||
next(err);
|
||||
} else if (user) {
|
||||
req.user = user;
|
||||
next();
|
||||
} else {
|
||||
next(new Error('failed to load user'));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
# app.set()
|
||||
|
||||
Assign `setting` to `val`, or return `setting`'s value.
|
||||
|
||||
app.set('foo', 'bar');
|
||||
app.get('foo');
|
||||
// => "bar"
|
||||
|
||||
Mounted servers inherit their parent server's settings.
|
||||
|
||||
# app.enabled()
|
||||
|
||||
Check if `setting` is enabled (truthy).
|
||||
|
||||
app.enabled('foo')
|
||||
// => false
|
||||
|
||||
app.enable('foo')
|
||||
app.enabled('foo')
|
||||
// => true
|
||||
|
||||
# app.disabled()
|
||||
|
||||
Check if `setting` is disabled.
|
||||
|
||||
app.disabled('foo')
|
||||
// => true
|
||||
|
||||
app.enable('foo')
|
||||
app.disabled('foo')
|
||||
// => false
|
||||
|
||||
# app.enable()
|
||||
|
||||
Enable `setting`.
|
||||
|
||||
# app.disable()
|
||||
|
||||
Disable `setting`.
|
||||
|
||||
# app.configure()
|
||||
|
||||
Configure callback for zero or more envs,
|
||||
when no `env` is specified that callback will
|
||||
be invoked for all environments. Any combination
|
||||
can be used multiple times, in any order desired.
|
||||
|
||||
## Examples
|
||||
|
||||
app.configure(function(){
|
||||
// executed for all envs
|
||||
});
|
||||
|
||||
app.configure('stage', function(){
|
||||
// executed staging env
|
||||
});
|
||||
|
||||
app.configure('stage', 'production', function(){
|
||||
// executed for stage and production
|
||||
});
|
||||
|
||||
## Note
|
||||
|
||||
These callbacks are invoked immediately, and
|
||||
are effectively sugar for the following.
|
||||
|
||||
var env = process.env.NODE_ENV || 'development';
|
||||
|
||||
switch (env) {
|
||||
case 'development':
|
||||
...
|
||||
break;
|
||||
case 'stage':
|
||||
...
|
||||
break;
|
||||
case 'production':
|
||||
...
|
||||
break;
|
||||
}
|
||||
|
||||
# app.all()
|
||||
|
||||
Special-cased "all" method, applying the given route `path`,
|
||||
middleware, and callback to _every_ HTTP method.
|
||||
|
||||
# app.render()
|
||||
|
||||
Render the given view `name` name with `options`
|
||||
and a callback accepting an error and the
|
||||
rendered template string.
|
||||
|
||||
## Example
|
||||
|
||||
app.render('email', { name: 'Tobi' }, function(err, html){
|
||||
// ...
|
||||
})
|
||||
|
||||
# app.listen()
|
||||
|
||||
Listen for connections.
|
||||
|
||||
A node `http.Server` is returned, with this
|
||||
application (which is a `Function`) as its
|
||||
callback. If you wish to create both an HTTP
|
||||
and HTTPS server you may do so with the "http"
|
||||
and "https" modules as shown here.
|
||||
|
||||
var http = require('http')
|
||||
, https = require('https')
|
||||
, express = require('express')
|
||||
, app = express();
|
||||
|
||||
http.createServer(app).listen(80);
|
||||
http.createServer({ ... }, app).listen(443);
|
||||
|
||||
511
docs/express.md
511
docs/express.md
@@ -1,511 +0,0 @@
|
||||
|
||||
# app
|
||||
|
||||
Application prototype.
|
||||
|
||||
# app.use()
|
||||
|
||||
Proxy `connect#use()` to apply settings to
|
||||
mounted applications.
|
||||
|
||||
# app.engine()
|
||||
|
||||
Register the given template engine callback `fn`
|
||||
as `ext`.
|
||||
|
||||
By default will `require()` the engine based on the
|
||||
file extension. For example if you try to render
|
||||
a "foo.jade" file Express will invoke the following internally:
|
||||
|
||||
app.engine('jade', require('jade').__express);
|
||||
|
||||
For engines that do not provide `.__express` out of the box,
|
||||
or if you wish to "map" a different extension to the template engine
|
||||
you may use this method. For example mapping the EJS template engine to
|
||||
".html" files
|
||||
|
||||
app.engine('html', require('ejs').renderFile);
|
||||
|
||||
In this case EJS provides a `.renderFile()` method with
|
||||
the same signature that Express expects: `(path, options, callback)`,
|
||||
though note that it aliases this method as `ejs.__express` internally
|
||||
so if you're using ".ejs" extensions you dont need to do anything.
|
||||
|
||||
Some template engines do not follow this convention, the
|
||||
[Consolidate.js](https://github.com/visionmedia/consolidate.js)
|
||||
library was created to map all of node's popular template
|
||||
engines to follow this convention, thus allowing them to
|
||||
work seemlessly within Express.
|
||||
|
||||
# app.param()
|
||||
|
||||
Map the given param placeholder `name`(s) to the given callback(s).
|
||||
|
||||
Parameter mapping is used to provide pre-conditions to routes
|
||||
which use normalized placeholders. For example a _:user_id_ parameter
|
||||
could automatically load a user's information from the database without
|
||||
any additional code,
|
||||
|
||||
The callback uses the samesignature as middleware, the only differencing
|
||||
being that the value of the placeholder is passed, in this case the _id_
|
||||
of the user. Once the `next()` function is invoked, just like middleware
|
||||
it will continue on to execute the route, or subsequent parameter functions.
|
||||
|
||||
app.param('user_id', function(req, res, next, id){
|
||||
User.find(id, function(err, user){
|
||||
if (err) {
|
||||
next(err);
|
||||
} else if (user) {
|
||||
req.user = user;
|
||||
next();
|
||||
} else {
|
||||
next(new Error('failed to load user'));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
# app.set()
|
||||
|
||||
Assign `setting` to `val`, or return `setting`'s value.
|
||||
|
||||
app.set('foo', 'bar');
|
||||
app.get('foo');
|
||||
// => "bar"
|
||||
|
||||
Mounted servers inherit their parent server's settings.
|
||||
|
||||
# app.enabled()
|
||||
|
||||
Check if `setting` is enabled (truthy).
|
||||
|
||||
app.enabled('foo')
|
||||
// => false
|
||||
|
||||
app.enable('foo')
|
||||
app.enabled('foo')
|
||||
// => true
|
||||
|
||||
# app.disabled()
|
||||
|
||||
Check if `setting` is disabled.
|
||||
|
||||
app.disabled('foo')
|
||||
// => true
|
||||
|
||||
app.enable('foo')
|
||||
app.disabled('foo')
|
||||
// => false
|
||||
|
||||
# app.enable()
|
||||
|
||||
Enable `setting`.
|
||||
|
||||
# app.disable()
|
||||
|
||||
Disable `setting`.
|
||||
|
||||
# app.configure()
|
||||
|
||||
Configure callback for zero or more envs,
|
||||
when no `env` is specified that callback will
|
||||
be invoked for all environments. Any combination
|
||||
can be used multiple times, in any order desired.
|
||||
|
||||
## Examples
|
||||
|
||||
app.configure(function(){
|
||||
// executed for all envs
|
||||
});
|
||||
|
||||
app.configure('stage', function(){
|
||||
// executed staging env
|
||||
});
|
||||
|
||||
app.configure('stage', 'production', function(){
|
||||
// executed for stage and production
|
||||
});
|
||||
|
||||
## Note
|
||||
|
||||
These callbacks are invoked immediately, and
|
||||
are effectively sugar for the following.
|
||||
|
||||
var env = process.env.NODE_ENV || 'development';
|
||||
|
||||
switch (env) {
|
||||
case 'development':
|
||||
...
|
||||
break;
|
||||
case 'stage':
|
||||
...
|
||||
break;
|
||||
case 'production':
|
||||
...
|
||||
break;
|
||||
}
|
||||
|
||||
# app.all()
|
||||
|
||||
Special-cased "all" method, applying the given route `path`,
|
||||
middleware, and callback to _every_ HTTP method.
|
||||
|
||||
# app.render()
|
||||
|
||||
Render the given view `name` name with `options`
|
||||
and a callback accepting an error and the
|
||||
rendered template string.
|
||||
|
||||
## Example
|
||||
|
||||
app.render('email', { name: 'Tobi' }, function(err, html){
|
||||
// ...
|
||||
})
|
||||
|
||||
# app.listen()
|
||||
|
||||
Listen for connections.
|
||||
|
||||
A node `http.Server` is returned, with this
|
||||
application (which is a `Function`) as its
|
||||
callback. If you wish to create both an HTTP
|
||||
and HTTPS server you may do so with the "http"
|
||||
and "https" modules as shown here.
|
||||
|
||||
var http = require('http')
|
||||
, https = require('https')
|
||||
, express = require('express')
|
||||
, app = express();
|
||||
|
||||
http.createServer(app).listen(80);
|
||||
http.createServer({ ... }, app).listen(443);
|
||||
|
||||
|
||||
# req
|
||||
|
||||
Request prototype.
|
||||
|
||||
# req.get
|
||||
|
||||
Return request header.
|
||||
|
||||
The `Referrer` header field is special-cased,
|
||||
both `Referrer` and `Referer` are interchangeable.
|
||||
|
||||
## Examples
|
||||
|
||||
req.get('Content-Type');
|
||||
// => "text/plain"
|
||||
|
||||
req.get('content-type');
|
||||
// => "text/plain"
|
||||
|
||||
req.get('Something');
|
||||
// => undefined
|
||||
|
||||
Aliased as `req.header()`.
|
||||
|
||||
# req.accepts()
|
||||
|
||||
Check if the given `type(s)` is acceptable, returning
|
||||
the best match when true, otherwise `undefined`, in which
|
||||
case you should respond with 406 "Not Acceptable".
|
||||
|
||||
The `type` value may be a single mime type string
|
||||
such as "application/json", the extension name
|
||||
such as "json", a comma-delimted list such as "json, html, text/plain",
|
||||
or an array `["json", "html", "text/plain"]`. When a list
|
||||
or array is given the _best_ match, if any is returned.
|
||||
|
||||
## Examples
|
||||
|
||||
// Accept: text/html
|
||||
req.accepts('html');
|
||||
// => "html"
|
||||
|
||||
// Accept: text/*, application/json
|
||||
req.accepts('html');
|
||||
// => "html"
|
||||
req.accepts('text/html');
|
||||
// => "text/html"
|
||||
req.accepts('json, text');
|
||||
// => "json"
|
||||
req.accepts('application/json');
|
||||
// => "application/json"
|
||||
|
||||
// Accept: text/*, application/json
|
||||
req.accepts('image/png');
|
||||
req.accepts('png');
|
||||
// => undefined
|
||||
|
||||
// Accept: text/*;q=.5, application/json
|
||||
req.accepts(['html', 'json']);
|
||||
req.accepts('html, json');
|
||||
// => "json"
|
||||
|
||||
# req.acceptsCharset()
|
||||
|
||||
Check if the given `charset` is acceptable,
|
||||
otherwise you should respond with 406 "Not Acceptable".
|
||||
|
||||
# req.acceptsLanguage()
|
||||
|
||||
Check if the given `lang` is acceptable,
|
||||
otherwise you should respond with 406 "Not Acceptable".
|
||||
|
||||
# req.param()
|
||||
|
||||
Return the value of param `name` when present or `defaultValue`.
|
||||
|
||||
- Checks body params, ex: id=12, {"id":12}
|
||||
- Checks route placeholders, ex: _/user/:id_
|
||||
- Checks query string params, ex: ?id=12
|
||||
|
||||
To utilize request bodies, `req.body`
|
||||
should be an object. This can be done by using
|
||||
the `connect.bodyParser()` middleware.
|
||||
|
||||
# req.is()
|
||||
|
||||
Check if the incoming request contains the "Content-Type"
|
||||
header field, and it contains the give mime `type`.
|
||||
|
||||
## Examples
|
||||
|
||||
// With Content-Type: text/html; charset=utf-8
|
||||
req.is('html');
|
||||
req.is('text/html');
|
||||
req.is('text/*');
|
||||
// => true
|
||||
|
||||
// When Content-Type is application/json
|
||||
req.is('json');
|
||||
req.is('application/json');
|
||||
req.is('application/*');
|
||||
// => true
|
||||
|
||||
req.is('html');
|
||||
// => false
|
||||
|
||||
Now within our route callbacks, we can use to to assert content types
|
||||
such as "image/jpeg", "image/png", etc.
|
||||
|
||||
app.post('/image/upload', function(req, res, next){
|
||||
if (req.is('image/*')) {
|
||||
// do something
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
# res
|
||||
|
||||
Response prototype.
|
||||
|
||||
# res.status()
|
||||
|
||||
Set status `code`.
|
||||
|
||||
# res.send()
|
||||
|
||||
Send a response.
|
||||
|
||||
## Examples
|
||||
|
||||
res.send(new Buffer('wahoo'));
|
||||
res.send({ some: 'json' });
|
||||
res.send('<p>some html</p>');
|
||||
res.send(404, 'Sorry, cant find that');
|
||||
res.send(404);
|
||||
|
||||
# res.json()
|
||||
|
||||
Send JSON response.
|
||||
|
||||
## Examples
|
||||
|
||||
res.json(null);
|
||||
res.json({ user: 'tj' });
|
||||
res.json(500, 'oh noes!');
|
||||
res.json(404, 'I dont have that');
|
||||
|
||||
# res.sendfile()
|
||||
|
||||
Transfer the file at the given `path`.
|
||||
|
||||
Automatically sets the _Content-Type_ response header field.
|
||||
The callback `fn(err)` is invoked when the transfer is complete
|
||||
or when an error occurs. Be sure to check `res.sentHeader`
|
||||
if you wish to attempt responding, as the header and some data
|
||||
may have already been transferred.
|
||||
|
||||
## Options
|
||||
|
||||
- `maxAge` defaulting to 0
|
||||
- `root` root directory for relative filenames
|
||||
|
||||
## Examples
|
||||
|
||||
The following example illustrates how `res.sendfile()` may
|
||||
be used as an alternative for the `static()` middleware for
|
||||
dynamic situations. The code backing `res.sendfile()` is actually
|
||||
the same code, so HTTP cache support etc is identical.
|
||||
|
||||
app.get('/user/:uid/photos/:file', function(req, res){
|
||||
var uid = req.params.uid
|
||||
, file = req.params.file;
|
||||
|
||||
req.user.mayViewFilesFrom(uid, function(yes){
|
||||
if (yes) {
|
||||
res.sendfile('/uploads/' + uid + '/' + file);
|
||||
} else {
|
||||
res.send(403, 'Sorry! you cant see that.');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
# res.download()
|
||||
|
||||
Transfer the file at the given `path` as an attachment.
|
||||
|
||||
Optionally providing an alternate attachment `filename`,
|
||||
and optional callback `fn(err)`. The callback is invoked
|
||||
when the data transfer is complete, or when an error has
|
||||
ocurred. Be sure to check `res.headerSent` if you plan to respond.
|
||||
|
||||
# res.format()
|
||||
|
||||
Respond to the Acceptable formats using an `obj`
|
||||
of mime-type callbacks.
|
||||
|
||||
This method uses `req.accepted`, an array of
|
||||
acceptable types ordered by their quality values.
|
||||
When "Accept" is not present the _first_ callback
|
||||
is invoked, otherwise the first match is used. When
|
||||
no match is performed the server responds with
|
||||
406 "Not Acceptable".
|
||||
|
||||
Content-Type is set for you, however if you choose
|
||||
you may alter this within the callback using `res.type()`
|
||||
or `res.set('Content-Type', ...)`.
|
||||
|
||||
res.format({
|
||||
'text/plain': function(){
|
||||
res.send('hey');
|
||||
},
|
||||
|
||||
'text/html': function(){
|
||||
res.send('<p>hey</p>');
|
||||
},
|
||||
|
||||
'appliation/json': function(){
|
||||
res.send({ message: 'hey' });
|
||||
}
|
||||
});
|
||||
|
||||
In addition to canonicalized MIME types you may
|
||||
## also use extnames mapped to these types
|
||||
|
||||
res.format({
|
||||
text: function(){
|
||||
res.send('hey');
|
||||
},
|
||||
|
||||
html: function(){
|
||||
res.send('<p>hey</p>');
|
||||
},
|
||||
|
||||
json: function(){
|
||||
res.send({ message: 'hey' });
|
||||
}
|
||||
});
|
||||
|
||||
# res.attachment()
|
||||
|
||||
Set _Content-Disposition_ header to _attachment_ with optional `filename`.
|
||||
|
||||
# res.set()
|
||||
|
||||
Set header `field` to `val`, or pass
|
||||
an object of of header fields.
|
||||
|
||||
## Examples
|
||||
|
||||
res.set('Accept', 'application/json');
|
||||
res.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' });
|
||||
|
||||
# res.get()
|
||||
|
||||
Get value for header `field`.
|
||||
|
||||
# res.clearCookie()
|
||||
|
||||
Clear cookie `name`.
|
||||
|
||||
# res.signedCookie()
|
||||
|
||||
Set a signed cookie with the given `name` and `val`.
|
||||
See `res.cookie()` for details.
|
||||
|
||||
# res.cookie()
|
||||
|
||||
Set cookie `name` to `val`, with the given `options`.
|
||||
|
||||
## Options
|
||||
|
||||
- `maxAge` max-age in milliseconds, converted to `expires`
|
||||
- `path` defaults to "/"
|
||||
|
||||
## Examples
|
||||
|
||||
// "Remember Me" for 15 minutes
|
||||
res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });
|
||||
|
||||
// save as above
|
||||
res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })
|
||||
|
||||
# res.redirect()
|
||||
|
||||
Redirect to the given `url` with optional response `status`
|
||||
defaulting to 302.
|
||||
|
||||
The given `url` can also be the name of a mapped url, for
|
||||
example by default express supports "back" which redirects
|
||||
to the _Referrer_ or _Referer_ headers or "/".
|
||||
|
||||
## Examples
|
||||
|
||||
res.redirect('/foo/bar');
|
||||
res.redirect('http://example.com');
|
||||
res.redirect(301, 'http://example.com');
|
||||
res.redirect('../login'); // /blog/post/1 -> /blog/login
|
||||
|
||||
## Mounting
|
||||
|
||||
When an application is mounted, and `res.redirect()`
|
||||
is given a path that does _not_ lead with "/". For
|
||||
example suppose a "blog" app is mounted at "/blog",
|
||||
the following redirect would result in "/blog/login":
|
||||
|
||||
res.redirect('login');
|
||||
|
||||
While the leading slash would result in a redirect to "/login":
|
||||
|
||||
res.redirect('/login');
|
||||
|
||||
# res.render()
|
||||
|
||||
Render `view` with the given `options` and optional callback `fn`.
|
||||
When a callback function is given a response will _not_ be made
|
||||
automatically, otherwise a response of _200_ and _text/html_ is given.
|
||||
|
||||
## Options
|
||||
|
||||
- `status` Response status code (`res.statusCode`)
|
||||
- `charset` Set the charset (`res.charset`)
|
||||
|
||||
## Reserved locals
|
||||
|
||||
- `cache` boolean hinting to the engine it should cache
|
||||
- `filename` filename of the view being rendered
|
||||
|
||||
118
docs/request.md
118
docs/request.md
@@ -1,118 +0,0 @@
|
||||
|
||||
# req
|
||||
|
||||
Request prototype.
|
||||
|
||||
# req.get
|
||||
|
||||
Return request header.
|
||||
|
||||
The `Referrer` header field is special-cased,
|
||||
both `Referrer` and `Referer` are interchangeable.
|
||||
|
||||
## Examples
|
||||
|
||||
req.get('Content-Type');
|
||||
// => "text/plain"
|
||||
|
||||
req.get('content-type');
|
||||
// => "text/plain"
|
||||
|
||||
req.get('Something');
|
||||
// => undefined
|
||||
|
||||
Aliased as `req.header()`.
|
||||
|
||||
# req.accepts()
|
||||
|
||||
Check if the given `type(s)` is acceptable, returning
|
||||
the best match when true, otherwise `undefined`, in which
|
||||
case you should respond with 406 "Not Acceptable".
|
||||
|
||||
The `type` value may be a single mime type string
|
||||
such as "application/json", the extension name
|
||||
such as "json", a comma-delimted list such as "json, html, text/plain",
|
||||
or an array `["json", "html", "text/plain"]`. When a list
|
||||
or array is given the _best_ match, if any is returned.
|
||||
|
||||
## Examples
|
||||
|
||||
// Accept: text/html
|
||||
req.accepts('html');
|
||||
// => "html"
|
||||
|
||||
// Accept: text/*, application/json
|
||||
req.accepts('html');
|
||||
// => "html"
|
||||
req.accepts('text/html');
|
||||
// => "text/html"
|
||||
req.accepts('json, text');
|
||||
// => "json"
|
||||
req.accepts('application/json');
|
||||
// => "application/json"
|
||||
|
||||
// Accept: text/*, application/json
|
||||
req.accepts('image/png');
|
||||
req.accepts('png');
|
||||
// => undefined
|
||||
|
||||
// Accept: text/*;q=.5, application/json
|
||||
req.accepts(['html', 'json']);
|
||||
req.accepts('html, json');
|
||||
// => "json"
|
||||
|
||||
# req.acceptsCharset()
|
||||
|
||||
Check if the given `charset` is acceptable,
|
||||
otherwise you should respond with 406 "Not Acceptable".
|
||||
|
||||
# req.acceptsLanguage()
|
||||
|
||||
Check if the given `lang` is acceptable,
|
||||
otherwise you should respond with 406 "Not Acceptable".
|
||||
|
||||
# req.param()
|
||||
|
||||
Return the value of param `name` when present or `defaultValue`.
|
||||
|
||||
- Checks body params, ex: id=12, {"id":12}
|
||||
- Checks route placeholders, ex: _/user/:id_
|
||||
- Checks query string params, ex: ?id=12
|
||||
|
||||
To utilize request bodies, `req.body`
|
||||
should be an object. This can be done by using
|
||||
the `connect.bodyParser()` middleware.
|
||||
|
||||
# req.is()
|
||||
|
||||
Check if the incoming request contains the "Content-Type"
|
||||
header field, and it contains the give mime `type`.
|
||||
|
||||
## Examples
|
||||
|
||||
// With Content-Type: text/html; charset=utf-8
|
||||
req.is('html');
|
||||
req.is('text/html');
|
||||
req.is('text/*');
|
||||
// => true
|
||||
|
||||
// When Content-Type is application/json
|
||||
req.is('json');
|
||||
req.is('application/json');
|
||||
req.is('application/*');
|
||||
// => true
|
||||
|
||||
req.is('html');
|
||||
// => false
|
||||
|
||||
Now within our route callbacks, we can use to to assert content types
|
||||
such as "image/jpeg", "image/png", etc.
|
||||
|
||||
app.post('/image/upload', function(req, res, next){
|
||||
if (req.is('image/*')) {
|
||||
// do something
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
|
||||
212
docs/response.md
212
docs/response.md
@@ -1,212 +0,0 @@
|
||||
|
||||
# res
|
||||
|
||||
Response prototype.
|
||||
|
||||
# res.status()
|
||||
|
||||
Set status `code`.
|
||||
|
||||
# res.send()
|
||||
|
||||
Send a response.
|
||||
|
||||
## Examples
|
||||
|
||||
res.send(new Buffer('wahoo'));
|
||||
res.send({ some: 'json' });
|
||||
res.send('<p>some html</p>');
|
||||
res.send(404, 'Sorry, cant find that');
|
||||
res.send(404);
|
||||
|
||||
# res.json()
|
||||
|
||||
Send JSON response.
|
||||
|
||||
## Examples
|
||||
|
||||
res.json(null);
|
||||
res.json({ user: 'tj' });
|
||||
res.json(500, 'oh noes!');
|
||||
res.json(404, 'I dont have that');
|
||||
|
||||
# res.sendfile()
|
||||
|
||||
Transfer the file at the given `path`.
|
||||
|
||||
Automatically sets the _Content-Type_ response header field.
|
||||
The callback `fn(err)` is invoked when the transfer is complete
|
||||
or when an error occurs. Be sure to check `res.sentHeader`
|
||||
if you wish to attempt responding, as the header and some data
|
||||
may have already been transferred.
|
||||
|
||||
## Options
|
||||
|
||||
- `maxAge` defaulting to 0
|
||||
- `root` root directory for relative filenames
|
||||
|
||||
## Examples
|
||||
|
||||
The following example illustrates how `res.sendfile()` may
|
||||
be used as an alternative for the `static()` middleware for
|
||||
dynamic situations. The code backing `res.sendfile()` is actually
|
||||
the same code, so HTTP cache support etc is identical.
|
||||
|
||||
app.get('/user/:uid/photos/:file', function(req, res){
|
||||
var uid = req.params.uid
|
||||
, file = req.params.file;
|
||||
|
||||
req.user.mayViewFilesFrom(uid, function(yes){
|
||||
if (yes) {
|
||||
res.sendfile('/uploads/' + uid + '/' + file);
|
||||
} else {
|
||||
res.send(403, 'Sorry! you cant see that.');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
# res.download()
|
||||
|
||||
Transfer the file at the given `path` as an attachment.
|
||||
|
||||
Optionally providing an alternate attachment `filename`,
|
||||
and optional callback `fn(err)`. The callback is invoked
|
||||
when the data transfer is complete, or when an error has
|
||||
ocurred. Be sure to check `res.headerSent` if you plan to respond.
|
||||
|
||||
# res.format()
|
||||
|
||||
Respond to the Acceptable formats using an `obj`
|
||||
of mime-type callbacks.
|
||||
|
||||
This method uses `req.accepted`, an array of
|
||||
acceptable types ordered by their quality values.
|
||||
When "Accept" is not present the _first_ callback
|
||||
is invoked, otherwise the first match is used. When
|
||||
no match is performed the server responds with
|
||||
406 "Not Acceptable".
|
||||
|
||||
Content-Type is set for you, however if you choose
|
||||
you may alter this within the callback using `res.type()`
|
||||
or `res.set('Content-Type', ...)`.
|
||||
|
||||
res.format({
|
||||
'text/plain': function(){
|
||||
res.send('hey');
|
||||
},
|
||||
|
||||
'text/html': function(){
|
||||
res.send('<p>hey</p>');
|
||||
},
|
||||
|
||||
'appliation/json': function(){
|
||||
res.send({ message: 'hey' });
|
||||
}
|
||||
});
|
||||
|
||||
In addition to canonicalized MIME types you may
|
||||
## also use extnames mapped to these types
|
||||
|
||||
res.format({
|
||||
text: function(){
|
||||
res.send('hey');
|
||||
},
|
||||
|
||||
html: function(){
|
||||
res.send('<p>hey</p>');
|
||||
},
|
||||
|
||||
json: function(){
|
||||
res.send({ message: 'hey' });
|
||||
}
|
||||
});
|
||||
|
||||
# res.attachment()
|
||||
|
||||
Set _Content-Disposition_ header to _attachment_ with optional `filename`.
|
||||
|
||||
# res.set()
|
||||
|
||||
Set header `field` to `val`, or pass
|
||||
an object of of header fields.
|
||||
|
||||
## Examples
|
||||
|
||||
res.set('Accept', 'application/json');
|
||||
res.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' });
|
||||
|
||||
# res.get()
|
||||
|
||||
Get value for header `field`.
|
||||
|
||||
# res.clearCookie()
|
||||
|
||||
Clear cookie `name`.
|
||||
|
||||
# res.signedCookie()
|
||||
|
||||
Set a signed cookie with the given `name` and `val`.
|
||||
See `res.cookie()` for details.
|
||||
|
||||
# res.cookie()
|
||||
|
||||
Set cookie `name` to `val`, with the given `options`.
|
||||
|
||||
## Options
|
||||
|
||||
- `maxAge` max-age in milliseconds, converted to `expires`
|
||||
- `path` defaults to "/"
|
||||
|
||||
## Examples
|
||||
|
||||
// "Remember Me" for 15 minutes
|
||||
res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });
|
||||
|
||||
// save as above
|
||||
res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })
|
||||
|
||||
# res.redirect()
|
||||
|
||||
Redirect to the given `url` with optional response `status`
|
||||
defaulting to 302.
|
||||
|
||||
The given `url` can also be the name of a mapped url, for
|
||||
example by default express supports "back" which redirects
|
||||
to the _Referrer_ or _Referer_ headers or "/".
|
||||
|
||||
## Examples
|
||||
|
||||
res.redirect('/foo/bar');
|
||||
res.redirect('http://example.com');
|
||||
res.redirect(301, 'http://example.com');
|
||||
res.redirect('../login'); // /blog/post/1 -> /blog/login
|
||||
|
||||
## Mounting
|
||||
|
||||
When an application is mounted, and `res.redirect()`
|
||||
is given a path that does _not_ lead with "/". For
|
||||
example suppose a "blog" app is mounted at "/blog",
|
||||
the following redirect would result in "/blog/login":
|
||||
|
||||
res.redirect('login');
|
||||
|
||||
While the leading slash would result in a redirect to "/login":
|
||||
|
||||
res.redirect('/login');
|
||||
|
||||
# res.render()
|
||||
|
||||
Render `view` with the given `options` and optional callback `fn`.
|
||||
When a callback function is given a response will _not_ be made
|
||||
automatically, otherwise a response of _200_ and _text/html_ is given.
|
||||
|
||||
## Options
|
||||
|
||||
- `status` Response status code (`res.statusCode`)
|
||||
- `charset` Set the charset (`res.charset`)
|
||||
|
||||
## Reserved locals
|
||||
|
||||
- `cache` boolean hinting to the engine it should cache
|
||||
- `filename` filename of the view being rendered
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../lib/express')
|
||||
, crypto = require('crypto');
|
||||
var express = require('../..')
|
||||
, hash = require('./pass').hash;
|
||||
|
||||
var app = module.exports = express();
|
||||
|
||||
app.use(express.bodyParser());
|
||||
app.use(express.cookieParser('shhhh, very secret'));
|
||||
app.use(express.session());
|
||||
// config
|
||||
|
||||
app.set('view engine', 'ejs');
|
||||
app.set('views', __dirname + '/views');
|
||||
|
||||
// middleware
|
||||
|
||||
app.use(express.urlencoded({ extended: false }));
|
||||
app.use(express.session({ secret: 'shhhh, very secret' }));
|
||||
|
||||
// Session-persisted message middleware
|
||||
|
||||
app.locals.use(function(req,res){
|
||||
app.use(function(req, res, next){
|
||||
var err = req.session.error
|
||||
, msg = req.session.success;
|
||||
delete req.session.error;
|
||||
@@ -25,28 +27,28 @@ app.locals.use(function(req,res){
|
||||
res.locals.message = '';
|
||||
if (err) res.locals.message = '<p class="msg error">' + err + '</p>';
|
||||
if (msg) res.locals.message = '<p class="msg success">' + msg + '</p>';
|
||||
})
|
||||
next();
|
||||
});
|
||||
|
||||
// dummy database
|
||||
|
||||
// Generate a salt for the user to prevent rainbow table attacks
|
||||
// for better security take a look at the bcrypt c++ addon:
|
||||
// https://github.com/ncb000gt/node.bcrypt.js
|
||||
var users = {
|
||||
tj: {
|
||||
name: 'tj'
|
||||
, salt: 'randomly-generated-salt'
|
||||
, pass: hash('foobar', 'randomly-generated-salt')
|
||||
}
|
||||
tj: { name: 'tj' }
|
||||
};
|
||||
|
||||
// Used to generate a hash of the plain-text password + salt
|
||||
function hash(msg, key) {
|
||||
return crypto
|
||||
.createHmac('sha256', key)
|
||||
.update(msg)
|
||||
.digest('hex');
|
||||
}
|
||||
// when you create a user, generate a salt
|
||||
// and hash the password ('foobar' is the pass here)
|
||||
|
||||
hash('foobar', function(err, salt, hash){
|
||||
if (err) throw err;
|
||||
// store the salt & hash in the "db"
|
||||
users.tj.salt = salt;
|
||||
users.tj.hash = hash;
|
||||
});
|
||||
|
||||
|
||||
// Authenticate using our plain-object database of doom!
|
||||
|
||||
function authenticate(name, pass, fn) {
|
||||
if (!module.parent) console.log('authenticating %s:%s', name, pass);
|
||||
var user = users[name];
|
||||
@@ -55,9 +57,11 @@ function authenticate(name, pass, fn) {
|
||||
// apply the same algorithm to the POSTed password, applying
|
||||
// the hash against the pass / salt, if there is a match we
|
||||
// found the user
|
||||
if (user.pass == hash(pass, user.salt)) return fn(null, user);
|
||||
// Otherwise password is invalid
|
||||
fn(new Error('invalid password'));
|
||||
hash(pass, user.salt, function(err, hash){
|
||||
if (err) return fn(err);
|
||||
if (hash == user.hash) return fn(null, user);
|
||||
fn(new Error('invalid password'));
|
||||
})
|
||||
}
|
||||
|
||||
function restrict(req, res, next) {
|
||||
@@ -74,7 +78,7 @@ app.get('/', function(req, res){
|
||||
});
|
||||
|
||||
app.get('/restricted', restrict, function(req, res){
|
||||
res.send('Wahoo! restricted area');
|
||||
res.send('Wahoo! restricted area, click to <a href="/logout">logout</a>');
|
||||
});
|
||||
|
||||
app.get('/logout', function(req, res){
|
||||
@@ -86,11 +90,6 @@ app.get('/logout', function(req, res){
|
||||
});
|
||||
|
||||
app.get('/login', function(req, res){
|
||||
if (req.session.user) {
|
||||
req.session.success = 'Authenticated as ' + req.session.user.name
|
||||
+ ' click to <a href="/logout">logout</a>. '
|
||||
+ ' You may now access <a href="/restricted">/restricted</a>.';
|
||||
}
|
||||
res.render('login');
|
||||
});
|
||||
|
||||
@@ -104,6 +103,9 @@ app.post('/login', function(req, res){
|
||||
// in the session store to be retrieved,
|
||||
// or in this case the entire user object
|
||||
req.session.user = user;
|
||||
req.session.success = 'Authenticated as ' + user.name
|
||||
+ ' click to <a href="/logout">logout</a>. '
|
||||
+ ' You may now access <a href="/restricted">/restricted</a>.';
|
||||
res.redirect('back');
|
||||
});
|
||||
} else {
|
||||
@@ -115,7 +117,8 @@ app.post('/login', function(req, res){
|
||||
});
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
}
|
||||
|
||||
48
examples/auth/pass.js
Normal file
48
examples/auth/pass.js
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
// check out https://github.com/visionmedia/node-pwd
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var crypto = require('crypto');
|
||||
|
||||
/**
|
||||
* Bytesize.
|
||||
*/
|
||||
|
||||
var len = 128;
|
||||
|
||||
/**
|
||||
* Iterations. ~300ms
|
||||
*/
|
||||
|
||||
var iterations = 12000;
|
||||
|
||||
/**
|
||||
* Hashes a password with optional `salt`, otherwise
|
||||
* generate a salt for `pass` and invoke `fn(err, salt, hash)`.
|
||||
*
|
||||
* @param {String} password to hash
|
||||
* @param {String} optional salt
|
||||
* @param {Function} callback
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.hash = function (pwd, salt, fn) {
|
||||
if (3 == arguments.length) {
|
||||
crypto.pbkdf2(pwd, salt, iterations, len, function(err, hash){
|
||||
fn(err, hash.toString('base64'));
|
||||
});
|
||||
} else {
|
||||
fn = salt;
|
||||
crypto.randomBytes(len, function(err, salt){
|
||||
if (err) return fn(err);
|
||||
salt = salt.toString('base64');
|
||||
crypto.pbkdf2(pwd, salt, iterations, len, function(err, hash){
|
||||
if (err) return fn(err);
|
||||
fn(null, salt, hash.toString('base64'));
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
2
examples/auth/views/foot.ejs
Normal file
2
examples/auth/views/foot.ejs
Normal file
@@ -0,0 +1,2 @@
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Authentication Example</title>
|
||||
<title><%= title %></title>
|
||||
<style>
|
||||
body {
|
||||
padding: 50px;
|
||||
@@ -16,6 +16,3 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<%- body %>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,3 +1,7 @@
|
||||
|
||||
<% var title = 'Authentication Example' %>
|
||||
<% include head %>
|
||||
|
||||
<h1>Login</h1>
|
||||
<%- message %>
|
||||
Try accessing <a href="/restricted">/restricted</a>, then authenticate with "tj" and "foobar".
|
||||
@@ -13,4 +17,6 @@ Try accessing <a href="/restricted">/restricted</a>, then authenticate with "tj"
|
||||
<p>
|
||||
<input type="submit" value="Login">
|
||||
</p>
|
||||
</form>
|
||||
</form>
|
||||
|
||||
<% include foot %>
|
||||
|
||||
@@ -20,5 +20,8 @@ app.get('/', function(req, res){
|
||||
res.render('pets', { pets: pets });
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express listening on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
style
|
||||
style.
|
||||
body {
|
||||
padding: 50px;
|
||||
font: 16px "Helvetica Neue", Helvetica;
|
||||
|
||||
8
examples/content-negotiation/db.js
Normal file
8
examples/content-negotiation/db.js
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
var users = [];
|
||||
|
||||
users.push({ name: 'Tobi' });
|
||||
users.push({ name: 'Loki' });
|
||||
users.push({ name: 'Jane' });
|
||||
|
||||
module.exports = users;
|
||||
@@ -1,13 +1,9 @@
|
||||
|
||||
var express = require('../../')
|
||||
, app = module.exports = express();
|
||||
|
||||
var users = [];
|
||||
|
||||
users.push({ name: 'Tobi' });
|
||||
users.push({ name: 'Loki' });
|
||||
users.push({ name: 'Jane' });
|
||||
, app = module.exports = express()
|
||||
, users = require('./db');
|
||||
|
||||
// so either you can deal with different types of formatting
|
||||
// for expected response in index.js
|
||||
app.get('/', function(req, res){
|
||||
res.format({
|
||||
html: function(){
|
||||
@@ -28,7 +24,21 @@ app.get('/', function(req, res){
|
||||
})
|
||||
});
|
||||
|
||||
// or you could write a tiny middleware like
|
||||
// this to add a layer of abstraction
|
||||
// and make things a bit more declarative:
|
||||
|
||||
function format(path) {
|
||||
var obj = require(path);
|
||||
return function(req, res){
|
||||
res.format(obj);
|
||||
}
|
||||
}
|
||||
|
||||
app.get('/users', format('./users'));
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('listening on port 3000');
|
||||
}
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
18
examples/content-negotiation/users.js
Normal file
18
examples/content-negotiation/users.js
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
var users = require('./db');
|
||||
|
||||
exports.html = function(req, res){
|
||||
res.send('<ul>' + users.map(function(user){
|
||||
return '<li>' + user.name + '</li>';
|
||||
}).join('') + '</ul>');
|
||||
};
|
||||
|
||||
exports.text = function(req, res){
|
||||
res.send(users.map(function(user){
|
||||
return ' - ' + user.name + '\n';
|
||||
}).join(''));
|
||||
};
|
||||
|
||||
exports.json = function(req, res){
|
||||
res.json(users);
|
||||
};
|
||||
@@ -26,7 +26,8 @@ function count(req, res) {
|
||||
res.send('viewed ' + n + ' times\n');
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express server listening on port 3000');
|
||||
}
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -15,8 +15,7 @@ var express = require('../../')
|
||||
app.use(express.favicon());
|
||||
|
||||
// custom log format
|
||||
if ('test' != process.env.NODE_ENV)
|
||||
app.use(express.logger(':method :url'));
|
||||
if ('test' != process.env.NODE_ENV) app.use(express.logger(':method :url'));
|
||||
|
||||
// parses request cookies, populating
|
||||
// req.cookies and req.signedCookies
|
||||
@@ -48,7 +47,8 @@ app.post('/', function(req, res){
|
||||
res.redirect('back');
|
||||
});
|
||||
|
||||
if (!module.parent){
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
}
|
||||
|
||||
46
examples/cors/index.js
Normal file
46
examples/cors/index.js
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../..')
|
||||
, app = express()
|
||||
, api = express();
|
||||
|
||||
// app middleware
|
||||
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
|
||||
// api middleware
|
||||
|
||||
api.use(express.logger('dev'));
|
||||
api.use(express.bodyParser());
|
||||
|
||||
/**
|
||||
* CORS support.
|
||||
*/
|
||||
|
||||
api.all('*', function(req, res, next){
|
||||
if (!req.get('Origin')) return next();
|
||||
// use "*" here to accept any origin
|
||||
res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
|
||||
res.set('Access-Control-Allow-Methods', 'GET, POST');
|
||||
res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
|
||||
// res.set('Access-Control-Allow-Max-Age', 3600);
|
||||
if ('OPTIONS' == req.method) return res.send(200);
|
||||
next();
|
||||
});
|
||||
|
||||
/**
|
||||
* POST a user.
|
||||
*/
|
||||
|
||||
api.post('/user', function(req, res){
|
||||
console.log(req.body);
|
||||
res.send(201);
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
api.listen(3001);
|
||||
|
||||
console.log('app listening on 3000');
|
||||
console.log('api listening on 3001');
|
||||
12
examples/cors/public/index.html
Normal file
12
examples/cors/public/index.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
var req = new XMLHttpRequest;
|
||||
req.open('POST', 'http://localhost:3001/user', false);
|
||||
req.setRequestHeader('Content-Type', 'application/json');
|
||||
req.send('{"name":"tobi","species":"ferret"}');
|
||||
console.log(req.responseText);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -38,7 +38,8 @@ app.use(function(err, req, res, next){
|
||||
}
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,16 +31,21 @@ app.set('view engine', 'html');
|
||||
|
||||
// Dummy users
|
||||
var users = [
|
||||
{ name: 'tobi', email: 'tobi@learnboost.com' }
|
||||
, { name: 'loki', email: 'loki@learnboost.com' }
|
||||
, { name: 'jane', email: 'jane@learnboost.com' }
|
||||
{ name: 'tobi', email: 'tobi@learnboost.com' },
|
||||
{ name: 'loki', email: 'loki@learnboost.com' },
|
||||
{ name: 'jane', email: 'jane@learnboost.com' }
|
||||
];
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.render('users', { users: users });
|
||||
res.render('users', {
|
||||
users: users,
|
||||
title: "EJS example",
|
||||
header: "Some users"
|
||||
});
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express app started on port 3000');
|
||||
}
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
2
examples/ejs/views/footer.html
Normal file
2
examples/ejs/views/footer.html
Normal file
@@ -0,0 +1,2 @@
|
||||
</body>
|
||||
</html>
|
||||
13
examples/ejs/views/header.html
Normal file
13
examples/ejs/views/header.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title> <%= title %> </title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
padding: 50px;
|
||||
font: 13px Helvetica, Arial, sans-serif;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -1,6 +1,10 @@
|
||||
<% include header.html %>
|
||||
|
||||
<h1>Users</h1>
|
||||
<ul id="users">
|
||||
<% users.forEach(function(user){ %>
|
||||
<li><%= user.name %> <%= user.email %></li>
|
||||
<li><%= user.name %> <<%= user.email %>></li>
|
||||
<% }) %>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<% include footer.html %>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
@@ -7,9 +6,19 @@ var express = require('../../')
|
||||
, app = module.exports = express()
|
||||
, silent = 'test' == process.env.NODE_ENV;
|
||||
|
||||
// general config
|
||||
app.set('views', __dirname + '/views');
|
||||
app.set('view engine', 'jade');
|
||||
|
||||
// our custom "verbose errors" setting
|
||||
// which we can use in the templates
|
||||
// via settings['verbose errors']
|
||||
app.enable('verbose errors');
|
||||
|
||||
// disable them in production
|
||||
// use $ NODE_ENV=production node examples/error-pages
|
||||
if ('production' == app.settings.env) app.disable('verbose errors');
|
||||
|
||||
app.use(express.favicon());
|
||||
|
||||
silent || app.use(express.logger('dev'));
|
||||
@@ -32,9 +41,10 @@ app.use(app.router);
|
||||
// $ curl http://localhost:3000/notfound -H "Accept: text/plain"
|
||||
|
||||
app.use(function(req, res, next){
|
||||
res.status(404);
|
||||
|
||||
// respond with html page
|
||||
if (req.accepts('html')) {
|
||||
res.status(404);
|
||||
res.render('404', { url: req.url });
|
||||
return;
|
||||
}
|
||||
@@ -76,20 +86,26 @@ app.get('/', function(req, res){
|
||||
});
|
||||
|
||||
app.get('/404', function(req, res, next){
|
||||
// trigger a 404 since no other middleware
|
||||
// will match /404 after this one, and we're not
|
||||
// responding here
|
||||
next();
|
||||
});
|
||||
|
||||
app.get('/403', function(req, res, next){
|
||||
// trigger a 403 error
|
||||
var err = new Error('not allowed!');
|
||||
err.status = 403;
|
||||
next(err);
|
||||
});
|
||||
|
||||
app.get('/500', function(req, res, next){
|
||||
// trigger a generic (500) error
|
||||
next(new Error('keyboard cat!'));
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
silent || console.log('Express started on port 3000');
|
||||
}
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -7,4 +7,7 @@ extends error
|
||||
|
||||
block content
|
||||
h1 Error: #{error.message}
|
||||
pre= error.stack
|
||||
if settings['verbose errors']
|
||||
pre= error.stack
|
||||
else
|
||||
p An error ocurred!
|
||||
@@ -8,8 +8,8 @@ block content
|
||||
| visit
|
||||
a(href="/500") 500
|
||||
li
|
||||
| visit
|
||||
| visit
|
||||
a(href="/404") 404
|
||||
li
|
||||
| visit
|
||||
| visit
|
||||
a(href='/403') 403
|
||||
@@ -42,7 +42,8 @@ app.get('/next', function(req, res, next){
|
||||
});
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,14 +45,6 @@ app.use(function(req, res, next){
|
||||
next();
|
||||
});
|
||||
|
||||
// if you wanted to _always_ expose
|
||||
// the user you might do something like this:
|
||||
/*
|
||||
app.locals.use(function(req, res){
|
||||
if (req.user) res.locals.expose.user = req.user;
|
||||
})
|
||||
*/
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.redirect('/user');
|
||||
});
|
||||
@@ -64,5 +56,8 @@ app.get('/user', function(req, res){
|
||||
res.render('page');
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('app listening on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
html
|
||||
head
|
||||
title Express
|
||||
script
|
||||
script.
|
||||
// call this whatever you like,
|
||||
// or dump them into individual
|
||||
// props like "var user ="
|
||||
@@ -10,5 +10,5 @@ html
|
||||
h1 Expose client data
|
||||
p The following was exposed to the client:
|
||||
pre
|
||||
script
|
||||
script.
|
||||
document.write(JSON.stringify(data, null, 2))
|
||||
@@ -7,5 +7,8 @@ app.get('/', function(req, res){
|
||||
res.send('Hello World');
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -9,10 +9,9 @@ var express = require('../../lib/express');
|
||||
|
||||
var pub = __dirname + '/public';
|
||||
|
||||
// Auto-compile sass to css with "compiler"
|
||||
// and then serve with connect's staticProvider
|
||||
// setup middleware
|
||||
|
||||
var app = express.createServer();
|
||||
var app = express();
|
||||
app.use(app.router);
|
||||
app.use(express.static(pub));
|
||||
app.use(express.errorHandler());
|
||||
@@ -42,5 +41,8 @@ app.get('/', function(req, res){
|
||||
res.render('users', { users: users });
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express app started on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
body {
|
||||
padding: 50px 80px;
|
||||
font: 14px "Helvetica Nueue", "Lucida Grande", Arial, sans-serif;}
|
||||
font: 14px "Helvetica Nueue", "Lucida Grande", Arial, sans-serif;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
!!! 5
|
||||
doctype html
|
||||
html
|
||||
include header
|
||||
body
|
||||
block content
|
||||
block content
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../')
|
||||
var express = require('../..')
|
||||
, fs = require('fs')
|
||||
, md = require('github-flavored-markdown').parse;
|
||||
, md = require('marked').parse;
|
||||
|
||||
var app = module.exports = express();
|
||||
|
||||
@@ -39,7 +39,8 @@ app.get('/fail', function(req, res){
|
||||
res.render('missing', { title: 'Markdown Example' });
|
||||
})
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../')
|
||||
var express = require('../..')
|
||||
, format = require('util').format;
|
||||
|
||||
var app = module.exports = express()
|
||||
@@ -30,7 +30,8 @@ app.post('/', function(req, res, next){
|
||||
, req.body.title));
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ exports.edit = function(req, res, next){
|
||||
|
||||
exports.update = function(req, res, next){
|
||||
var body = req.body;
|
||||
req.pet.name = body.user.name;
|
||||
req.pet.name = body.pet.name;
|
||||
res.message('Information updated!');
|
||||
res.redirect('/pet/' + req.pet.id);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
var express = require('../..');
|
||||
|
||||
var app = module.exports = express();
|
||||
@@ -25,8 +24,23 @@ app.response.message = function(msg){
|
||||
return this;
|
||||
};
|
||||
|
||||
// log
|
||||
if (!module.parent) app.use(express.logger('dev'));
|
||||
|
||||
// serve static files
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
|
||||
// session support
|
||||
app.use(express.session({ secret: 'some secret here' }));
|
||||
|
||||
// parse request bodies (req.body)
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
|
||||
// support _method (PUT in forms etc)
|
||||
app.use(express.methodOverride());
|
||||
|
||||
// expose the "messages" local variable when views are rendered
|
||||
app.locals.use(function(req, res){
|
||||
app.use(function(req, res, next){
|
||||
var msgs = req.session.messages || [];
|
||||
|
||||
// expose "messages" local variable
|
||||
@@ -42,27 +56,12 @@ app.locals.use(function(req, res){
|
||||
});
|
||||
*/
|
||||
|
||||
next();
|
||||
// empty or "flush" the messages so they
|
||||
// don't build up
|
||||
req.session.messages = [];
|
||||
});
|
||||
|
||||
// log
|
||||
if (!module.parent) app.use(express.logger('dev'));
|
||||
|
||||
// serve static files
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
|
||||
// session support
|
||||
app.use(express.cookieParser('some secret here'));
|
||||
app.use(express.session());
|
||||
|
||||
// parse request bodies (req.body)
|
||||
app.use(express.bodyParser());
|
||||
|
||||
// support _method (PUT in forms etc)
|
||||
app.use(express.methodOverride());
|
||||
|
||||
// load controllers
|
||||
require('./lib/boot')(app, { verbose: !module.parent });
|
||||
|
||||
@@ -86,7 +85,8 @@ app.use(function(req, res, next){
|
||||
res.status(404).render('404', { url: req.originalUrl });
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('\n listening on port 3000\n');
|
||||
}
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ module.exports = function(parent, options){
|
||||
case 'show':
|
||||
method = 'get';
|
||||
path = '/' + name + '/:' + name + '_id';
|
||||
app[method](path, obj[key]);
|
||||
break;
|
||||
case 'list':
|
||||
method = 'get';
|
||||
|
||||
57
examples/online/index.js
Normal file
57
examples/online/index.js
Normal file
@@ -0,0 +1,57 @@
|
||||
|
||||
// first:
|
||||
// $ npm install redis online
|
||||
// $ redis-server
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../..')
|
||||
, online = require('online')
|
||||
, redis = require('redis')
|
||||
, db = redis.createClient();
|
||||
|
||||
// online
|
||||
|
||||
online = online(db);
|
||||
|
||||
// app
|
||||
|
||||
var app = express();
|
||||
|
||||
// activity tracking, in this case using
|
||||
// the UA string, you would use req.user.id etc
|
||||
|
||||
app.use(function(req, res, next){
|
||||
// fire-and-forget
|
||||
online.add(req.headers['user-agent']);
|
||||
next();
|
||||
});
|
||||
|
||||
/**
|
||||
* List helper.
|
||||
*/
|
||||
|
||||
function list(ids) {
|
||||
return '<ul>' + ids.map(function(id){
|
||||
return '<li>' + id + '</li>';
|
||||
}).join('') + '</ul>';
|
||||
}
|
||||
|
||||
/**
|
||||
* GET users online.
|
||||
*/
|
||||
|
||||
app.get('/', function(req, res, next){
|
||||
online.last(5, function(err, ids){
|
||||
if (err) return next(err);
|
||||
res.send('<p>Users online: ' + ids.length + '</p>' + list(ids));
|
||||
});
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
@@ -19,8 +19,8 @@ var users = [
|
||||
// Convert :to and :from to integers
|
||||
|
||||
app.param(['to', 'from'], function(req, res, next, num, name){
|
||||
req.params[name] = num = parseInt(num, 10);
|
||||
if( isNaN(num) ){
|
||||
req.params[name] = parseInt(num, 10);
|
||||
if( isNaN(req.params[name]) ){
|
||||
next(new Error('failed to parseInt '+num));
|
||||
} else {
|
||||
next();
|
||||
@@ -64,7 +64,8 @@ app.get('/users/:from-:to', function(req, res, next){
|
||||
res.send('users ' + names.slice(from, to).join(', '));
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../lib/express');
|
||||
|
||||
var app = express.createServer();
|
||||
|
||||
// Optional since express defaults to CWD/views
|
||||
|
||||
app.set('views', __dirname + '/views');
|
||||
|
||||
// Set our default template engine to "jade"
|
||||
// which prevents the need for extensions
|
||||
// (although you can still mix and match)
|
||||
app.set('view engine', 'jade');
|
||||
|
||||
// Dummy record
|
||||
var ninja = {
|
||||
name: 'leonardo',
|
||||
summary: { email: 'hunter.loftis+github@gmail.com', master: 'splinter', description: 'peaceful leader' },
|
||||
weapons: ['katana', 'fists', 'shell'],
|
||||
victims: ['shredder', 'brain', 'beebop', 'rocksteady']
|
||||
};
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.render('ninja', { ninja: ninja });
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express app started on port 3000');
|
||||
@@ -1,5 +0,0 @@
|
||||
!!!
|
||||
html
|
||||
head
|
||||
title Partials Example
|
||||
body!= body
|
||||
@@ -1 +0,0 @@
|
||||
li= value
|
||||
@@ -1 +0,0 @@
|
||||
li.weapon= weapon
|
||||
@@ -1,22 +0,0 @@
|
||||
h1= ninja.name
|
||||
|
||||
// file, partial name, and partial object all match ('summary')
|
||||
// the partial filename prefix '_' is completely optional.
|
||||
|
||||
// In this case we need to specify ninja.summary as the object
|
||||
// option, since it is a "plain" object Express cannot otherwise
|
||||
// tell if it is intended to be locals, or THE summary object
|
||||
#summary!= partial('summary', { object: ninja.summary })
|
||||
|
||||
// file, partial name = '_weapon', resolves to 'weapon' object within partial
|
||||
#weapons
|
||||
h2 Weapons
|
||||
// the weapon partial is rendered once per item in
|
||||
// the weapons array or "collection"
|
||||
ul!= partial('weapon', ninja.weapons)
|
||||
|
||||
// partial name 'victim' resolves to 'victim.jade'
|
||||
// or 'victim/index.jade', providing the "victim" local
|
||||
#victims
|
||||
h2 Victims
|
||||
ul!= partial('victim', ninja.victims)
|
||||
@@ -1,4 +0,0 @@
|
||||
h2 Summary
|
||||
p= summary.email
|
||||
p= summary.description
|
||||
p taught by master #{summary.master}
|
||||
@@ -1,5 +0,0 @@
|
||||
// this is insane overkill, I do not recommend
|
||||
// doing tiny partials like this as it gets expensive
|
||||
// with collections, however this illustrates the new
|
||||
// partial lookup mechanism
|
||||
!= partial('../../li', { object: victim, as: 'value' })
|
||||
@@ -18,7 +18,10 @@ app.resource = function(path, obj) {
|
||||
obj.range(req, res, a, b, format);
|
||||
});
|
||||
this.get(path + '/:id', obj.show);
|
||||
this.del(path + '/:id', obj.destroy);
|
||||
this.delete(path + '/:id', function(req, res){
|
||||
var id = parseInt(req.params.id, 10);
|
||||
obj.destroy(req, res, id);
|
||||
});
|
||||
};
|
||||
|
||||
// Fake records
|
||||
@@ -41,8 +44,7 @@ var User = {
|
||||
show: function(req, res){
|
||||
res.send(users[req.params.id] || { error: 'Cannot find user' });
|
||||
},
|
||||
destroy: function(req, res){
|
||||
var id = req.params.id;
|
||||
destroy: function(req, res, id){
|
||||
var destroyed = id in users;
|
||||
delete users[id];
|
||||
res.send(destroyed ? 'destroyed' : 'Cannot find user');
|
||||
@@ -85,7 +87,8 @@ app.get('/', function(req, res){
|
||||
].join('\n'));
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var vm = require('vm')
|
||||
, fs = require('fs');
|
||||
|
||||
module.exports = function(app, db){
|
||||
var dir = __dirname + '/routes';
|
||||
// grab a list of our route files
|
||||
fs.readdirSync(dir).forEach(function(file){
|
||||
var str = fs.readFileSync(dir + '/' + file, 'utf8');
|
||||
// inject some pseudo globals by evaluating
|
||||
// the file with vm.runInNewContext()
|
||||
// instead of loading it with require(). require's
|
||||
// internals use similar, so dont be afraid of "boot time".
|
||||
var context = { app: app, db: db };
|
||||
// we have to merge the globals for console, process etc
|
||||
for (var key in global) context[key] = global[key];
|
||||
// note that this is essentially no different than ... just using
|
||||
// global variables, though it's only YOUR code that could influence
|
||||
// them, which is a bonus.
|
||||
vm.runInNewContext(str, context, file);
|
||||
});
|
||||
};
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../lib/express')
|
||||
, app = express()
|
||||
, db = { users: [] };
|
||||
|
||||
app.set('views', __dirname + '/views');
|
||||
app.set('view engine', 'jade');
|
||||
app.use(express.bodyParser());
|
||||
|
||||
// pretend db is a database, could be
|
||||
// whatever you like
|
||||
require('./boot')(app, db);
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express app started on port 3000');
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.render('index');
|
||||
});
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
app.get('/users', function(req, res){
|
||||
res.render('user/list', { users: db.users });
|
||||
});
|
||||
|
||||
app.get('/user/add', function(req, res){
|
||||
res.render('user/add');
|
||||
});
|
||||
|
||||
app.post('/user', function(req, res){
|
||||
var user = req.body.user;
|
||||
db.users.push(user);
|
||||
res.redirect('/users');
|
||||
});
|
||||
|
||||
app.get('/user/:id', function(req, res){
|
||||
res.render('user');
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
extends layout
|
||||
|
||||
block content
|
||||
h2 Route sharing example
|
||||
ul
|
||||
li: a(href='/user/add') Add user
|
||||
li: a(href='/users') User list
|
||||
@@ -1,11 +0,0 @@
|
||||
doctype html
|
||||
html
|
||||
head
|
||||
title Route loading example
|
||||
style
|
||||
body {
|
||||
padding: 50px;
|
||||
font: 14px/1.5 solid helvetica, arial, sans-serif;
|
||||
}
|
||||
body
|
||||
block content
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
extends ../layout
|
||||
|
||||
block content
|
||||
h2 Add a user
|
||||
form(action='/user', method='post')
|
||||
p: input(type='text', name='user[name]', placeholder='Username')
|
||||
p: input(type='text', name='user[email]', placeholder='Email')
|
||||
p: input(type='submit', value='Add')
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
extends ../layout
|
||||
|
||||
block content
|
||||
h1= user.name
|
||||
table
|
||||
tbody
|
||||
tr
|
||||
td Email
|
||||
td= user.email
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
extends ../layout
|
||||
|
||||
block content
|
||||
h1 Users
|
||||
if users.length
|
||||
for user in users
|
||||
include index
|
||||
else
|
||||
p No users, head over to <a href='/user/add'>/user/add</a> to create one.
|
||||
67
examples/route-map/index.js
Normal file
67
examples/route-map/index.js
Normal file
@@ -0,0 +1,67 @@
|
||||
|
||||
var express = require('../../lib/express')
|
||||
, verbose = process.env.NODE_ENV != 'test'
|
||||
, app = module.exports = express();
|
||||
|
||||
app.map = function(a, route){
|
||||
route = route || '';
|
||||
for (var key in a) {
|
||||
switch (typeof a[key]) {
|
||||
// { '/path': { ... }}
|
||||
case 'object':
|
||||
app.map(a[key], route + key);
|
||||
break;
|
||||
// get: function(){ ... }
|
||||
case 'function':
|
||||
if (verbose) console.log('%s %s', key, route);
|
||||
app[key](route, a[key]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var users = {
|
||||
list: function(req, res){
|
||||
res.send('user list');
|
||||
},
|
||||
|
||||
get: function(req, res){
|
||||
res.send('user ' + req.params.uid);
|
||||
},
|
||||
|
||||
delete: function(req, res){
|
||||
res.send('delete users');
|
||||
}
|
||||
};
|
||||
|
||||
var pets = {
|
||||
list: function(req, res){
|
||||
res.send('user ' + req.params.uid + '\'s pets');
|
||||
},
|
||||
|
||||
delete: function(req, res){
|
||||
res.send('delete ' + req.params.uid + '\'s pet ' + req.params.pid);
|
||||
}
|
||||
};
|
||||
|
||||
app.map({
|
||||
'/users': {
|
||||
get: users.list,
|
||||
delete: users.delete,
|
||||
'/:uid': {
|
||||
get: users.get,
|
||||
'/pets': {
|
||||
get: pets.list,
|
||||
'/:pid': {
|
||||
delete: pets.delete
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
var express = require('../../lib/express');
|
||||
|
||||
var app = express.createServer();
|
||||
var app = express();
|
||||
|
||||
// Example requests:
|
||||
// curl http://localhost:3000/user/0
|
||||
@@ -77,9 +77,12 @@ app.get('/user/:id/edit', loadUser, andRestrictToSelf, function(req, res){
|
||||
res.send('Editing user ' + req.user.name);
|
||||
});
|
||||
|
||||
app.del('/user/:id', loadUser, andRestrictTo('admin'), function(req, res){
|
||||
app.delete('/user/:id', loadUser, andRestrictTo('admin'), function(req, res){
|
||||
res.send('Deleted user ' + req.user.name);
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express app started on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
@@ -3,17 +3,19 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../lib/express')
|
||||
, app = express.createServer()
|
||||
var express = require('../..')
|
||||
, app = express()
|
||||
, site = require('./site')
|
||||
, post = require('./post')
|
||||
, user = require('./user');
|
||||
|
||||
// Config
|
||||
|
||||
app.set('view engine', 'ejs');
|
||||
app.set('view engine', 'jade');
|
||||
app.set('views', __dirname + '/views');
|
||||
app.use(express.logger('dev'));
|
||||
app.use(express.cookieParser());
|
||||
app.use(express.bodyParser());
|
||||
app.use(express.methodOverride());
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
|
||||
@@ -34,5 +36,8 @@ app.put('/user/:id/edit', user.update);
|
||||
|
||||
app.get('/posts', post.list);
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express app started on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
// Fake posts database
|
||||
|
||||
var posts = [
|
||||
{ title: 'Foo', body: 'some foo bar' }
|
||||
, { title: 'Foo bar', body: 'more foo bar' }
|
||||
, { title: 'Foo bar baz', body: 'more foo bar baz' }
|
||||
{ title: 'Foo', body: 'some foo bar' },
|
||||
{ title: 'Foo bar', body: 'more foo bar' },
|
||||
{ title: 'Foo bar baz', body: 'more foo bar baz' }
|
||||
];
|
||||
|
||||
exports.list = function(req, res){
|
||||
|
||||
@@ -11,10 +11,10 @@ a.edit {
|
||||
opacity: .3;
|
||||
}
|
||||
a.edit::before {
|
||||
content: '[ ';
|
||||
content: ' [';
|
||||
}
|
||||
a.edit::after {
|
||||
content: ' ]';
|
||||
content: ']';
|
||||
}
|
||||
dt {
|
||||
font-weight: bold;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Fake user database
|
||||
|
||||
var users = [
|
||||
{ name: 'TJ', email: 'tj@vision-media.ca' }
|
||||
, { name: 'Tobi', email: 'tobi@vision-media.ca' }
|
||||
{ name: 'TJ', email: 'tj@vision-media.ca' },
|
||||
{ name: 'Tobi', email: 'tobi@vision-media.ca' }
|
||||
];
|
||||
|
||||
exports.list = function(req, res){
|
||||
@@ -22,15 +22,15 @@ exports.load = function(req, res, next){
|
||||
|
||||
exports.view = function(req, res){
|
||||
res.render('users/view', {
|
||||
title: 'Viewing user ' + req.user.name
|
||||
, user: req.user
|
||||
title: 'Viewing user ' + req.user.name,
|
||||
user: req.user
|
||||
});
|
||||
};
|
||||
|
||||
exports.edit = function(req, res){
|
||||
res.render('users/edit', {
|
||||
title: 'Editing user ' + req.user.name
|
||||
, user: req.user
|
||||
title: 'Editing user ' + req.user.name,
|
||||
user: req.user
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
<ul>
|
||||
<li>Visit the <a href="/users">users</a> page</li>
|
||||
<li>Visit the <a href="/posts">posts</a> page</li>
|
||||
</ul>
|
||||
6
examples/route-separation/views/index.jade
Normal file
6
examples/route-separation/views/index.jade
Normal file
@@ -0,0 +1,6 @@
|
||||
extends layout
|
||||
|
||||
block content
|
||||
ul
|
||||
li Visit the <a href="/users">users</a> page
|
||||
li Visit the <a href="/posts">posts</a> page
|
||||
@@ -1,9 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title><%= title %></title>
|
||||
<link href="/style.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<%- body %>
|
||||
</body>
|
||||
</html>
|
||||
6
examples/route-separation/views/layout.jade
Normal file
6
examples/route-separation/views/layout.jade
Normal file
@@ -0,0 +1,6 @@
|
||||
html
|
||||
head
|
||||
title= title
|
||||
link(href="/style.css", rel="stylesheet")
|
||||
body
|
||||
block content
|
||||
@@ -1,7 +0,0 @@
|
||||
<h1>Posts</h1>
|
||||
<dl id="posts">
|
||||
<% posts.forEach(function(post){ %>
|
||||
<dt><%= post.title %></dt>
|
||||
<dd><%= post.body %></dd>
|
||||
<% }) %>
|
||||
</dl>
|
||||
8
examples/route-separation/views/posts/index.jade
Normal file
8
examples/route-separation/views/posts/index.jade
Normal file
@@ -0,0 +1,8 @@
|
||||
extends ../layout
|
||||
|
||||
block content
|
||||
h1 Posts
|
||||
dl#posts
|
||||
for post in posts
|
||||
dt= post.title
|
||||
dd= post.body
|
||||
@@ -1,9 +0,0 @@
|
||||
<h1>Editing <%= user.name %></h1>
|
||||
<div id="user">
|
||||
<form method="post">
|
||||
<input type="hidden" value="put" name="_method" />
|
||||
<p>Name: <input type="text" value="<%= user.name %>" name="user[name]"/></p>
|
||||
<p>Email: <input type="text" value="<%= user.email %>" name="user[email]"/></p>
|
||||
<p><input type="submit" value="Save" /></p>
|
||||
</form>
|
||||
</div>
|
||||
13
examples/route-separation/views/users/edit.jade
Normal file
13
examples/route-separation/views/users/edit.jade
Normal file
@@ -0,0 +1,13 @@
|
||||
extends ../layout
|
||||
|
||||
block content
|
||||
h1 Editing #{user.name}
|
||||
#user
|
||||
form(method="post")
|
||||
input(type="hidden", value="put", name="_method")
|
||||
p Name:
|
||||
input(type="text", value= user.name, name="user[name]")
|
||||
p Email:
|
||||
input(type="text", value= user.email, name="user[email]")
|
||||
p
|
||||
input(type="submit", value="Save")
|
||||
@@ -1,9 +0,0 @@
|
||||
<h1>Users</h1>
|
||||
<ul id="users">
|
||||
<% users.forEach(function(user, id){ %>
|
||||
<li>
|
||||
<a href="/user/<%= id %>"><%= user.name %></a>
|
||||
<a class="edit" href="/user/<%= id %>/edit">edit</a>
|
||||
</li>
|
||||
<% }) %>
|
||||
</ul>
|
||||
9
examples/route-separation/views/users/index.jade
Normal file
9
examples/route-separation/views/users/index.jade
Normal file
@@ -0,0 +1,9 @@
|
||||
extends ../layout
|
||||
|
||||
block content
|
||||
h1 Users
|
||||
#users
|
||||
for user, i in users
|
||||
li
|
||||
a(href="/user/#{i}")= user.name
|
||||
a.edit(href="/user/#{i}/edit") edit
|
||||
@@ -1,4 +0,0 @@
|
||||
<h1><%= user.name %></h1>
|
||||
<div id="user">
|
||||
<p>Email: <%= user.email %></p>
|
||||
</div>
|
||||
6
examples/route-separation/views/users/view.jade
Normal file
6
examples/route-separation/views/users/view.jade
Normal file
@@ -0,0 +1,6 @@
|
||||
extends ../layout
|
||||
|
||||
block content
|
||||
h1= user.name
|
||||
#user
|
||||
p Email: #{user.email}
|
||||
@@ -1,44 +0,0 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../')
|
||||
, path = require('path')
|
||||
, exec = require('child_process').exec
|
||||
, fs = require('fs');
|
||||
|
||||
/**
|
||||
* Error handler.
|
||||
*/
|
||||
|
||||
function errorHandler(voice) {
|
||||
return function(err, req, res, next) {
|
||||
var parts = err.stack.split('\n')[1].split(/[()]/)[1].split(':')
|
||||
, filename = parts.shift()
|
||||
, basename = path.basename(filename)
|
||||
, lineno = parts.shift()
|
||||
, col = parts.shift()
|
||||
, lines = fs.readFileSync(filename, 'utf8').split('\n')
|
||||
, line = lines[lineno - 1].replace(/\./, ' ');
|
||||
|
||||
exec('say -v "' + voice + '" '
|
||||
+ err.message
|
||||
+ ' on line ' + lineno
|
||||
+ ' of ' + basename + '.'
|
||||
+ ' The contents of this line is '
|
||||
+ ' "' + line + '".');
|
||||
|
||||
res.send(500);
|
||||
}
|
||||
}
|
||||
|
||||
var app = express.createServer();
|
||||
|
||||
app.get('/', function(request, response){
|
||||
if (request.is(foo)) response.end('bar');
|
||||
});
|
||||
|
||||
app.use(errorHandler('Vicki'));
|
||||
|
||||
app.listen(3000);
|
||||
14
examples/search/client.js
Normal file
14
examples/search/client.js
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
var search = document.querySelector('[type=search]');
|
||||
var code = document.querySelector('pre');
|
||||
|
||||
search.addEventListener('keyup', function(){
|
||||
var xhr = new XMLHttpRequest;
|
||||
xhr.open('GET', '/search/' + search.value, true);
|
||||
xhr.onreadystatechange = function(){
|
||||
if (4 == xhr.readyState) {
|
||||
code.textContent = xhr.responseText;
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
}, false);
|
||||
64
examples/search/index.js
Normal file
64
examples/search/index.js
Normal file
@@ -0,0 +1,64 @@
|
||||
|
||||
// first:
|
||||
// $ npm install redis
|
||||
// $ redis-server
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../..')
|
||||
, redis = require('redis')
|
||||
, db = redis.createClient();
|
||||
|
||||
// npm install redis
|
||||
|
||||
var app = express();
|
||||
|
||||
app.set('view engine', 'jade');
|
||||
app.set('views', __dirname);
|
||||
|
||||
// populate search
|
||||
|
||||
db.sadd('ferret', 'tobi');
|
||||
db.sadd('ferret', 'loki');
|
||||
db.sadd('ferret', 'jane');
|
||||
db.sadd('cat', 'manny');
|
||||
db.sadd('cat', 'luna');
|
||||
|
||||
/**
|
||||
* GET the search page.
|
||||
*/
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.render('search');
|
||||
});
|
||||
|
||||
/**
|
||||
* GET search for :query.
|
||||
*/
|
||||
|
||||
app.get('/search/:query?', function(req, res){
|
||||
var query = req.params.query;
|
||||
db.smembers(query, function(err, vals){
|
||||
if (err) return res.send(500);
|
||||
res.send(vals);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* GET client javascript. Here we use sendfile()
|
||||
* because serving __dirname with the static() middleware
|
||||
* would also mean serving our server "index.js" and the "search.jade"
|
||||
* template.
|
||||
*/
|
||||
|
||||
app.get('/client.js', function(req, res){
|
||||
res.sendfile(__dirname + '/client.js');
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
15
examples/search/search.jade
Normal file
15
examples/search/search.jade
Normal file
@@ -0,0 +1,15 @@
|
||||
!!! 5
|
||||
html
|
||||
head
|
||||
title Search example
|
||||
style.
|
||||
body {
|
||||
font: 14px "Helvetica Neue", Helvetica;
|
||||
padding: 50px;
|
||||
}
|
||||
body
|
||||
h2 Search
|
||||
p Try searching for "ferret" or "cat".
|
||||
input(type='search')
|
||||
pre
|
||||
script(src='client.js')
|
||||
@@ -1,17 +1,16 @@
|
||||
|
||||
// first:
|
||||
// $ npm install redis
|
||||
// $ redis-server
|
||||
|
||||
var express = require('../..');
|
||||
|
||||
var app = express();
|
||||
|
||||
app.use(express.logger('dev'));
|
||||
|
||||
// Required by session() middleware
|
||||
// pass the secret for signed cookies
|
||||
// (required by session())
|
||||
app.use(express.cookieParser('keyboard cat'));
|
||||
|
||||
// Populates req.session
|
||||
app.use(express.session());
|
||||
app.use(express.session({ secret: 'keyboard cat' }));
|
||||
|
||||
app.get('/', function(req, res){
|
||||
var body = '';
|
||||
@@ -24,5 +23,8 @@ app.get('/', function(req, res){
|
||||
res.send(body + '<p>viewed <strong>' + req.session.views + '</strong> times.</p>');
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express app started on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -10,13 +10,8 @@ var app = express();
|
||||
|
||||
app.use(express.logger('dev'));
|
||||
|
||||
// Required by session() middleware
|
||||
// pass the secret for signed cookies
|
||||
// (required by session())
|
||||
app.use(express.cookieParser('keyboard cat'));
|
||||
|
||||
// Populates req.session
|
||||
app.use(express.session({ store: new RedisStore }));
|
||||
app.use(express.session({ store: new RedisStore, secret: 'keyboard cat' }));
|
||||
|
||||
app.get('/', function(req, res){
|
||||
var body = '';
|
||||
|
||||
44
examples/static-files/index.js
Normal file
44
examples/static-files/index.js
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
var express = require('../..');
|
||||
var app = express();
|
||||
|
||||
// log requests
|
||||
app.use(express.logger('dev'));
|
||||
|
||||
// express on its own has no notion
|
||||
// of a "file". The express.static()
|
||||
// middleware checks for a file matching
|
||||
// the `req.path` within the directory
|
||||
// that you pass it. In this case "GET /js/app.js"
|
||||
// will look for "./public/js/app.js".
|
||||
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
|
||||
// if you wanted to "prefix" you may use
|
||||
// the mounting feature of Connect, for example
|
||||
// "GET /static/js/app.js" instead of "GET /js/app.js".
|
||||
// The mount-path "/static" is simply removed before
|
||||
// passing control to the express.static() middleware,
|
||||
// thus it serves the file correctly by ignoring "/static"
|
||||
app.use('/static', express.static(__dirname + '/public'));
|
||||
|
||||
// if for some reason you want to serve files from
|
||||
// several directories, you can use express.static()
|
||||
// multiple times! Here we're passing "./public/css",
|
||||
// this will allow "GET /style.css" instead of "GET /css/style.css":
|
||||
app.use(express.static(__dirname + '/public/css'));
|
||||
|
||||
// this examples does not have any routes, however
|
||||
// you may `app.use(app.router)` before or after these
|
||||
// static() middleware. If placed before them your routes
|
||||
// will be matched BEFORE file serving takes place. If placed
|
||||
// after as shown here then file serving is performed BEFORE
|
||||
// any routes are hit:
|
||||
app.use(app.router);
|
||||
|
||||
app.listen(3000);
|
||||
console.log('listening on port 3000');
|
||||
console.log('try:');
|
||||
console.log(' GET /hello.txt');
|
||||
console.log(' GET /js/app.js');
|
||||
console.log(' GET /css/style.css');
|
||||
3
examples/static-files/public/css/style.css
Normal file
3
examples/static-files/public/css/style.css
Normal file
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
|
||||
}
|
||||
1
examples/static-files/public/hello.txt
Normal file
1
examples/static-files/public/hello.txt
Normal file
@@ -0,0 +1 @@
|
||||
hey
|
||||
1
examples/static-files/public/js/app.js
Normal file
1
examples/static-files/public/js/app.js
Normal file
@@ -0,0 +1 @@
|
||||
foo
|
||||
@@ -1,51 +0,0 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../lib/express')
|
||||
, stylus = require('stylus');
|
||||
|
||||
var app = express.createServer();
|
||||
|
||||
// $ npm install stylus
|
||||
|
||||
// completely optional, however
|
||||
// the compile function allows you to
|
||||
// define additional functions exposed to Stylus,
|
||||
// alter settings, etc
|
||||
|
||||
function compile(str, path) {
|
||||
return stylus(str)
|
||||
.set('filename', path)
|
||||
.set('compress', true);
|
||||
};
|
||||
|
||||
// add the stylus middleware, which re-compiles when
|
||||
// a stylesheet has changed, compiling FROM src,
|
||||
// TO dest. dest is optional, defaulting to src
|
||||
|
||||
app.use(stylus.middleware({
|
||||
src: __dirname + '/views'
|
||||
, dest: __dirname + '/public'
|
||||
, compile: compile
|
||||
}));
|
||||
|
||||
|
||||
// minimal setup both reading and writting to ./public
|
||||
// would look like:
|
||||
// app.use(stylus.middleware({ src: __dirname + '/public' }));
|
||||
|
||||
// the middleware itself does not serve the static
|
||||
// css files, so we need to expose them with staticProvider
|
||||
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
|
||||
app.set('views', __dirname + '/views');
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.render('index.jade');
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('server listening on port 3000');
|
||||
1
examples/stylus/public/.gitignore
vendored
1
examples/stylus/public/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
*.css
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user