nadesiko3 3.7.20 → 3.7.21
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/batch/command.txt +115 -113
- package/core/package.json +2 -2
- package/core/src/README.md +98 -0
- package/core/src/nako_core_version.mjs +2 -2
- package/core/src/nako_core_version.mts +2 -2
- package/package.json +21 -27
- package/release/_hash.txt +36 -36
- package/release/_script-tags.txt +16 -16
- package/release/command.json +1 -1
- package/release/command.json.js +1 -1
- package/release/command_cnako3.json +1 -1
- package/release/command_list.json +1 -1
- package/release/edit_main.js +2 -2
- package/release/edit_main.js.map +3 -3
- package/release/editor.js +2 -2
- package/release/plugin_datetime.js +1 -1
- package/release/plugin_datetime.js.map +3 -3
- package/release/plugin_markup.js +28 -28
- package/release/plugin_markup.js.map +3 -3
- package/release/version.js +2 -2
- package/release/version_main.js +2 -2
- package/release/version_main.js.map +2 -2
- package/release/wnako3.js +13 -13
- package/release/wnako3.js.map +2 -2
- package/release/wnako3webworker.js +1 -1
- package/release/wnako3webworker.js.map +1 -1
- package/src/cnako3mod.mjs +1 -2
- package/src/cnako3mod.mts +1 -2
- package/src/nako_version.mjs +2 -2
- package/src/nako_version.mts +2 -2
- package/src/plugin_httpserver.mjs +184 -13
- package/src/plugin_httpserver.mts +176 -10
- package/src/plugin_node.mjs +0 -1
- package/src/plugin_node.mts +0 -1
- package/src/wnako3mod.mjs +3 -0
- package/src/wnako3mod.mts +3 -0
- package/test/common/wnako3mod_test.mjs +48 -0
- package/test/node/package_json_test.mjs +17 -0
- package/test/node/plugin_httpserver_test.mjs +239 -0
- package/tools/nako3server/index.nako3 +4 -2
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/* eslint-disable no-undef */
|
|
2
|
+
import assert from 'assert'
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import fs from 'fs'
|
|
5
|
+
import http from 'http'
|
|
6
|
+
import os from 'os'
|
|
7
|
+
import { NakoCompiler } from '../../core/src/nako3.mjs'
|
|
8
|
+
import PluginHttpServer from '../../src/plugin_httpserver.mjs'
|
|
9
|
+
|
|
10
|
+
// __dirname のために
|
|
11
|
+
import url from 'url'
|
|
12
|
+
const __filename = url.fileURLToPath(import.meta.url)
|
|
13
|
+
const __dirname = path.dirname(__filename)
|
|
14
|
+
|
|
15
|
+
describe('plugin_httpserver_test', () => {
|
|
16
|
+
let nako
|
|
17
|
+
let serverDp
|
|
18
|
+
|
|
19
|
+
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
serverDp = null
|
|
23
|
+
nako = new NakoCompiler()
|
|
24
|
+
// PluginHttpServerの登録。名前は 'plugin_httpserver.js' とする。
|
|
25
|
+
nako.addPluginFile('PluginHttpServer', 'plugin_httpserver.js', PluginHttpServer)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
afterEach(async () => {
|
|
29
|
+
if (serverDp && serverDp.server) {
|
|
30
|
+
await new Promise((resolve) => {
|
|
31
|
+
serverDp.server.close(() => {
|
|
32
|
+
resolve()
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('クエリパラメータ付きのURLで静的ファイルが取得できること', async () => {
|
|
39
|
+
// テスト用のダミーファイルを作成
|
|
40
|
+
const tempDir = path.join(__dirname, 'fixtures_http')
|
|
41
|
+
if (!fs.existsSync(tempDir)) {
|
|
42
|
+
fs.mkdirSync(tempDir, { recursive: true })
|
|
43
|
+
}
|
|
44
|
+
const tempFile = path.join(tempDir, 'test.txt')
|
|
45
|
+
fs.writeFileSync(tempFile, 'hello world')
|
|
46
|
+
|
|
47
|
+
let port = 0
|
|
48
|
+
// `簡易HTTPサーバ起動時`を呼ぶ
|
|
49
|
+
const code = `
|
|
50
|
+
●ダミー起動
|
|
51
|
+
戻る。
|
|
52
|
+
ここまで。
|
|
53
|
+
「ダミー起動」を${port}で簡易HTTPサーバ起動時。
|
|
54
|
+
「/」を「${tempDir.replace(/\\/g, '/')}」に簡易HTTPサーバ静的パス指定。
|
|
55
|
+
`
|
|
56
|
+
const g = await nako.runAsync(code, 'main')
|
|
57
|
+
serverDp = g.__httpserver
|
|
58
|
+
await wait(100)
|
|
59
|
+
port = serverDp.server.address().port
|
|
60
|
+
|
|
61
|
+
// クエリパラメータ付きでリクエストを送る
|
|
62
|
+
const resText = await new Promise((resolve, reject) => {
|
|
63
|
+
http.get(`http://localhost:${port}/test.txt?foo=bar&baz=123`, (res) => {
|
|
64
|
+
let data = ''
|
|
65
|
+
res.on('data', (chunk) => { data += chunk })
|
|
66
|
+
res.on('end', () => { resolve(data) })
|
|
67
|
+
}).on('error', reject)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
assert.strictEqual(resText, 'hello world')
|
|
71
|
+
|
|
72
|
+
// 一時ファイルを削除
|
|
73
|
+
try {
|
|
74
|
+
fs.unlinkSync(tempFile)
|
|
75
|
+
fs.rmdirSync(tempDir)
|
|
76
|
+
} catch (e) {}
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('POSTメソッドで送信されたJSONデータを取得できること', async () => {
|
|
80
|
+
let port = 0
|
|
81
|
+
const code = `
|
|
82
|
+
●ダミー起動
|
|
83
|
+
戻る。
|
|
84
|
+
ここまで。
|
|
85
|
+
●受信処理
|
|
86
|
+
POSTデータ["message"]を簡易HTTPサーバ出力。
|
|
87
|
+
ここまで。
|
|
88
|
+
「ダミー起動」を${port}で簡易HTTPサーバ起動時。
|
|
89
|
+
「受信処理」を「/post-json」に簡易HTTPサーバ受信時。
|
|
90
|
+
`
|
|
91
|
+
const g = await nako.runAsync(code, 'main')
|
|
92
|
+
serverDp = g.__httpserver
|
|
93
|
+
await wait(100)
|
|
94
|
+
port = serverDp.server.address().port
|
|
95
|
+
|
|
96
|
+
const postData = JSON.stringify({ message: 'hello post json' })
|
|
97
|
+
const resText = await new Promise((resolve, reject) => {
|
|
98
|
+
const req = http.request({
|
|
99
|
+
hostname: 'localhost',
|
|
100
|
+
port: port,
|
|
101
|
+
path: '/post-json',
|
|
102
|
+
method: 'POST',
|
|
103
|
+
headers: {
|
|
104
|
+
'Content-Type': 'application/json',
|
|
105
|
+
'Content-Length': Buffer.byteLength(postData)
|
|
106
|
+
}
|
|
107
|
+
}, (res) => {
|
|
108
|
+
let data = ''
|
|
109
|
+
res.on('data', (chunk) => { data += chunk })
|
|
110
|
+
res.on('end', () => { resolve(data) })
|
|
111
|
+
})
|
|
112
|
+
req.on('error', reject)
|
|
113
|
+
req.write(postData)
|
|
114
|
+
req.end()
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
assert.strictEqual(resText, 'hello post json')
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it('POSTメソッドで送信されたurlencodedデータを取得できること', async () => {
|
|
121
|
+
let port = 0
|
|
122
|
+
const code = `
|
|
123
|
+
●ダミー起動
|
|
124
|
+
戻る。
|
|
125
|
+
ここまで。
|
|
126
|
+
●受信処理
|
|
127
|
+
POSTデータ["message"]を簡易HTTPサーバ出力。
|
|
128
|
+
ここまで。
|
|
129
|
+
「ダミー起動」を${port}で簡易HTTPサーバ起動時。
|
|
130
|
+
「受信処理」を「/post-urlencoded」に簡易HTTPサーバ受信時。
|
|
131
|
+
`
|
|
132
|
+
const g = await nako.runAsync(code, 'main')
|
|
133
|
+
serverDp = g.__httpserver
|
|
134
|
+
await wait(100)
|
|
135
|
+
port = serverDp.server.address().port
|
|
136
|
+
|
|
137
|
+
const postData = 'message=hello+post+urlencoded'
|
|
138
|
+
const resText = await new Promise((resolve, reject) => {
|
|
139
|
+
const req = http.request({
|
|
140
|
+
hostname: 'localhost',
|
|
141
|
+
port: port,
|
|
142
|
+
path: '/post-urlencoded',
|
|
143
|
+
method: 'POST',
|
|
144
|
+
headers: {
|
|
145
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
146
|
+
'Content-Length': Buffer.byteLength(postData)
|
|
147
|
+
}
|
|
148
|
+
}, (res) => {
|
|
149
|
+
let data = ''
|
|
150
|
+
res.on('data', (chunk) => { data += chunk })
|
|
151
|
+
res.on('end', () => { resolve(data) })
|
|
152
|
+
})
|
|
153
|
+
req.on('error', reject)
|
|
154
|
+
req.write(postData)
|
|
155
|
+
req.end()
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
assert.strictEqual(resText, 'hello post urlencoded')
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
it('POSTメソッドでファイルをアップロードしてFILESデータを取得できること', async () => {
|
|
162
|
+
const originalWriteFileSync = fs.writeFileSync
|
|
163
|
+
fs.writeFileSync = () => {
|
|
164
|
+
throw new Error('writeFileSync should not be used during upload handling')
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
let port = 0
|
|
168
|
+
const code = `
|
|
169
|
+
●ダミー起動
|
|
170
|
+
戻る。
|
|
171
|
+
ここまで。
|
|
172
|
+
●受信処理
|
|
173
|
+
ファイル情報=FILESデータ[0]
|
|
174
|
+
もし、ファイル情報["path"]が空でなければ
|
|
175
|
+
ファイル名=ファイル情報["name"]
|
|
176
|
+
ファイルサイズ=ファイル情報["size"]
|
|
177
|
+
「OK:{ファイル名}:{ファイルサイズ}」を簡易HTTPサーバ出力。
|
|
178
|
+
違えば
|
|
179
|
+
「NG」を簡易HTTPサーバ出力。
|
|
180
|
+
ここまで。
|
|
181
|
+
ここまで。
|
|
182
|
+
「ダミー起動」を${port}で簡易HTTPサーバ起動時。
|
|
183
|
+
「受信処理」を「/upload」に簡易HTTPサーバ受信時。
|
|
184
|
+
`
|
|
185
|
+
const g = await nako.runAsync(code, 'main')
|
|
186
|
+
serverDp = g.__httpserver
|
|
187
|
+
await wait(100)
|
|
188
|
+
port = serverDp.server.address().port
|
|
189
|
+
|
|
190
|
+
const boundary = '----TestBoundary'
|
|
191
|
+
const parts = [
|
|
192
|
+
`--${boundary}\r\n`,
|
|
193
|
+
`Content-Disposition: form-data; name="file1"; filename="hello.txt"\r\n`,
|
|
194
|
+
`Content-Type: text/plain\r\n\r\n`,
|
|
195
|
+
`hello world nako3 upload\r\n`,
|
|
196
|
+
`--${boundary}--\r\n`
|
|
197
|
+
]
|
|
198
|
+
const postData = Buffer.from(parts.join(''))
|
|
199
|
+
|
|
200
|
+
const resText = await new Promise((resolve, reject) => {
|
|
201
|
+
const req = http.request({
|
|
202
|
+
hostname: 'localhost',
|
|
203
|
+
port: port,
|
|
204
|
+
path: '/upload',
|
|
205
|
+
method: 'POST',
|
|
206
|
+
headers: {
|
|
207
|
+
'Content-Type': `multipart/form-data; boundary=${boundary}`,
|
|
208
|
+
'Content-Length': postData.length
|
|
209
|
+
}
|
|
210
|
+
}, (res) => {
|
|
211
|
+
let data = ''
|
|
212
|
+
res.on('data', (chunk) => { data += chunk })
|
|
213
|
+
res.on('end', () => { resolve(data) })
|
|
214
|
+
})
|
|
215
|
+
req.on('error', reject)
|
|
216
|
+
req.write(postData)
|
|
217
|
+
req.end()
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
try {
|
|
221
|
+
assert.strictEqual(resText, 'OK:hello.txt:24')
|
|
222
|
+
|
|
223
|
+
const uploadDir = path.join(os.tmpdir(), 'nako3-plugin_httpserver_upload')
|
|
224
|
+
if (fs.existsSync(uploadDir)) {
|
|
225
|
+
const files = fs.readdirSync(uploadDir)
|
|
226
|
+
for (const file of files) {
|
|
227
|
+
try {
|
|
228
|
+
fs.unlinkSync(path.join(uploadDir, file))
|
|
229
|
+
} catch (e) {}
|
|
230
|
+
}
|
|
231
|
+
try {
|
|
232
|
+
fs.rmdirSync(uploadDir)
|
|
233
|
+
} catch (e) {}
|
|
234
|
+
}
|
|
235
|
+
} finally {
|
|
236
|
+
fs.writeFileSync = originalWriteFileSync
|
|
237
|
+
}
|
|
238
|
+
})
|
|
239
|
+
})
|