fixed 0000013
[JIRC.git] / JIRC.js
CommitLineData
39c8b14f 1#!/usr/bin/env node
2
3//growl('5 new emails', { title: 'Email Client' });
4//process.exit(0);
5var argv = require('optimist').argv, bindhost="127.0.0.1", bindport="10080";
6if(argv.h || argv.help){
7 console.log('usage: '+argv.$0+' [options] [bind-host]');
8 console.log('');
9 console.log('Options:');
10 console.log('-q be quiet');
11 console.log('-v verbose logging');
12 process.exit(0);
13}
14if(argv._[0]){
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];
18 } else {
19 console.error('Error: bind-host must be in the format [IP]:[PORT]');
20 process.exit(0);
21 }
22}
23
24require('./lib/IRC.js');
25global.argv=argv;
26global.irc.loadScripts();
27global.settings = '';
28global.resume = '';
29
30var http = require('http'),
31 WebSocketRequest = require('websocket').request,
32 ws = require('websocket-server'),
33 url = require('url'),
34 fs = require('fs'),
35 static = require('node-static'),
36 file = new(static.Server)('./public', { cache: 7200, headers: {'X-Hello':'World!'} }),
37 httpServer = http.createServer(function(request, response) {
38 var queryData = "";
39 request.on('data', function(data) {
40 var path = url.parse(request.url).pathname;
41 if(path=="/resume"){
42 queryData += data;
43 if(queryData.length > 1e6) {
44 queryData = "";
45 response.writeHead(413, {'Content-Type': 'text/plain'});
46 request.connection.destroy();
47 }
48 } else if(path=="/settings"){
49 queryData += data;
50 if(queryData.length > 1e6) {
51 queryData = "";
52 response.writeHead(413, {'Content-Type': 'text/plain'});
53 request.connection.destroy();
54 }
55 }
56 });
57
58 request.addListener('end', function () {
59 var path = url.parse(request.url).pathname;
60 if(path=="/emoticons"){
61 var emoticons = fs.readFileSync(
62 __dirname + '/public/images/emoticons/Emoticons.plist', 'utf8'
63 );
64 response.writeHead(200, {"Content-Type": "application/xml"});
65 response.end(emoticons);
66 } else if(path=="/resume"){
67 response.writeHead(200, {"Content-Type": "application/json"});
68 response.end(JSON.stringify(global.resume));
69 if(queryData) {
70 global.resume=JSON.parse(queryData);
71 }
72 } else if(path=="/settings"){
73 response.writeHead(200, {"Content-Type": "application/json"});
74 response.end(JSON.stringify(global.settings));
75 if(queryData) {
76 global.settings=JSON.parse(queryData);
77 }
78 } else{
79 file.serve(request, response, function (err, res) {
80 if (err) {
81 console.error((new Date()) + " > Error serving " + request.url + " - " + err.message);
82 response.writeHead(err.status, err.headers);
83 response.end();
84 } else {
85 if(argv.v) console.log((new Date()) + " > " + request.url + " - " + res.message);
86 }
87 });
88 }
89 });
90 });
91httpServer.listen(bindport, bindhost, function() {
92 if(!argv.q) console.log((new Date()) + " Server is listening on " + bindhost + ":" + bindport);
93});
94
95// node-websocket-server
96var miksagoConnection = require('./node_modules/websocket-server/lib/ws/connection');
97var miksagoServer = ws.createServer();
98miksagoServer.server = httpServer;
99miksagoServer.addListener('connection', function(connection) {
100 connection.remoteAddress = connection._socket.remoteAddress;
101 connection.sendUTF = connection.send;
102 handleConnection(connection);
103});
104
105
106// WebSocket-Node config
107
108var wsServerConfig = {
109 // All options *except* 'httpServer' are required when bypassing
110 // WebSocketServer.
111 maxReceivedFrameSize: 0x10000,
112 maxReceivedMessageSize: 0x100000,
113 fragmentOutgoingMessages: true,
114 fragmentationThreshold: 0x4000,
115 keepalive: true,
116 keepaliveInterval: 20000,
117 assembleFragments: true,
118 // autoAcceptConnections is not applicable when bypassing WebSocketServer
119 // autoAcceptConnections: false,
120 disableNagleAlgorithm: true,
121 closeTimeout: 5000
122};
123
124httpServer.on('upgrade', function(req, socket, head) {
125 if (typeof req.headers['sec-websocket-version'] !== 'undefined') {
126 // WebSocket hybi-08/-09/-10 connection (WebSocket-Node)
127 var wsRequest = new WebSocketRequest(socket, req, wsServerConfig);
128 try {
129 wsRequest.readHandshake();
130 var wsConnection = wsRequest.accept(wsRequest.requestedProtocols[0], wsRequest.origin);
131 handleConnection(wsConnection);
132 }
133 catch(e) {
134 console.log("WebSocket Request unsupported by WebSocket-Node: " + e.toString());
135 return;
136 }
137 } else {
138 // WebSocket hixie-75/-76/hybi-00 connection (node-websocket-server)
139 if (req.method === 'GET' &&
140 (req.headers.upgrade && req.headers.connection) &&
141 req.headers.upgrade.toLowerCase() === 'websocket' &&
142 req.headers.connection.toLowerCase() === 'upgrade') {
143 new miksagoConnection(miksagoServer.manager, miksagoServer.options, req, socket, head);
144 }
145 }
146});
147
148function handleConnection(connection) {
149 if(!argv.q) console.log((new Date()) + " Connection accepted.");
150 global.websocket = connection;
151 connection.addListener('message', function(wsMessage) {
152 var message = wsMessage;
153 // WebSocket-Node adds a "type", node-websocket-server does not
154 if (typeof wsMessage.type !== 'undefined') {
155 if (wsMessage.type !== 'utf8') {
156 return;
157 }
158 message = wsMessage.utf8Data;
159 }
160// console.log("Received Message: " + message);
161 if (message.match(/^CONNECT (.*)$/i)) {
162 var arrCmd = message.split(" ");
163 global.irc.connect(arrCmd[1], arrCmd[2], arrCmd[3], arrCmd[4], arrCmd[5], arrCmd[6]);
164 } else{
165 global.irc.send(message);
166 }
167 });
168
169 connection.addListener('close', function() {
170 if(!argv.q) console.log((new Date()) + " Peer " + connection.remoteAddress + " disconnected.");
171 if(!global.resume || global.settings.hold != "on") {
172 global.irc.quit('BYE BYE');
173 if(!argv.q) console.log((new Date()) + " Disconnected from IRC");
174 }
175 });
176
177}
178if(!argv.n) require("openurl").open("http://" + bindhost + ":" + bindport);