2014-08-17 06:17:23 +00:00
var Promise = require ( 'bluebird' ) ,
2014-08-19 12:36:46 -04:00
fs = require ( 'fs' ) ,
semver = require ( 'semver' ) ,
packageInfo = require ( '../../package.json' ) ,
config = require ( './config' ) ;
function GhostServer ( app ) {
this . app = app ;
this . httpServer = null ;
this . connections = [ ] ;
this . upgradeWarning = setTimeout ( this . logUpgradeWarning . bind ( this ) , 5000 ) ;
2014-08-23 16:42:44 -04:00
// Expose config module for use externally.
this . config = config ;
2014-08-19 12:36:46 -04:00
}
GhostServer . prototype . connection = function ( socket ) {
this . connections . push ( socket ) ;
} ;
// Most browsers keep a persistant connection open to the server
// which prevents the close callback of httpServer from returning
// We need to destroy all connections manually
GhostServer . prototype . closeConnections = function ( ) {
this . connections . forEach ( function ( socket ) {
socket . destroy ( ) ;
} ) ;
} ;
GhostServer . prototype . logStartMessages = function ( ) {
// Tell users if their node version is not supported, and exit
if ( ! semver . satisfies ( process . versions . node , packageInfo . engines . node ) ) {
console . log (
2014-09-10 00:06:24 -04:00
'\nERROR: Unsupported version of Node' . red ,
'\nGhost needs Node version' . red ,
2014-08-19 12:36:46 -04:00
packageInfo . engines . node . yellow ,
2014-09-10 00:06:24 -04:00
'you are using version' . red ,
2014-08-19 12:36:46 -04:00
process . versions . node . yellow ,
2014-09-10 00:06:24 -04:00
'\nPlease go to http://nodejs.org to get a supported version' . green
2014-08-19 12:36:46 -04:00
) ;
process . exit ( 0 ) ;
}
// Startup & Shutdown messages
if ( process . env . NODE _ENV === 'production' ) {
console . log (
2014-09-10 00:06:24 -04:00
'Ghost is running...' . green ,
'\nYour blog is now available on' ,
2014-08-19 12:36:46 -04:00
config . url ,
2014-09-10 00:06:24 -04:00
'\nCtrl+C to shut down' . grey
2014-08-19 12:36:46 -04:00
) ;
// ensure that Ghost exits correctly on Ctrl+C
process . removeAllListeners ( 'SIGINT' ) . on ( 'SIGINT' , function ( ) {
console . log (
2014-09-10 00:06:24 -04:00
'\nGhost has shut down' . red ,
'\nYour blog is now offline'
2014-08-19 12:36:46 -04:00
) ;
process . exit ( 0 ) ;
} ) ;
} else {
console . log (
2014-09-10 00:06:24 -04:00
( 'Ghost is running in ' + process . env . NODE _ENV + '...' ) . green ,
'\nListening on' ,
2014-08-19 12:36:46 -04:00
config . getSocket ( ) || config . server . host + ':' + config . server . port ,
2014-09-10 00:06:24 -04:00
'\nUrl configured as:' ,
2014-08-19 12:36:46 -04:00
config . url ,
2014-09-10 00:06:24 -04:00
'\nCtrl+C to shut down' . grey
2014-08-19 12:36:46 -04:00
) ;
// ensure that Ghost exits correctly on Ctrl+C
process . removeAllListeners ( 'SIGINT' ) . on ( 'SIGINT' , function ( ) {
console . log (
2014-09-10 00:06:24 -04:00
'\nGhost has shutdown' . red ,
'\nGhost was running for' ,
2014-08-19 12:36:46 -04:00
Math . round ( process . uptime ( ) ) ,
2014-09-10 00:06:24 -04:00
'seconds'
2014-08-19 12:36:46 -04:00
) ;
process . exit ( 0 ) ;
} ) ;
}
} ;
GhostServer . prototype . logShutdownMessages = function ( ) {
console . log ( 'Ghost is closing connections' . red ) ;
} ;
GhostServer . prototype . logUpgradeWarning = function ( ) {
console . log ( 'Warning: Ghost will no longer start automatically when using it as an npm module. Please see the docs(http://tinyurl.com/npm-upgrade) for information on how to update your code.' . red ) ;
} ;
2014-08-23 16:42:44 -04:00
/ * *
* Starts the ghost server listening on the configured port .
* Alternatively you can pass in your own express instance and let Ghost
* start lisetning for you .
* @ param { Object = } externalApp Optional express app instance .
* @ return { Promise }
* /
GhostServer . prototype . start = function ( externalApp ) {
var self = this ,
app = externalApp ? externalApp : self . app ;
2014-08-17 06:17:23 +00:00
2014-08-19 12:36:46 -04:00
// ## Start Ghost App
2014-08-17 06:17:23 +00:00
return new Promise ( function ( resolve ) {
if ( config . getSocket ( ) ) {
// Make sure the socket is gone before trying to create another
try {
fs . unlinkSync ( config . getSocket ( ) ) ;
} catch ( e ) {
// We can ignore this.
}
2014-08-23 16:42:44 -04:00
self . httpServer = app . listen (
2014-08-17 06:17:23 +00:00
config . getSocket ( )
) ;
2014-08-19 12:36:46 -04:00
2014-08-17 06:17:23 +00:00
fs . chmod ( config . getSocket ( ) , '0660' ) ;
} else {
2014-08-23 16:42:44 -04:00
self . httpServer = app . listen (
2014-08-17 06:17:23 +00:00
config . server . port ,
config . server . host
) ;
}
2014-08-19 12:36:46 -04:00
2014-09-09 14:20:31 +00:00
self . httpServer . on ( 'error' , function ( error ) {
if ( error . errno === 'EADDRINUSE' ) {
console . log ( 'ERROR: Cannot start Ghost. Another program is already using this port (is another Ghost instance already running?)' . red ) ;
} else {
console . log (
'ERROR: There was an error starting your server. ' . red ,
( '(Code: ' + error . errno + ')' ) . red
) ;
}
process . exit ( - 1 ) ;
} ) ;
2014-08-17 06:17:23 +00:00
self . httpServer . on ( 'connection' , self . connection . bind ( self ) ) ;
self . httpServer . on ( 'listening' , function ( ) {
self . logStartMessages ( ) ;
clearTimeout ( self . upgradeWarning ) ;
resolve ( self ) ;
} ) ;
} ) ;
2014-08-19 12:36:46 -04:00
} ;
// Returns a promise that will be fulfilled when the server stops.
// If the server has not been started, the promise will be fulfilled
// immediately
GhostServer . prototype . stop = function ( ) {
2014-08-17 06:17:23 +00:00
var self = this ;
return new Promise ( function ( resolve ) {
if ( self . httpServer === null ) {
resolve ( self ) ;
} else {
self . httpServer . close ( function ( ) {
self . httpServer = null ;
self . logShutdownMessages ( ) ;
resolve ( self ) ;
} ) ;
self . closeConnections ( ) ;
}
} ) ;
2014-08-19 12:36:46 -04:00
} ;
// Restarts the ghost application
GhostServer . prototype . restart = function ( ) {
return this . stop ( ) . then ( this . start . bind ( this ) ) ;
} ;
// To be called after `stop`
GhostServer . prototype . hammertime = function ( ) {
console . log ( 'Can\'t touch this' . green ) ;
2014-08-17 06:17:23 +00:00
return Promise . resolve ( this ) ;
2014-08-19 12:36:46 -04:00
} ;
module . exports = GhostServer ;