@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Improve Aphlict server

Summary:
- Move to port 22280 by default.
- Warn when running as non-root.
- Allow subscription and publish/admin ports to be configured.
- Allow server to drop root after binding to 843.
- Allow log path to be configured.
- Add /status/ admin URI which shows server status.
- Return HTTP 400 Bad Request for other requests, instead of hanging.
- Minor formatting cleanup.

Test Plan:
Ran without root:

$ node aphlict_server.js

...got a good error message. Ran with --user:

$ sudo node aphlict_server.js --user=epriestley

...verified server dropped permissions. Ran with --port / --admin. Hit /status/ with GET, got status. Hit other URLs with GET, got 400.

Reviewers: allenjohnashton, ddfisher, keebuhm

Reviewed By: ddfisher

CC: aran

Differential Revision: https://secure.phabricator.com/D2737

+91 -13
+1 -1
src/__celerity_resource_map__.php
··· 737 737 ), 738 738 'javelin-aphlict' => 739 739 array( 740 - 'uri' => '/res/50cae715/rsrc/js/application/aphlict/Aphlict.js', 740 + 'uri' => '/res/c0b9e53f/rsrc/js/application/aphlict/Aphlict.js', 741 741 'type' => 'js', 742 742 'requires' => 743 743 array(
+1 -1
src/applications/notifications/controller/PhabricatorAphlictTestPageController.php
··· 39 39 array( 40 40 'id' => $object_id, 41 41 'server' => '127.0.0.1', 42 - 'port' => 2600, 42 + 'port' => 22280, 43 43 )); 44 44 45 45 return $this->buildStandardPageResponse(
+1 -1
src/view/page/PhabricatorStandardPageView.php
··· 397 397 array( 398 398 'id' => $aphlict_object_id, 399 399 'server' => $server_domain, 400 - 'port' => 2600, 400 + 'port' => 22280, 401 401 'pageObjects' => $this->pageObjects, 402 402 )); 403 403
+87 -9
support/aphlict/server/aphlict_server.js
··· 1 + /** 2 + * Notification server. Launch with: 3 + * 4 + * sudo node aphlict_server.js --user=aphlict 5 + * 6 + * You can also specify `port`, `admin` and `log`. 7 + */ 8 + 9 + var config = parse_command_line_arguments(process.argv); 10 + 11 + function parse_command_line_arguments(argv) { 12 + var config = { 13 + port : 22280, 14 + admin : 22281, 15 + user : null, 16 + log: '/var/log/aphlict.log' 17 + }; 18 + 19 + for (var ii = 2; ii < argv.length; ii++) { 20 + var arg = argv[ii]; 21 + var matches = arg.match(/^--([^=]+)=(.*)$/); 22 + if (!matches) { 23 + throw new Error("Unknown argument '"+arg+"'!"); 24 + } 25 + if (!(matches[1] in config)) { 26 + throw new Error("Unknown argument '"+matches[1]+"'!"); 27 + } 28 + config[matches[1]] = matches[2]; 29 + } 30 + 31 + config.port = parseInt(config.port, 10); 32 + config.admin = parseInt(config.admin, 10); 33 + 34 + return config; 35 + } 36 + 37 + if (process.getuid() != 0) { 38 + console.log( 39 + "ERROR: "+ 40 + "This server must be run as root because it needs to bind to privileged "+ 41 + "port 843 to start a Flash policy server. It will downgrade to run as a "+ 42 + "less-privileged user after binding if you pass a user in the command "+ 43 + "line arguments with '--user=alincoln'."); 44 + process.exit(1); 45 + } 46 + 1 47 var net = require('net'); 2 48 var http = require('http'); 3 49 var url = require('url'); ··· 5 51 var fs = require('fs'); 6 52 7 53 // set up log file 8 - logfile = fs.createWriteStream('/var/log/aphlict.log', 54 + var logfile = fs.createWriteStream(config.log, 9 55 { flags: 'a', 10 56 encoding: null, 11 57 mode: 0666 }); ··· 23 69 '<!DOCTYPE cross-domain-policy SYSTEM ' + 24 70 '"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">', 25 71 '<cross-domain-policy>', 26 - '<allow-access-from domain="*" to-ports="2600"/>', 72 + '<allow-access-from domain="*" to-ports="'+config.port+'"/>', 27 73 '</cross-domain-policy>' 28 74 ].join('\n'); 29 75 } ··· 97 143 }); 98 144 99 145 socket.on('error', function (e) { 100 - console.log('Uncaught error in send server: ' + e); 146 + log('Uncaught error in send server: ' + e); 101 147 }); 102 - }).listen(2600); 148 + }).listen(config.port); 103 149 104 150 151 + var messages_out = 0; 152 + var messages_in = 0; 153 + var start_time = new Date().getTime(); 105 154 106 155 var receive_server = http.createServer(function(request, response) { 107 156 response.writeHead(200, {'Content-Type' : 'text/plain'}); 108 157 109 - if (request.method == 'POST') { // Only pay attention to POST requests 158 + // Publishing a notification. 159 + if (request.method == 'POST') { 110 160 var body = ''; 111 161 112 162 request.on('data', function (data) { ··· 114 164 }); 115 165 116 166 request.on('end', function () { 167 + ++messages_in; 168 + 117 169 var data = querystring.parse(body); 118 170 log('notification: ' + JSON.stringify(data)); 119 171 broadcast(data); 120 172 response.end(); 121 173 }); 174 + } else if (request.url == '/status/') { 175 + request.on('end', function() { 176 + var status = { 177 + 'uptime': (new Date().getTime() - start_time), 178 + 'clients.active': current_connections, 179 + 'clients.total': generate_id.current_id || 0, 180 + 'messages.in': messages_in, 181 + 'messages.out': messages_out, 182 + 'log': config.log 183 + }; 184 + 185 + response.write(JSON.stringify(status)); 186 + response.end(); 187 + }); 188 + } else { 189 + response.statusCode = 400; 190 + response.write('400 Bad Request'); 191 + response.end(); 122 192 } 123 - }).listen(22281, '127.0.0.1'); 193 + 194 + }).listen(config.admin, '127.0.0.1'); 124 195 125 196 function broadcast(data) { 126 - for(var client_id in clients) { 197 + for (var client_id in clients) { 127 198 try { 128 199 write_json(clients[client_id], data); 129 - log(' wrote to client ' + client_id); 200 + ++messages_out; 201 + log('wrote to client ' + client_id); 130 202 } catch (error) { 131 203 delete clients[client_id]; 132 204 current_connections--; 133 - log(' ERROR: could not write to client ' + client_id); 205 + log('ERROR: could not write to client ' + client_id); 134 206 } 135 207 } 136 208 } 137 209 210 + // If we're configured to drop permissions, get rid of them now that we've 211 + // bound to the ports we need and opened logfiles. 212 + if (config.user) { 213 + process.setuid(config.user); 214 + } 215 +
+1 -1
webroot/rsrc/js/application/aphlict/Aphlict.js
··· 7 7 /** 8 8 * Simple JS API for the Flash Aphlict client. Example usage: 9 9 * 10 - * var aphlict = new JX.Aphlict('aphlict_swf', '127.0.0.1', 2600) 10 + * var aphlict = new JX.Aphlict('aphlict_swf', '127.0.0.1', 22280) 11 11 * .setHandler(function(type, message) { 12 12 * JX.log("Got " + type + " event!") 13 13 * })