server.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. 'use strict';
  2. var connect = require('connect');
  3. var http = require('http');
  4. var chalk = require('chalk');
  5. var Promise = require('bluebird');
  6. var open = require('opn');
  7. var net = require('net');
  8. var url = require('url');
  9. module.exports = function(args) {
  10. var app = connect();
  11. var config = this.config;
  12. var ip = args.i || args.ip || config.server.ip || undefined;
  13. var port = parseInt(args.p || args.port || config.server.port || process.env.port, 10) || 4000;
  14. var root = config.root;
  15. var self = this;
  16. return checkPort(ip, port).then(function() {
  17. return self.extend.filter.exec('server_middleware', app, {context: self});
  18. }).then(function() {
  19. if (args.s || args.static) {
  20. return self.load();
  21. }
  22. return self.watch();
  23. }).then(function() {
  24. return startServer(http.createServer(app), port, ip);
  25. }).then(function(server) {
  26. var addr = server.address();
  27. var addrString = formatAddress(ip || addr.address, addr.port, root);
  28. self.log.info('Hexo is running at %s . Press Ctrl+C to stop.', chalk.underline(addrString));
  29. self.emit('server');
  30. if (args.o || args.open) {
  31. open(addrString);
  32. }
  33. return server;
  34. }).catch(function(err) {
  35. switch (err.code){
  36. case 'EADDRINUSE':
  37. self.log.fatal('Port %d has been used. Try other port instead.', port);
  38. break;
  39. case 'EACCES':
  40. self.log.fatal('Permission denied. You can\'t use port ' + port + '.');
  41. break;
  42. }
  43. self.unwatch();
  44. throw err;
  45. });
  46. };
  47. function startServer(server, port, ip) {
  48. return new Promise(function(resolve, reject) {
  49. server.listen(port, ip, function() {
  50. resolve(server);
  51. });
  52. server.on('error', reject);
  53. });
  54. }
  55. function checkPort(ip, port) {
  56. return new Promise(function(resolve, reject) {
  57. if (port > 65535 || port < 1) {
  58. return reject(new Error('Port number ' + port + ' is invalid. Try a number between 1 and 65535.'));
  59. }
  60. var server = net.createServer();
  61. server.once('error', reject);
  62. server.once('listening', function() {
  63. server.close();
  64. resolve();
  65. });
  66. server.listen(port, ip);
  67. });
  68. }
  69. function formatAddress(ip, port, root) {
  70. var hostname = ip;
  71. if (ip === '0.0.0.0' || ip === '::') {
  72. hostname = 'localhost';
  73. }
  74. return url.format({protocol: 'http', hostname: hostname, port: port, path: root});
  75. }