UNPKG

nadesiko3

Version:
124 lines (112 loc) 3.23 kB
#!/usr/bin/env node /** 超簡易サーバ(生のnodeだけで簡単HTTPサーバ) */ import path from 'path' import fs from 'fs' import { execSync } from 'child_process' import opener from 'opener' import http from 'http' // __dirname のために import url from 'url' const __filename = url.fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) // CONST const SERVER_PORT = 3000 const rootDir = path.resolve(__dirname, '../../') // ライブラリがあるかチェック const testFile = path.join(rootDir, 'demo/extlib/pure-min.css') if (!fs.existsSync(testFile)) { console.log('try to downlod extlib') try { execSync('npm run extlib:install') } catch (err) { console.error(err) } } // root => redirect to demo/ const server = http.createServer(function (req, res) { console.log('[ようこそ]', JSON.stringify(req.url)) // root なら "demo/"へリダイレクト if (req.url === '/') { res.writeHead(302, { 'Location': '/demo/' }) res.end('<a href="/demo/">DEMO</a>') return } // サニタイズ let uri = '' + req.url uri = uri.replace(/\.\./g, '') // 上のフォルダは許さない if (uri.indexOf('?') >= 0) { uri = (uri + '?').split('?')[0] } // ファイルパスを生成 let filePath = path.join(rootDir, uri) // エイリアス if (uri.startsWith('/extlib')) { filePath = path.join(rootDir, 'demo', uri) } if (uri.startsWith('/css')) { filePath = path.join(rootDir, 'demo', uri) } if (uri.startsWith('/image')) { filePath = path.join(rootDir, 'demo', uri) } // フォルダか? if (isDir(filePath)) { // index.html を足す filePath = path.join(filePath, 'index.html') } // ファイルの存在確認 if (!fs.existsSync(filePath)) { console.log('[ERROR] 404 ', uri) console.log('| file=', filePath) res.statusCode = 404 res.end('<html><meta charset="utf-8"><body><h1>404 残念(ToT) ファイルがありません。</h1></body></html>') return } // ファイルを読んで返す fs.readFile(filePath, (err, data) => { if (err) { res.statusCode = 500 res.end('Failed to read file.') return } const mime = getMIMEType(filePath) res.writeHead(200, { 'Content-Type': mime }) res.end(data) }) }) // サーバを起動 server.listen(SERVER_PORT, function () { const url = 'http://localhost:' + SERVER_PORT console.log('### 超簡易Webサーバが起動しました') console.log('### script: /src/nako3server.mjs') console.log('[URL]', url) opener(url) }) // MIMEタイプ const MimeTypes = { '.html': 'text/html; charset=utf-8', '.css': 'text/css', '.js': 'text/javascript', '.png': 'image/png', '.gif': 'image/gif', '.svg': 'svg+xml' } function getMIMEType (url) { let ext = '.txt' const m = url.match(/(\.[a-z0-9_]+)$/) if (m) { ext = m[1] } if (MimeTypes[ext]) { return MimeTypes[ext] } return 'text/plain; charset=utf-8' } // ディレクトリか判定 function isDir (pathName) { try { const stats = fs.statSync(pathName, { throwIfNoEntry: false }) if (stats && stats.isDirectory()) { return true } } catch (e) { return false } return false }