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 getyt
= require('request'),
40 file
= new(static.Server
)('./public', { cache
: 7200, headers
: {'X-Hello':'World!'} }),
41 httpServer
= http
.createServer(function(request
, response
) {
43 request
.on('data', function(data
) {
44 var path
= url
.parse(request
.url
).pathname
;
47 if(queryData
.length
> 1e6
) {
48 response
.writeHead(413, {'Content-Type': 'text/plain'});
49 request
.connection
.destroy();
54 if(queryData
.length
> 1e6
) {
56 response
.writeHead(413, {'Content-Type': 'text/plain'});
57 request
.connection
.destroy();
59 } else if(path
=="/settings"){
61 if(queryData
.length
> 1e6
) {
63 response
.writeHead(413, {'Content-Type': 'text/plain'});
64 request
.connection
.destroy();
69 request
.addListener('end', function () {
70 var path
= url
.parse(request
.url
).pathname
;
71 if(path
=="/emoticons"){
72 var emoticons
= fs
.readFileSync(
73 __dirname
+ '/public/images/emoticons/Emoticons.plist', 'utf8'
75 response
.writeHead(200, {"Content-Type": "application/xml"});
76 response
.end(emoticons
);
77 } else if(path
=="/resume"){
78 response
.writeHead(200, {"Content-Type": "application/json"});
79 response
.end(JSON
.stringify(global
.resume
));
81 global
.resume
=JSON
.parse(queryData
);
83 } else if(path
=="/settings"){
84 response
.writeHead(200, {"Content-Type": "application/json"});
85 response
.end(JSON
.stringify(global
.settings
));
87 console
.log(queryData
);
88 global
.settings
=JSON
.parse(queryData
);
91 file
.serve(request
, response
, function (err
, res
) {
93 console
.error((new Date()) + " > Error serving " + request
.url
+ " - " + err
.message
);
94 response
.writeHead(err
.status
, err
.headers
);
97 if(argv
.v
) console
.log((new Date()) + " > " + request
.url
+ " - " + res
.message
);
103 httpServer
.listen(bindport
, bindhost
, function() {
104 if(!argv
.q
) console
.log((new Date()) + " Server is listening on " + bindhost
+ ":" + bindport
);
107 // node-websocket-server
108 var miksagoConnection
= require('./node_modules/websocket-server/lib/ws/connection');
109 var miksagoServer
= ws
.createServer();
110 miksagoServer
.server
= httpServer
;
111 miksagoServer
.addListener('connection', function(connection
) {
112 connection
.remoteAddress
= connection
._socket
.remoteAddress
;
113 connection
.sendUTF
= connection
.send
;
114 handleConnection(connection
);
118 // WebSocket-Node config
120 var wsServerConfig
= {
121 // All options *except* 'httpServer' are required when bypassing
123 maxReceivedFrameSize
: 0x10000,
124 maxReceivedMessageSize
: 0x100000,
125 fragmentOutgoingMessages
: true,
126 fragmentationThreshold
: 0x4000,
128 keepaliveInterval
: 20000,
129 assembleFragments
: true,
130 // autoAcceptConnections is not applicable when bypassing WebSocketServer
131 // autoAcceptConnections: false,
132 disableNagleAlgorithm
: true,
136 httpServer
.on('upgrade', function(req
, socket
, head
) {
137 if (typeof req
.headers
['sec-websocket-version'] !== 'undefined') {
138 // WebSocket hybi-08/-09/-10 connection (WebSocket-Node)
139 var wsRequest
= new WebSocketRequest(socket
, req
, wsServerConfig
);
141 wsRequest
.readHandshake();
142 var wsConnection
= wsRequest
.accept(wsRequest
.requestedProtocols
[0], wsRequest
.origin
);
143 handleConnection(wsConnection
);
146 console
.log("WebSocket Request unsupported by WebSocket-Node: " + e
.toString());
150 // WebSocket hixie-75/-76/hybi-00 connection (node-websocket-server)
151 if (req
.method
=== 'GET' &&
152 (req
.headers
.upgrade
&& req
.headers
.connection
) &&
153 req
.headers
.upgrade
.toLowerCase() === 'websocket' &&
154 req
.headers
.connection
.toLowerCase() === 'upgrade') {
155 new miksagoConnection(miksagoServer
.manager
, miksagoServer
.options
, req
, socket
, head
);
160 function handleConnection(connection
) {
161 if(!argv
.q
) console
.log((new Date()) + " Connection accepted.");
162 global
.websocket
= connection
;
163 connection
.addListener('message', function(wsMessage
) {
164 var message
= wsMessage
;
165 // WebSocket-Node adds a "type", node-websocket-server does not
166 if (typeof wsMessage
.type
!== 'undefined') {
167 if (wsMessage
.type
!== 'utf8') {
170 message
= wsMessage
.utf8Data
;
172 // console.log("Received Message: " + message);
173 if (message
.match(/^CONNECT (.*)$/i)) {
174 var arrCmd
= message
.split(" ");
175 global
.irc
.connect(arrCmd
[1], arrCmd
[2], arrCmd
[3], arrCmd
[4], arrCmd
[5], arrCmd
[6]);
177 global
.irc
.send(message
);
181 connection
.addListener('close', function() {
182 if(!argv
.q
) console
.log((new Date()) + " Peer " + connection
.remoteAddress
+ " disconnected.");
183 if(!global
.resume
|| global
.settings
.hold
!= "on") {
184 global
.irc
.quit('BYE BYE');
185 if(!argv
.q
) console
.log((new Date()) + " Disconnected from IRC");
190 if(!argv
.n
) require("openurl").open("http://" + bindhost
+ ":" + bindport
);