fixed 0000022
[JIRC.git] / JIRC.js
1 #!/usr/bin/env node
2
3 //growl('5 new emails', { title: 'Email Client' });
4 //process.exit(0);
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]');
8 console.log('');
9 console.log('Options:');
10 console.log('-q be quiet');
11 console.log('-v verbose logging');
12 process.exit(0);
13 }
14 if(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
24 require('./lib/IRC.js');
25 global.argv=argv;
26 global.irc.loadScripts();
27 global.settings = '';
28 global.resume = '';
29
30 var pf = require('policyfile').createServer()
31 pf.listen(8002);
32
33 var http = require('http'),
34 WebSocketRequest = require('websocket').request,
35 ws = require('websocket-server'),
36 url = require('url'),
37 fs = require('fs'),
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) {
42 var queryData = "";
43 request.on('data', function(data) {
44 var path = url.parse(request.url).pathname;
45 if(path=="/youtube"){
46 queryData += data;
47 if(queryData.length > 1e6) {
48 response.writeHead(413, {'Content-Type': 'text/plain'});
49 request.connection.destroy();
50 }
51 }
52 if(path=="/resume"){
53 queryData += data;
54 if(queryData.length > 1e6) {
55 queryData = "";
56 response.writeHead(413, {'Content-Type': 'text/plain'});
57 request.connection.destroy();
58 }
59 } else if(path=="/settings"){
60 queryData += data;
61 if(queryData.length > 1e6) {
62 queryData = "";
63 response.writeHead(413, {'Content-Type': 'text/plain'});
64 request.connection.destroy();
65 }
66 }
67 });
68
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'
74 );
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));
80 if(queryData) {
81 global.resume=JSON.parse(queryData);
82 }
83 } else if(path=="/settings"){
84 response.writeHead(200, {"Content-Type": "application/json"});
85 response.end(JSON.stringify(global.settings));
86 if(queryData) {
87 console.log(queryData);
88 global.settings=JSON.parse(queryData);
89 }
90 } else{
91 file.serve(request, response, function (err, res) {
92 if (err) {
93 console.error((new Date()) + " > Error serving " + request.url + " - " + err.message);
94 response.writeHead(err.status, err.headers);
95 response.end();
96 } else {
97 if(argv.v) console.log((new Date()) + " > " + request.url + " - " + res.message);
98 }
99 });
100 }
101 });
102 });
103 httpServer.listen(bindport, bindhost, function() {
104 if(!argv.q) console.log((new Date()) + " Server is listening on " + bindhost + ":" + bindport);
105 });
106
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);
115 });
116
117
118 // WebSocket-Node config
119
120 var wsServerConfig = {
121 // All options *except* 'httpServer' are required when bypassing
122 // WebSocketServer.
123 maxReceivedFrameSize: 0x10000,
124 maxReceivedMessageSize: 0x100000,
125 fragmentOutgoingMessages: true,
126 fragmentationThreshold: 0x4000,
127 keepalive: true,
128 keepaliveInterval: 20000,
129 assembleFragments: true,
130 // autoAcceptConnections is not applicable when bypassing WebSocketServer
131 // autoAcceptConnections: false,
132 disableNagleAlgorithm: true,
133 closeTimeout: 5000
134 };
135
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);
140 try {
141 wsRequest.readHandshake();
142 var wsConnection = wsRequest.accept(wsRequest.requestedProtocols[0], wsRequest.origin);
143 handleConnection(wsConnection);
144 }
145 catch(e) {
146 console.log("WebSocket Request unsupported by WebSocket-Node: " + e.toString());
147 return;
148 }
149 } else {
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);
156 }
157 }
158 });
159
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') {
168 return;
169 }
170 message = wsMessage.utf8Data;
171 }
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]);
176 } else{
177 global.irc.send(message);
178 }
179 });
180
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");
186 }
187 });
188
189 }
190 if(!argv.n) require("openurl").open("http://" + bindhost + ":" + bindport);