3 //growl('5 new emails', { title: 'Email Client' });
5 var argv
= require('optimist').argv
, bindhost
="127.0.0.1", bindport
="10080";
6 if(argv
.h
|| argv
.help
){
7 console
.log('usage: '+argv
.$0+' [options] [bind-host]');
9 console
.log('Options:');
10 console
.log('-q be quiet');
11 console
.log('-v verbose logging');
15 if(argv
._
[0].match(/^\d+\.\d+\.\d+\.\d+\:[0-9]{1,5}$/)){
16 bindhost
=argv
._
[0].split(":")[0];
17 bindport
=argv
._
[0].split(":")[1];
19 console
.error('Error: bind-host must be in the format [IP]:[PORT]');
24 require('./lib/IRC.js');
26 global
.irc
.loadScripts();
30 var pf
= require('policyfile').createServer()
33 var http
= require('http'),
34 WebSocketRequest
= require('websocket').request
,
35 ws
= require('websocket-server'),
38 static = require('node-static'),
39 file
= new(static.Server
)('./public', { cache
: 7200, headers
: {'X-Hello':'World!'} }),
40 httpServer
= http
.createServer(function(request
, response
) {
42 request
.on('data', function(data
) {
43 var path
= url
.parse(request
.url
).pathname
;
46 if(queryData
.length
> 1e6
) {
48 response
.writeHead(413, {'Content-Type': 'text/plain'});
49 request
.connection
.destroy();
51 } else if(path
=="/settings"){
53 if(queryData
.length
> 1e6
) {
55 response
.writeHead(413, {'Content-Type': 'text/plain'});
56 request
.connection
.destroy();
61 request
.addListener('end', function () {
62 var path
= url
.parse(request
.url
).pathname
;
63 if(path
=="/emoticons"){
64 var emoticons
= fs
.readFileSync(
65 __dirname
+ '/public/images/emoticons/Emoticons.plist', 'utf8'
67 response
.writeHead(200, {"Content-Type": "application/xml"});
68 response
.end(emoticons
);
69 } else if(path
=="/resume"){
70 response
.writeHead(200, {"Content-Type": "application/json"});
71 response
.end(JSON
.stringify(global
.resume
));
73 global
.resume
=JSON
.parse(queryData
);
75 } else if(path
=="/settings"){
76 response
.writeHead(200, {"Content-Type": "application/json"});
77 response
.end(JSON
.stringify(global
.settings
));
79 global
.settings
=JSON
.parse(queryData
);
82 file
.serve(request
, response
, function (err
, res
) {
84 console
.error((new Date()) + " > Error serving " + request
.url
+ " - " + err
.message
);
85 response
.writeHead(err
.status
, err
.headers
);
88 if(argv
.v
) console
.log((new Date()) + " > " + request
.url
+ " - " + res
.message
);
94 httpServer
.listen(bindport
, bindhost
, function() {
95 if(!argv
.q
) console
.log((new Date()) + " Server is listening on " + bindhost
+ ":" + bindport
);
98 // node-websocket-server
99 var miksagoConnection
= require('./node_modules/websocket-server/lib/ws/connection');
100 var miksagoServer
= ws
.createServer();
101 miksagoServer
.server
= httpServer
;
102 miksagoServer
.addListener('connection', function(connection
) {
103 connection
.remoteAddress
= connection
._socket
.remoteAddress
;
104 connection
.sendUTF
= connection
.send
;
105 handleConnection(connection
);
109 // WebSocket-Node config
111 var wsServerConfig
= {
112 // All options *except* 'httpServer' are required when bypassing
114 maxReceivedFrameSize
: 0x10000,
115 maxReceivedMessageSize
: 0x100000,
116 fragmentOutgoingMessages
: true,
117 fragmentationThreshold
: 0x4000,
119 keepaliveInterval
: 20000,
120 assembleFragments
: true,
121 // autoAcceptConnections is not applicable when bypassing WebSocketServer
122 // autoAcceptConnections: false,
123 disableNagleAlgorithm
: true,
127 httpServer
.on('upgrade', function(req
, socket
, head
) {
128 if (typeof req
.headers
['sec-websocket-version'] !== 'undefined') {
129 // WebSocket hybi-08/-09/-10 connection (WebSocket-Node)
130 var wsRequest
= new WebSocketRequest(socket
, req
, wsServerConfig
);
132 wsRequest
.readHandshake();
133 var wsConnection
= wsRequest
.accept(wsRequest
.requestedProtocols
[0], wsRequest
.origin
);
134 handleConnection(wsConnection
);
137 console
.log("WebSocket Request unsupported by WebSocket-Node: " + e
.toString());
141 // WebSocket hixie-75/-76/hybi-00 connection (node-websocket-server)
142 if (req
.method
=== 'GET' &&
143 (req
.headers
.upgrade
&& req
.headers
.connection
) &&
144 req
.headers
.upgrade
.toLowerCase() === 'websocket' &&
145 req
.headers
.connection
.toLowerCase() === 'upgrade') {
146 new miksagoConnection(miksagoServer
.manager
, miksagoServer
.options
, req
, socket
, head
);
151 function handleConnection(connection
) {
152 if(!argv
.q
) console
.log((new Date()) + " Connection accepted.");
153 global
.websocket
= connection
;
154 connection
.addListener('message', function(wsMessage
) {
155 var message
= wsMessage
;
156 // WebSocket-Node adds a "type", node-websocket-server does not
157 if (typeof wsMessage
.type
!== 'undefined') {
158 if (wsMessage
.type
!== 'utf8') {
161 message
= wsMessage
.utf8Data
;
163 // console.log("Received Message: " + message);
164 if (message
.match(/^CONNECT (.*)$/i)) {
165 var arrCmd
= message
.split(" ");
166 global
.irc
.connect(arrCmd
[1], arrCmd
[2], arrCmd
[3], arrCmd
[4], arrCmd
[5], arrCmd
[6]);
168 global
.irc
.send(message
);
172 connection
.addListener('close', function() {
173 if(!argv
.q
) console
.log((new Date()) + " Peer " + connection
.remoteAddress
+ " disconnected.");
174 if(!global
.resume
|| global
.settings
.hold
!= "on") {
175 global
.irc
.quit('BYE BYE');
176 if(!argv
.q
) console
.log((new Date()) + " Disconnected from IRC");
181 if(!argv
.n
) require("openurl").open("http://" + bindhost
+ ":" + bindport
);