1 var engine
= require('engine.io'),
2 WebsocketRpc
= require('./websocketrpc.js');
3 events
= require('events'),
4 http
= require('http'),
5 https
= require('https'),
6 util
= require('util'),
10 _
= require('lodash'),
11 spdy
= require('spdy'),
12 ipaddr
= require('ipaddr.js'),
13 Client
= require('./client.js').Client
,
14 HttpHandler
= require('./httphandler.js').HttpHandler
,
15 rehash
= require('./rehash.js');
19 rehash
.on('rehashed', function (files
) {
20 Client
= require('./client.js').Client
;
21 HttpHandler
= require('./httphandler.js').HttpHandler
;
25 // Instance of HttpHandler
29 var WebListener
= module
.exports = function (web_config
) {
34 events
.EventEmitter
.call(this);
36 http_handler
= new HttpHandler(web_config
);
40 key
: fs
.readFileSync(web_config
.ssl_key
),
41 cert
: fs
.readFileSync(web_config
.ssl_cert
)
44 // Do we have an intermediate certificate?
45 if (typeof web_config
.ssl_ca
!== 'undefined') {
47 if (typeof web_config
.ssl_ca
.map
!== 'undefined') {
48 opts
.ca
= web_config
.ssl_ca
.map(function (f
) { return fs
.readFileSync(f
); });
51 opts
.ca
= fs
.readFileSync(web_config
.ssl_ca
);
55 hs
= spdy
.createServer(opts
, handleHttpRequest
);
57 hs
.listen(web_config
.port
, web_config
.address
, function () {
58 that
.emit('listening');
62 // Start some plain-text server up
63 hs
= http
.createServer(handleHttpRequest
);
65 hs
.listen(web_config
.port
, web_config
.address
, function () {
66 that
.emit('listening');
70 hs
.on('error', function (err
) {
71 that
.emit('error', err
);
74 this.ws
= engine
.attach(hs
, {
75 transports
: ['websocket', 'polling', 'flashsocket'],
76 path
: (global
.config
.http_base_path
|| '') + '/transport'
79 this.ws
.on('connection', function(socket
) {
80 initialiseSocket(socket
, function(err
, authorised
) {
88 client
= new Client(socket
);
89 client
.on('dispose', function () {
90 that
.emit('client_dispose', this);
93 that
.emit('connection', client
);
95 // Call any modules listening for new clients
96 global
.modules
.emit('client created', {client
: client
});
100 util
.inherits(WebListener
, events
.EventEmitter
);
104 function handleHttpRequest(request
, response
) {
105 http_handler
.serve(request
, response
);
108 function rangeCheck(addr
, range
) {
109 var i
, ranges
, parts
;
110 ranges
= (!_
.isArray(range
)) ? [range
] : range
;
111 for (i
= 0; i
< ranges
.length
; i
++) {
112 parts
= ranges
[i
].split('/');
113 if (ipaddr
.process(addr
).match(ipaddr
.process(parts
[0]), parts
[1])) {
122 * Get the reverse DNS entry for this connection.
123 * Used later on for webirc, etc functionality
125 function initialiseSocket(socket
, callback
) {
126 var request
= socket
.request
,
127 address
= request
.connection
.remoteAddress
;
129 // Key/val data stored to the socket to be read later on
130 // May also be synced to a redis DB to lookup clients
133 // If a forwarded-for header is found, switch the source address
134 if (request
.headers
[global
.config
.http_proxy_ip_header
|| 'x-forwarded-for']) {
135 // Check we're connecting from a whitelisted proxy
136 if (!global
.config
.http_proxies
|| !rangeCheck(address
, global
.config
.http_proxies
)) {
137 console
.log('Unlisted proxy:', address
);
138 callback(null, false);
142 // We're sent from a whitelisted proxy, replace the hosts
143 address
= request
.headers
[global
.config
.http_proxy_ip_header
|| 'x-forwarded-for'];
146 socket
.meta
.real_address
= address
;
148 // If enabled, don't go over the connection limit
149 if (global
.config
.max_client_conns
&& global
.config
.max_client_conns
> 0) {
150 if (global
.clients
.numOnAddress(address
) + 1 > global
.config
.max_client_conns
) {
151 return callback(null, false);
157 dns
.reverse(address
, function (err
, domains
) {
158 if (err
|| domains
.length
=== 0) {
159 socket
.meta
.revdns
= address
;
161 socket
.meta
.revdns
= _
.first(domains
) || address
;
164 // All is well, authorise the connection
165 callback(null, true);
168 socket
.meta
.revdns
= address
;
169 callback(null, true);