st 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.travis.yml +13 -0
- package/README.md +36 -22
- package/bin/server.js +95 -60
- package/package.json +12 -10
- package/st.js +504 -445
- package/test/basic.js +57 -49
- package/test/cli/basic-test.js +32 -0
- package/test/cli/common.js +108 -0
- package/test/cli/host-test.js +92 -0
- package/test/common.js +42 -30
- package/test/cors.js +11 -13
- package/test/dot-common.js +25 -19
- package/test/dot-false.js +6 -8
- package/test/dot-true.js +8 -8
- package/test/gzip-after-no-gzip.js +12 -19
- package/test/middleware.js +8 -14
- package/test/multi-mount.js +100 -83
- package/test/no-cache.js +8 -10
- package/test/no-cors.js +4 -5
- package/test/no-gzip-accepted-no-cache.js +18 -25
- package/test/no-gzip-accepted.js +18 -24
- package/test/no-gzip.js +4 -9
- package/test/parent-path.js +1 -1
- package/test/passthrough.js +36 -42
- package/test/preset-cache-control.js +31 -27
- package/.npmignore +0 -1
package/test/basic.js
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
const zlib = require('zlib')
|
|
2
|
+
const { test } = require('tap')
|
|
3
|
+
const { req, stExpect, opts, mount } = require('./common')
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
module.exports.req = req
|
|
6
|
+
module.exports.stExpect = stExpect
|
|
7
|
+
module.exports.mount = mount
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
let stEtag
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
test('simple request', function (t) {
|
|
17
|
-
req('/test/st.js', function (er, res, body) {
|
|
11
|
+
test('simple request', (t) => {
|
|
12
|
+
req('/test/st.js', (er, res, body) => {
|
|
13
|
+
t.error(er)
|
|
18
14
|
t.equal(res.statusCode, 200)
|
|
19
15
|
t.ok(/\/javascript$/.test(res.headers['content-type']))
|
|
20
16
|
t.ok(res.headers.etag)
|
|
@@ -24,34 +20,33 @@ test('simple request', function (t) {
|
|
|
24
20
|
})
|
|
25
21
|
})
|
|
26
22
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
req('/test/st.js', {'if-none-match':stEtag}, function (er, res, body) {
|
|
23
|
+
test('304 request', (t) => {
|
|
24
|
+
req('/test/st.js', { 'if-none-match': stEtag }, (er, res, body) => {
|
|
30
25
|
t.equal(res.statusCode, 304)
|
|
31
26
|
t.equal(body.length, 0)
|
|
32
27
|
t.end()
|
|
33
28
|
})
|
|
34
29
|
})
|
|
35
30
|
|
|
36
|
-
|
|
37
31
|
if (opts.gzip !== false) {
|
|
38
|
-
test('gzip',
|
|
39
|
-
req('/test/st.js', {'accept-encoding':'gzip'},
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
32
|
+
test('gzip', (t) => {
|
|
33
|
+
req('/test/st.js', { 'accept-encoding': 'gzip' },
|
|
34
|
+
(er, res, body) => {
|
|
35
|
+
t.equal(res.statusCode, 200)
|
|
36
|
+
t.equal(res.headers['content-encoding'], 'gzip')
|
|
37
|
+
zlib.gunzip(body, (er, body) => {
|
|
38
|
+
if (er) {
|
|
39
|
+
throw er
|
|
40
|
+
}
|
|
41
|
+
t.equal(body.toString(), stExpect)
|
|
42
|
+
t.end()
|
|
43
|
+
})
|
|
47
44
|
})
|
|
48
|
-
})
|
|
49
45
|
})
|
|
50
46
|
}
|
|
51
47
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
var n = 6
|
|
48
|
+
test('multiball!', (t) => {
|
|
49
|
+
let n = 6
|
|
55
50
|
req('/test/st.js', then)
|
|
56
51
|
req('/test/README.md', then)
|
|
57
52
|
req('/test/LICENSE', then)
|
|
@@ -60,13 +55,14 @@ test('multiball!', function (t) {
|
|
|
60
55
|
req('/test/bin/server.js', then)
|
|
61
56
|
|
|
62
57
|
function then (er, res) {
|
|
63
|
-
if (er)
|
|
58
|
+
if (er) {
|
|
64
59
|
throw er
|
|
60
|
+
}
|
|
65
61
|
t.equal(res.statusCode, 200)
|
|
66
62
|
|
|
67
63
|
// give them all time to close, then go again.
|
|
68
|
-
if (--n === 0)
|
|
69
|
-
setTimeout(
|
|
64
|
+
if (--n === 0) {
|
|
65
|
+
setTimeout(() => {
|
|
70
66
|
n = 6
|
|
71
67
|
req('/test/st.js', then2)
|
|
72
68
|
req('/test/README.md', then2)
|
|
@@ -75,50 +71,62 @@ test('multiball!', function (t) {
|
|
|
75
71
|
req('/test/favicon.ico', then2)
|
|
76
72
|
req('/test/bin/server.js', then2)
|
|
77
73
|
}, 200)
|
|
74
|
+
}
|
|
78
75
|
}
|
|
79
76
|
|
|
80
77
|
function then2 (er, res) {
|
|
81
|
-
if (er)
|
|
78
|
+
if (er) {
|
|
82
79
|
throw er
|
|
80
|
+
}
|
|
83
81
|
|
|
84
82
|
t.equal(res.statusCode, 200)
|
|
85
83
|
|
|
86
|
-
if (opts.cache === false)
|
|
84
|
+
if (opts.cache === false) {
|
|
87
85
|
t.equal(res.headers['cache-control'], 'no-cache')
|
|
88
|
-
else if (opts.cache && opts.cache.content && opts.cache.content.maxAge === false)
|
|
86
|
+
} else if (opts.cache && opts.cache.content && opts.cache.content.maxAge === false) {
|
|
89
87
|
t.ok(res.headers['cache-control'] === undefined)
|
|
90
|
-
else if (opts.cache && opts.cache.content && opts.cache.content.cacheControl)
|
|
88
|
+
} else if (opts.cache && opts.cache.content && opts.cache.content.cacheControl) {
|
|
91
89
|
t.equal(res.headers['cache-control'], opts.cache.content.cacheControl)
|
|
92
|
-
else
|
|
90
|
+
} else {
|
|
93
91
|
t.equal(res.headers['cache-control'], 'public, max-age=600')
|
|
92
|
+
}
|
|
94
93
|
|
|
95
|
-
if (--n === 0)
|
|
94
|
+
if (--n === 0) {
|
|
96
95
|
t.end()
|
|
96
|
+
}
|
|
97
97
|
}
|
|
98
98
|
})
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
req('/test/test/fixtures/space in filename.txt', function (er, res, body) {
|
|
100
|
+
test('space in filename', (t) => {
|
|
101
|
+
req('/test/test/fixtures/space in filename.txt', (er, res, body) => {
|
|
103
102
|
t.equal(res.statusCode, 200)
|
|
104
103
|
t.ok(body)
|
|
105
104
|
t.end()
|
|
106
105
|
})
|
|
107
106
|
})
|
|
108
107
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
req('/test%2E%git', function (er, res) {
|
|
108
|
+
test('malformed URL', (t) => {
|
|
109
|
+
req('/test%2E%git', (er, res) => {
|
|
112
110
|
t.equal(res.statusCode, 404)
|
|
113
111
|
t.end()
|
|
114
112
|
})
|
|
115
113
|
})
|
|
116
114
|
|
|
115
|
+
test('shenanigans', (t) => {
|
|
116
|
+
req('/%2e%2E/%2e%2E/%2e%2E/%2e%2E/%2e%2E/%2e%2E/etc/passwd', (er, res) => {
|
|
117
|
+
if (er) {
|
|
118
|
+
throw er
|
|
119
|
+
}
|
|
120
|
+
t.equal(res.statusCode, 403)
|
|
121
|
+
t.end()
|
|
122
|
+
})
|
|
123
|
+
})
|
|
117
124
|
|
|
118
|
-
test('
|
|
119
|
-
req('/%2e%2E
|
|
120
|
-
if (er)
|
|
125
|
+
test('shenanigans2', (t) => {
|
|
126
|
+
req('/test//foo/%2e%2E', (er, res) => {
|
|
127
|
+
if (er) {
|
|
121
128
|
throw er
|
|
129
|
+
}
|
|
122
130
|
t.equal(res.statusCode, 403)
|
|
123
131
|
t.end()
|
|
124
132
|
})
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const { test } = require('tap')
|
|
2
|
+
const { serve, stExpect } = require('./common')
|
|
3
|
+
|
|
4
|
+
test('Basic cli operation', (t) => {
|
|
5
|
+
serve([], (req) => {
|
|
6
|
+
req('/st.js', (er, res, body) => {
|
|
7
|
+
t.ifError(er) &&
|
|
8
|
+
t.equal(res.statusCode, 200) &&
|
|
9
|
+
t.equal(body.toString(), stExpect)
|
|
10
|
+
})
|
|
11
|
+
}, (er, stdout, stderr) => {
|
|
12
|
+
t.ifError(er)
|
|
13
|
+
t.match(stdout, /^listening at http:\/\/(\[::\]|0\.0\.0\.0):[0-9]+\n$/)
|
|
14
|
+
t.equal(stderr, '')
|
|
15
|
+
t.end()
|
|
16
|
+
})
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
test('Listening on localhost only', (t) => {
|
|
20
|
+
serve(['--localhost'], (req) => {
|
|
21
|
+
req('/st.js', (er, res, body) => {
|
|
22
|
+
t.ifError(er) &&
|
|
23
|
+
t.equal(res.statusCode, 200) &&
|
|
24
|
+
t.equal(body.toString(), stExpect)
|
|
25
|
+
})
|
|
26
|
+
}, (er, stdout, stderr) => {
|
|
27
|
+
t.ifError(er)
|
|
28
|
+
t.match(stdout, /^listening at http:\/\/localhost:[0-9]+\n$/)
|
|
29
|
+
t.equal(stderr, '')
|
|
30
|
+
t.end()
|
|
31
|
+
})
|
|
32
|
+
})
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const path = require('path')
|
|
4
|
+
const fs = require('fs')
|
|
5
|
+
const request = require('request')
|
|
6
|
+
const childProcess = require('child_process')
|
|
7
|
+
const bl = require('bl')
|
|
8
|
+
|
|
9
|
+
const port = process.env.PORT || 1337
|
|
10
|
+
|
|
11
|
+
const stExpect = fs.readFileSync(require.resolve('../../st.js'), 'utf8')
|
|
12
|
+
|
|
13
|
+
// Run server with given command line arguments,
|
|
14
|
+
// then allow cbRequests to schedule a bunch of requests,
|
|
15
|
+
// finally call cbDone.
|
|
16
|
+
// cbRequests gets the req function as an argument.
|
|
17
|
+
|
|
18
|
+
function serve (args, cbRequests, cbDone) {
|
|
19
|
+
args = [require.resolve('../../bin/server.js')].concat(args || [])
|
|
20
|
+
const server = childProcess.spawn(process.execPath, args, {
|
|
21
|
+
cwd: path.dirname(path.dirname(__dirname)),
|
|
22
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
23
|
+
env: { LANG: 'C', LC_ALL: 'C' }
|
|
24
|
+
})
|
|
25
|
+
const stdout = bl()
|
|
26
|
+
const stderr = bl()
|
|
27
|
+
server.stdout.pipe(stdout)
|
|
28
|
+
server.stderr.pipe(stderr)
|
|
29
|
+
let thingsToDo = 4 // cbRequests, exit, stdout, stderr
|
|
30
|
+
let code = null
|
|
31
|
+
let signal = null
|
|
32
|
+
let cbReqEr = null
|
|
33
|
+
let outputSeen = false
|
|
34
|
+
server.once('error', (er) => {
|
|
35
|
+
thingsToDo = -10 // only call cbDone once
|
|
36
|
+
cbDone(er)
|
|
37
|
+
})
|
|
38
|
+
server.once('exit', (c, s) => {
|
|
39
|
+
code = c
|
|
40
|
+
signal = s
|
|
41
|
+
if (!outputSeen) {
|
|
42
|
+
outputSeen = true
|
|
43
|
+
--thingsToDo
|
|
44
|
+
}
|
|
45
|
+
then()
|
|
46
|
+
})
|
|
47
|
+
stdout.once('finish', then)
|
|
48
|
+
stderr.once('finish', then)
|
|
49
|
+
server.stdout.once('data', () => {
|
|
50
|
+
if (outputSeen) return
|
|
51
|
+
outputSeen = true
|
|
52
|
+
try {
|
|
53
|
+
cbRequests(req)
|
|
54
|
+
} catch (er) {
|
|
55
|
+
cbReqEr = er
|
|
56
|
+
} finally {
|
|
57
|
+
then()
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
function then () {
|
|
62
|
+
--thingsToDo
|
|
63
|
+
if (thingsToDo === 3) { // all requests done, one way or another
|
|
64
|
+
server.kill()
|
|
65
|
+
} else if (thingsToDo === 0) {
|
|
66
|
+
let er = null
|
|
67
|
+
if (cbReqEr) {
|
|
68
|
+
er = cbReqEr
|
|
69
|
+
} else if (signal !== null && signal !== 'SIGTERM') {
|
|
70
|
+
er = Error('Terminated by signal ' + signal)
|
|
71
|
+
} else if (code !== null && code !== 0) {
|
|
72
|
+
er = Error('Exited with code ' + code)
|
|
73
|
+
}
|
|
74
|
+
const o = stdout.toString(); const e = stderr.toString()
|
|
75
|
+
if (er) {
|
|
76
|
+
console.info(o)
|
|
77
|
+
console.error(e)
|
|
78
|
+
}
|
|
79
|
+
cbDone(er, o, e)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function req (url, headers, cb) {
|
|
84
|
+
if (typeof headers === 'function') {
|
|
85
|
+
cb = headers
|
|
86
|
+
headers = {}
|
|
87
|
+
}
|
|
88
|
+
if (!/:\/\//.test(url)) {
|
|
89
|
+
url = 'http://localhost:' + port + url
|
|
90
|
+
}
|
|
91
|
+
++thingsToDo
|
|
92
|
+
request({
|
|
93
|
+
encoding: null,
|
|
94
|
+
url: url,
|
|
95
|
+
headers: headers
|
|
96
|
+
}, (...args) => {
|
|
97
|
+
try {
|
|
98
|
+
cb.apply(null, args)
|
|
99
|
+
} finally {
|
|
100
|
+
then()
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
module.exports.port = port
|
|
107
|
+
module.exports.stExpect = stExpect
|
|
108
|
+
module.exports.serve = serve
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
const os = require('os')
|
|
2
|
+
let { test, fail, comment } = require('tap')
|
|
3
|
+
const { serve } = require('./common')
|
|
4
|
+
const port = 1338
|
|
5
|
+
|
|
6
|
+
const otherAddress = (() => {
|
|
7
|
+
const ifaces = os.networkInterfaces()
|
|
8
|
+
for (const iface in ifaces) {
|
|
9
|
+
const addrs = ifaces[iface]
|
|
10
|
+
for (let i = 0; i < addrs.length; ++i) {
|
|
11
|
+
const addr = addrs[i].address
|
|
12
|
+
if (/^127\./.test(addr) || /^::1$/.test(addr)) { // loopback device
|
|
13
|
+
continue
|
|
14
|
+
}
|
|
15
|
+
if (/^fe80:/.test(addr)) { // link-local address
|
|
16
|
+
continue
|
|
17
|
+
}
|
|
18
|
+
return addr
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return null
|
|
22
|
+
})()
|
|
23
|
+
if (!otherAddress) {
|
|
24
|
+
fail('No non-loopback network address found', { skip: true })
|
|
25
|
+
test = () => {}
|
|
26
|
+
} else {
|
|
27
|
+
comment('Using ' + otherAddress + ' as non-localhost address')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function addr2url (addr, path) {
|
|
31
|
+
if (/:/.test(addr)) {
|
|
32
|
+
addr = '[' + addr + ']'
|
|
33
|
+
}
|
|
34
|
+
addr = 'http://' + addr + ':' + port
|
|
35
|
+
if (path) {
|
|
36
|
+
addr += path
|
|
37
|
+
}
|
|
38
|
+
return addr
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function testServer (name, args, addr, canConnect, cannotConnect) {
|
|
42
|
+
test(name, (t) => {
|
|
43
|
+
serve(args.concat(['--port', port]), (req) => {
|
|
44
|
+
canConnect.forEach(checkConnections(t, req, true))
|
|
45
|
+
cannotConnect.forEach(checkConnections(t, req, false))
|
|
46
|
+
}, (err, stdout, stderr) => {
|
|
47
|
+
t.ifError(err)
|
|
48
|
+
t.equal(stderr, '')
|
|
49
|
+
if (addr) {
|
|
50
|
+
t.equal(stdout, 'listening at ' + addr2url(addr) + '\n')
|
|
51
|
+
}
|
|
52
|
+
t.end()
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function checkConnections (t, req, canConnect) {
|
|
58
|
+
return (addr) => {
|
|
59
|
+
const url = addr2url(addr, '/st.js')
|
|
60
|
+
req(url, (er, res, body) => {
|
|
61
|
+
if (canConnect) {
|
|
62
|
+
t.ifError(er, url) && t.equal(res.statusCode, 200, url)
|
|
63
|
+
} else {
|
|
64
|
+
t.ok(er, url)
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
testServer(
|
|
71
|
+
'Listening on all ports by default',
|
|
72
|
+
[], null,
|
|
73
|
+
['127.0.0.1', 'localhost', otherAddress], []
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
testServer(
|
|
77
|
+
'Restricted to localhost',
|
|
78
|
+
['--localhost'], 'localhost',
|
|
79
|
+
['127.0.0.1', 'localhost'], [otherAddress]
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
testServer(
|
|
83
|
+
'Restricted to non-local host',
|
|
84
|
+
['--host', otherAddress], otherAddress,
|
|
85
|
+
[otherAddress], ['127.0.0.1']
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
testServer(
|
|
89
|
+
'Restricted to IPv4',
|
|
90
|
+
['--host', '127.0.0.1'], '127.0.0.1',
|
|
91
|
+
['127.0.0.1'], ['::1']
|
|
92
|
+
)
|
package/test/common.js
CHANGED
|
@@ -1,54 +1,66 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
var tap = require('tap')
|
|
1
|
+
const path = require('path')
|
|
2
|
+
const fs = require('fs')
|
|
3
|
+
const http = require('http')
|
|
4
|
+
const request = require('request')
|
|
5
|
+
const { test, tearDown } = require('tap')
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
const st = require('../st.js')
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
let address
|
|
10
|
+
let server
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
var opts = util._extend({
|
|
12
|
+
const opts = Object.assign({
|
|
16
13
|
autoindex: true,
|
|
17
14
|
path: path.dirname(__dirname),
|
|
18
15
|
url: '/test'
|
|
19
16
|
}, global.options || {})
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
const stExpect = fs.readFileSync(require.resolve('../st.js'), 'utf8')
|
|
19
|
+
const mount = st(opts)
|
|
24
20
|
|
|
25
21
|
function req (url, headers, cb) {
|
|
26
|
-
if (typeof headers === 'function')
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
22
|
+
if (typeof headers === 'function') {
|
|
23
|
+
cb = headers
|
|
24
|
+
headers = {}
|
|
25
|
+
}
|
|
31
26
|
|
|
27
|
+
let host = address.address
|
|
28
|
+
if (address.family === 'IPv6') {
|
|
29
|
+
host = `[${host}]`
|
|
30
|
+
}
|
|
32
31
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
request({
|
|
33
|
+
encoding: null,
|
|
34
|
+
url: `http://${host}:${address.port}${url}`,
|
|
35
|
+
headers: headers,
|
|
36
|
+
followRedirect: false
|
|
37
|
+
}, cb)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
test('setup', (t) => {
|
|
41
|
+
server = http.createServer((req, res) => {
|
|
42
|
+
try {
|
|
43
|
+
if (!mount(req, res)) {
|
|
44
|
+
res.statusCode = 404
|
|
45
|
+
return res.end(`Not a match: ${req.url}`)
|
|
46
|
+
}
|
|
47
|
+
} catch (e) {
|
|
48
|
+
res.statusCode = 500
|
|
49
|
+
console.error(e)
|
|
50
|
+
return res.end(`Internal error: ${e.message}`)
|
|
38
51
|
}
|
|
39
|
-
}).listen(
|
|
52
|
+
}).listen(0, '127.0.0.1', () => {
|
|
40
53
|
t.pass('listening')
|
|
54
|
+
address = server.address()
|
|
41
55
|
t.end()
|
|
42
56
|
})
|
|
43
57
|
})
|
|
44
58
|
|
|
45
|
-
|
|
46
|
-
tap.tearDown(function() {
|
|
59
|
+
tearDown(() => {
|
|
47
60
|
server.close()
|
|
48
61
|
})
|
|
49
62
|
|
|
50
|
-
|
|
51
63
|
module.exports.mount = mount
|
|
52
64
|
module.exports.req = req
|
|
53
65
|
module.exports.stExpect = stExpect
|
|
54
|
-
module.exports.opts = opts
|
|
66
|
+
module.exports.opts = opts
|
package/test/cors.js
CHANGED
|
@@ -2,20 +2,18 @@ global.options = {
|
|
|
2
2
|
cors: true
|
|
3
3
|
}
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
const { test } = require('tap')
|
|
6
|
+
const { req } = require('./common')
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
t.
|
|
13
|
-
|
|
14
|
-
t.ok(/
|
|
15
|
-
t.ok(/
|
|
16
|
-
t.ok(/Content-Type/.test(headers));
|
|
17
|
-
t.ok(/Accept/.test(headers));
|
|
18
|
-
t.ok(/Range/.test(headers));
|
|
8
|
+
test('CORS headers', (t) => {
|
|
9
|
+
req('/test/st.js', (er, res) => {
|
|
10
|
+
t.equal(res.headers['access-control-allow-origin'], '*')
|
|
11
|
+
const headers = res.headers['access-control-allow-headers']
|
|
12
|
+
t.ok(/Origin/.test(headers))
|
|
13
|
+
t.ok(/X-Requested-With/.test(headers))
|
|
14
|
+
t.ok(/Content-Type/.test(headers))
|
|
15
|
+
t.ok(/Accept/.test(headers))
|
|
16
|
+
t.ok(/Range/.test(headers))
|
|
19
17
|
t.end()
|
|
20
18
|
})
|
|
21
19
|
})
|
package/test/dot-common.js
CHANGED
|
@@ -1,38 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
const path = require('path')
|
|
2
|
+
const http = require('http')
|
|
3
|
+
const request = require('request')
|
|
4
|
+
const { test, tearDown } = require('tap')
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const st = require('../st.js')
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
let address
|
|
9
|
+
let server
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
var opts = {
|
|
11
|
+
const opts = {
|
|
14
12
|
dot: global.dot,
|
|
15
|
-
path: path.join(__dirname,
|
|
13
|
+
path: path.join(__dirname, 'fixtures', '.dotted-dir')
|
|
16
14
|
}
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+
const mount = st(opts)
|
|
17
|
+
|
|
18
|
+
const req = (url, cb) => {
|
|
19
|
+
let host = address.address
|
|
20
|
+
if (address.family === 'IPv6') {
|
|
21
|
+
host = `[${host}]`
|
|
22
|
+
}
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
request({ url: 'http://localhost:' + port + url }, cb)
|
|
24
|
+
request({ url: `http://${host}:${address.port}${url}` }, cb)
|
|
22
25
|
}
|
|
23
26
|
|
|
24
|
-
test('setup',
|
|
25
|
-
server = http.createServer(
|
|
27
|
+
test('setup', (t) => {
|
|
28
|
+
server = http.createServer((req, res) => {
|
|
26
29
|
if (!mount(req, res)) {
|
|
27
30
|
res.statusCode = 404
|
|
28
|
-
return res.end(
|
|
31
|
+
return res.end(`Not a match: ${req.url}`)
|
|
29
32
|
}
|
|
30
|
-
}).listen(
|
|
33
|
+
}).listen(0, '127.0.0.1', () => {
|
|
31
34
|
t.pass('listening')
|
|
35
|
+
address = server.address()
|
|
32
36
|
t.end()
|
|
33
37
|
})
|
|
34
38
|
})
|
|
35
39
|
|
|
36
|
-
|
|
40
|
+
tearDown(() => {
|
|
37
41
|
server.close()
|
|
38
42
|
})
|
|
43
|
+
|
|
44
|
+
module.exports.req = req
|
package/test/dot-false.js
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
global.dot = false
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var req = common.req
|
|
6
|
-
var test = common.test
|
|
3
|
+
const { test } = require('tap')
|
|
4
|
+
const { req } = require('./dot-common')
|
|
7
5
|
|
|
8
6
|
// failing per https://github.com/isaacs/st/issues/67
|
|
9
|
-
test('non-dotted file',
|
|
10
|
-
req('/index.html',
|
|
7
|
+
test('non-dotted file', (t) => {
|
|
8
|
+
req('/index.html', (er, res, body) => {
|
|
11
9
|
t.equal(res.statusCode, 200)
|
|
12
10
|
t.end()
|
|
13
11
|
})
|
|
14
12
|
})
|
|
15
13
|
|
|
16
|
-
test('dotted file',
|
|
17
|
-
req('/.index.html',
|
|
14
|
+
test('dotted file', (t) => {
|
|
15
|
+
req('/.index.html', (er, res, body) => {
|
|
18
16
|
t.equal(res.statusCode, 403)
|
|
19
17
|
t.end()
|
|
20
18
|
})
|
package/test/dot-true.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
global.dot = true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const { test } = require('tap')
|
|
4
|
+
const { req } = require('./dot-common')
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
test('non-dotted file', function (t) {
|
|
9
|
-
req('/index.html', function (er, res, body) {
|
|
6
|
+
test('non-dotted file', (t) => {
|
|
7
|
+
req('/index.html', (er, res, body) => {
|
|
8
|
+
t.error(er)
|
|
10
9
|
t.equal(res.statusCode, 200)
|
|
11
10
|
t.end()
|
|
12
11
|
})
|
|
13
12
|
})
|
|
14
13
|
|
|
15
|
-
test('dotted file',
|
|
16
|
-
req('/.index.html',
|
|
14
|
+
test('dotted file', (t) => {
|
|
15
|
+
req('/.index.html', (er, res, body) => {
|
|
16
|
+
t.error(er)
|
|
17
17
|
t.equal(res.statusCode, 200)
|
|
18
18
|
t.end()
|
|
19
19
|
})
|