New HTTP/HTTPS server configuration, a lot more flexible.
This commit is contained in:
parent
7fc9ca96b2
commit
8b3373a7cc
@ -14,6 +14,11 @@ indent_style = tab
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespaces = true
|
||||
|
||||
# YAML only allows spaces.
|
||||
[*.yaml]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
# Special settings for NPM file.
|
||||
[/package.json]
|
||||
indent_size = 2
|
||||
|
@ -1,59 +1,56 @@
|
||||
# Configuration of XO-Server's HTTP server.
|
||||
# Note: Relative paths will be resolved from XO-Server's directory.
|
||||
|
||||
# Configuration of the embedded HTTP server.
|
||||
http:
|
||||
# Is HTTP enabled?
|
||||
#
|
||||
# Default: true
|
||||
#enabled: false
|
||||
|
||||
# Address on which the server is listening on.
|
||||
#
|
||||
# Sets it to '127.0.0.1' to listen only on the local host.
|
||||
#
|
||||
# Default: 0.0.0.0 (all addresses)
|
||||
#host: '127.0.0.1'
|
||||
# Hosts & ports on which to listen.
|
||||
listen:
|
||||
# Basic HTTP.
|
||||
-
|
||||
# Address on which the server is listening on.
|
||||
#
|
||||
# Sets it to '127.0.0.1' to listen only on the local host.
|
||||
#
|
||||
# Default: '0.0.0.0' (all addresses)
|
||||
#host: '127.0.0.1'
|
||||
|
||||
# Port on which the server is listening on.
|
||||
#
|
||||
# Default: 80
|
||||
#port: 8080
|
||||
# Port on which the server is listening on.
|
||||
#
|
||||
# Default: undefined
|
||||
port: 80
|
||||
|
||||
# Configuration of XO-Server's HTTPS server.
|
||||
#
|
||||
# A certificate is required, see http://www.selfsignedcertificate.com/
|
||||
# or https://devcenter.heroku.com/articles/ssl-certificate-self to
|
||||
# easily create a (unsecure) self-signed certificate.
|
||||
https:
|
||||
# Is HTTPS enabled?
|
||||
#
|
||||
# Default: false
|
||||
#enabled: true
|
||||
# Instead of `host` and `port` a path to a UNIX socket may be
|
||||
# specified (overrides `host` and `port`).
|
||||
#
|
||||
# Default: undefined
|
||||
#socket: './http.sock'
|
||||
|
||||
# Address on which the server is listening on.
|
||||
#
|
||||
# Sets it to '127.0.0.1' to listen only on the local host.
|
||||
#
|
||||
# Default: 0.0.0.0 (all addresses)
|
||||
#host: '127.0.0.1'
|
||||
# Basic HTTPS.
|
||||
# -
|
||||
# # The only difference is the presence of the certificate and the
|
||||
# # key.
|
||||
|
||||
# Port on which the server is listening on.
|
||||
#
|
||||
# Default: 443
|
||||
#port: 8081
|
||||
# #host: '127.0.0.1'
|
||||
# port: 443
|
||||
|
||||
# File containing the certificate (PEM format).
|
||||
#
|
||||
# Default: './certificate.pem'
|
||||
#certificate: '/path/to/the/certificate.pem'
|
||||
# # File containing the certificate (PEM format).
|
||||
# #
|
||||
# # Default: undefined
|
||||
# certificate: './certificate.pem'
|
||||
|
||||
# File containing the private key (PEM format).
|
||||
#
|
||||
# If the key is encrypted, the passphrase will be asked at server
|
||||
# startup.
|
||||
#
|
||||
# Default: './key.pem'
|
||||
#key: '/path/to/the/key.pem'
|
||||
# # File containing the private key (PEM format).
|
||||
# #
|
||||
# # If the key is encrypted, the passphrase will be asked at
|
||||
# # server startup.
|
||||
# #
|
||||
# # Default: undefined
|
||||
# key: './key.pem'
|
||||
|
||||
# Configuration of the Redis server.
|
||||
# List of files/directories which will be served.
|
||||
mounts:
|
||||
'/': './public/http/'
|
||||
|
||||
# Connection to the Redis server.
|
||||
redis:
|
||||
# Syntax: tcp://[db[:password]@]hostname[:port]
|
||||
#
|
||||
|
102
src/main.coffee
102
src/main.coffee
@ -1,10 +1,6 @@
|
||||
# File system handling.
|
||||
$fs = require 'fs'
|
||||
|
||||
# HTTP(S) handling.
|
||||
$http = require 'http'
|
||||
$https = require 'https'
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
# Low level tools.
|
||||
@ -31,34 +27,11 @@ $XO = require './xo'
|
||||
# Helpers for dealing with fibers.
|
||||
{$fiberize, $waitForPromise} = require './fibers-utils'
|
||||
|
||||
# HTTP/HTTPS server which can listen on multiple ports.
|
||||
$WebServer = require './web-server'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
$createWebServer = ({host, port, certificate, key}) ->
|
||||
# Creates the web server.
|
||||
if certificate? and key?
|
||||
protocol = 'HTTPS'
|
||||
server = $https.createServer {
|
||||
cert: certificate
|
||||
key: key
|
||||
}
|
||||
else
|
||||
protocol = 'HTTP'
|
||||
server = $http.createServer()
|
||||
|
||||
# Starts listening.
|
||||
server.listen port, host
|
||||
|
||||
# Prints a message when it has started to listen.
|
||||
server.once 'listening', ->
|
||||
console.log "#{protocol} server is listening on #{host}:#{port}"
|
||||
|
||||
# Prints an error message if if failed to listen.
|
||||
server.once 'error', ->
|
||||
console.warn "#{protocol} server could not listen on #{host}:#{port}"
|
||||
|
||||
# Returns the server.
|
||||
server
|
||||
|
||||
$handleJsonRpcCall = (api, session, encodedRequest) ->
|
||||
request = {
|
||||
id: null
|
||||
@ -122,19 +95,11 @@ do $fiberize ->
|
||||
# Defines defaults configuration.
|
||||
$nconf.defaults {
|
||||
http: {
|
||||
enabled: true
|
||||
host: '0.0.0.0'
|
||||
port: 80
|
||||
}
|
||||
https: {
|
||||
enabled: false
|
||||
host: '0.0.0.0'
|
||||
port: 443
|
||||
certificate: './certificate.pem'
|
||||
key: './key.pem'
|
||||
listen: []
|
||||
mounts: []
|
||||
}
|
||||
redis: {
|
||||
uri: 'tcp://127.0.0.1:6379'
|
||||
# Default values are handled by `redis`.
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,44 +119,35 @@ do $fiberize ->
|
||||
}
|
||||
}
|
||||
|
||||
# Creates web servers according to the configuration.
|
||||
webServers = []
|
||||
if $nconf.get 'http:enabled'
|
||||
webServers.push $createWebServer {
|
||||
host: $nconf.get 'http:host'
|
||||
port: $nconf.get 'http:port'
|
||||
}
|
||||
if $nconf.get 'https:enabled'
|
||||
webServers.push $createWebServer {
|
||||
host: $nconf.get 'https:host'
|
||||
port: $nconf.get 'https:port'
|
||||
certificate: $nconf.get 'https:certificate'
|
||||
key: $nconf.get 'https:key'
|
||||
}
|
||||
# Creates the web server according to the configuration.
|
||||
webServer = new $WebServer()
|
||||
webServer.listen options for options in $nconf.get 'http:listen'
|
||||
|
||||
# Static file serving (e.g. for XO-Web).
|
||||
connect = $connect()
|
||||
.use $connect.static "#{__dirname}/../public/http"
|
||||
webServer.on 'request', connect for webServer in webServers
|
||||
for urlPath, filePaths of $nconf.get 'http:mounts'
|
||||
filePaths = [filePaths] unless $_.isArray filePaths
|
||||
for filePath in filePaths
|
||||
connect.use urlPath, $connect.static filePath
|
||||
webServer.on 'request', connect
|
||||
|
||||
# Creates the API.
|
||||
api = new $API xo
|
||||
|
||||
# JSON-RPC over WebSocket.
|
||||
for webServer in webServers
|
||||
new $WSServer({
|
||||
server: webServer
|
||||
path: '/api/'
|
||||
}).on 'connection', (socket) ->
|
||||
# Binds a session to this connection.
|
||||
session = new $Session xo
|
||||
session.once 'close', -> socket.close()
|
||||
socket.once 'close', -> session.close()
|
||||
# # JSON-RPC over WebSocket.
|
||||
new $WSServer({
|
||||
server: webServer
|
||||
path: '/api/'
|
||||
}).on 'connection', (socket) ->
|
||||
# Binds a session to this connection.
|
||||
session = new $Session xo
|
||||
session.once 'close', -> socket.close()
|
||||
socket.once 'close', -> session.close()
|
||||
|
||||
# Handles each request in a separate fiber.
|
||||
socket.on 'message', $fiberize (request) ->
|
||||
response = $handleJsonRpcCall api, session, request
|
||||
# Handles each request in a separate fiber.
|
||||
socket.on 'message', $fiberize (request) ->
|
||||
response = $handleJsonRpcCall api, session, request
|
||||
|
||||
# The socket may have closed beetween the request and the
|
||||
# response.
|
||||
socket.send response if socket.readyState is socket.OPEN
|
||||
# The socket may have closed beetween the request and the
|
||||
# response.
|
||||
socket.send response if socket.readyState is socket.OPEN
|
||||
|
85
src/web-server.coffee
Normal file
85
src/web-server.coffee
Normal file
@ -0,0 +1,85 @@
|
||||
# Events handling.
|
||||
{EventEmitter: $EventEmitter} = require 'events'
|
||||
|
||||
# File handling.
|
||||
$fs = require 'fs'
|
||||
|
||||
# HTTP(S) handling.
|
||||
$http = require 'http'
|
||||
$https = require 'https'
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
# Low level tools.
|
||||
$_ = require 'underscore'
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
# Helpers for dealing with fibers.
|
||||
{$sleep, $synchronize} = require './fibers-utils'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
# Events which may be emitted by a `http(s).Server`
|
||||
$events = [
|
||||
'checkContinue'
|
||||
'clientError'
|
||||
'close'
|
||||
'connect'
|
||||
'connection'
|
||||
'error'
|
||||
'request'
|
||||
'upgrade'
|
||||
]
|
||||
|
||||
$readFile = $synchronize 'readFile', $fs
|
||||
|
||||
#=====================================================================
|
||||
|
||||
# HTTP/HTTPS server which can listen on multiple address/ports or
|
||||
# sockets.
|
||||
class $WebServer extends $EventEmitter
|
||||
|
||||
constructor: ->
|
||||
@_servers = []
|
||||
|
||||
close: ->
|
||||
server.close() for server in @_servers
|
||||
|
||||
# Does not return anything.
|
||||
|
||||
listen: ({host, port, socket, certificate, key}) ->
|
||||
server = if certificate? and key?
|
||||
$https.createServer {
|
||||
cert: $readFile certificate
|
||||
key: $readFile key
|
||||
}
|
||||
else
|
||||
$http.createServer()
|
||||
@_servers.push server
|
||||
|
||||
# Makes it start listening.
|
||||
if socket?
|
||||
server.listen socket
|
||||
else
|
||||
server.listen port, host
|
||||
|
||||
# Helpful message.
|
||||
server.once 'listening', ->
|
||||
address = server.address()
|
||||
if $_.isObject address
|
||||
{address, port} = address
|
||||
address = "#{address}:#{port}"
|
||||
|
||||
console.log "WebServer listening on #{address}"
|
||||
|
||||
# Forwards events to this object.
|
||||
$_.each $events, (event) =>
|
||||
server.on event, (args...) => @emit event, args...
|
||||
|
||||
# Does not return anything.
|
||||
undefined
|
||||
|
||||
#=====================================================================
|
||||
|
||||
module.exports = $WebServer
|
Loading…
Reference in New Issue
Block a user