You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
2.2 KiB
80 lines
2.2 KiB
'use strict'; |
|
|
|
const connect = require('connect'); |
|
const http = require('http'); |
|
const { underline } = require('picocolors'); |
|
const Promise = require('bluebird'); |
|
const open = require('open'); |
|
const net = require('net'); |
|
|
|
module.exports = function(args) { |
|
const app = connect(); |
|
const { config } = this; |
|
const ip = args.i || args.ip || config.server.ip || undefined; |
|
const port = parseInt(args.p || args.port || config.server.port || process.env.port, 10) || 4000; |
|
const { root } = config; |
|
|
|
return checkPort(ip, port).then(() => this.extend.filter.exec('server_middleware', app, {context: this})).then(() => { |
|
if (args.s || args.static) { |
|
return this.load(); |
|
} |
|
|
|
return this.watch(); |
|
}).then(() => startServer(http.createServer(app), port, ip)).then(server => { |
|
const addr = server.address(); |
|
const addrString = formatAddress(ip || addr.address, addr.port, root); |
|
|
|
this.log.info('Hexo is running at %s . Press Ctrl+C to stop.', underline(addrString)); |
|
this.emit('server'); |
|
|
|
if (args.o || args.open) { |
|
open(addrString); |
|
} |
|
|
|
return server; |
|
}).catch(err => { |
|
switch (err.code) { |
|
case 'EADDRINUSE': |
|
this.log.fatal(`Port ${port} has been used. Try other port instead.`); |
|
break; |
|
|
|
case 'EACCES': |
|
this.log.fatal(`Permission denied. You can't use port ${port}.`); |
|
break; |
|
} |
|
|
|
this.unwatch(); |
|
throw err; |
|
}); |
|
}; |
|
|
|
function startServer(server, port, ip) { |
|
return new Promise((resolve, reject) => { |
|
server.listen(port, ip, resolve); |
|
server.on('error', reject); |
|
}).then(() => server); |
|
} |
|
|
|
function checkPort(ip, port) { |
|
if (port > 65535 || port < 1) { |
|
return Promise.reject(new RangeError(`Port number ${port} is invalid. Try a number between 1 and 65535.`)); |
|
} |
|
|
|
const server = net.createServer(); |
|
|
|
return new Promise((resolve, reject) => { |
|
server.once('error', reject); |
|
server.once('listening', resolve); |
|
server.listen(port, ip); |
|
}).then(() => { server.close(); }); |
|
} |
|
|
|
function formatAddress(ip, port, root) { |
|
let hostname = ip; |
|
if (ip === '0.0.0.0' || ip === '::') { |
|
hostname = 'localhost'; |
|
} |
|
|
|
let path = root.startsWith("/") ? root : `/${root}`; |
|
return new URL(`http://${hostname}:${port}${path}`).toString(); |
|
}
|
|
|