import events from "events" ; import http from "http" ; import send from "send" ; import util from "util" ; import url from "url" ; import Promise from "../utils/promise" ; class Server extends events . EventEmitter { private running : http . Server ; private dir : null ; private port : number ; private sockets : any [ ] ; constructor ( ) { super ( ) ; this . running = null ; this . dir = null ; this . port = 0 ; this . sockets = [ ] ; } return { boolean } isRunning ( ) { return ! ! this . running ; } return { Promise } stop ( ) { const that = this ; if ( ! this . isRunning ( ) ) return Promise ( ) ; const d = Promise . defer ( ) ; this . running . close ( ( err ) => { that . running = null ; that . emit ( "state" , false ) ; if ( err ) d . reject ( err ) ; else d . resolve ( ) ; } ) ; for ( let i = 0 ; i < this . sockets . length ; i ++ ) { this . sockets [ i ] . destroy ( ) ; } return d . promise ; } return { Promise } start ( dir , port ) { const that = this ; let pre = Promise ( ) ; port = port || 8004 ; if ( that . isRunning ( ) ) pre = this . stop ( ) ; return pre . then ( ( ) => { const d = Promise . defer ( ) ; that . running = http . createServer ( ( req , res ) => { function error ( err ) { res . statusCode = err . status || 500 ; res . end ( err . message ) ; } function redirect ( ) { const resultURL = urlTransform ( req . url , ( parsed ) => { parsed . pathname += "/" ; return parsed ; } ) ; res . statusCode = 301 ; res . setHeader ( "Location" , resultURL ) ; res . end ( `Redirecting to ${ resultURL }` ) ; } res . setHeader ( "X-Current-Location" , req . url ) ; send ( req , url . parse ( req . url ) . pathname , { root : dir , } ) . on ( "error" , error ) . on ( "directory" , redirect ) . pipe ( res ) ; } ) ; that . running . on ( "connection" , ( socket ) => { that . sockets . push ( socket ) ; socket . setTimeout ( 4000 ) ; socket . on ( "close" , ( ) => { that . sockets . splice ( that . sockets . indexOf ( socket ) , 1 ) ; } ) ; } ) ; that . running . listen ( port , ( ) => { that . port = port ; that . dir = dir ; that . emit ( "state" , true ) ; d . resolve ( ) ; } ) ; return d . promise ; } ) ; } } param { string } uri param { Function } fn return { string } function urlTransform ( uri , fn ) { return url . format ( fn ( url . parse ( uri ) ) ) ; } export default Server ;