You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
5.9 KiB

  1. <?php
  2. require __DIR__ . '/vendor/autoload.php';
  3. define('DOCUMENT_ROOT', dirname(__FILE__));
  4. require_once(DOCUMENT_ROOT.'/bootstrap.php');
  5. gc_enable();
  6. $bootstrap = new Bootstrap();
  7. $booted = $bootstrap->boot();
  8. $loop = React\EventLoop\Factory::create();
  9. $dnsResolverFactory = new React\Dns\Resolver\Factory();
  10. $dns = $dnsResolverFactory->createCached('8.8.8.8', $loop);
  11. $connector = new React\SocketClient\Connector($loop, $dns);
  12. $stdin = new React\Stream\Stream(STDIN, $loop);
  13. fwrite(STDERR, colorize(getenv('sid'), 'yellow')." widgets before : ".\sizeToCleanSize(memory_get_usage())."\n");
  14. // We load and register all the widgets
  15. $wrapper = WidgetWrapper::getInstance();
  16. $wrapper->registerAll(true);
  17. fwrite(STDERR, colorize(getenv('sid'), 'yellow')." widgets : ".\sizeToCleanSize(memory_get_usage())."\n");
  18. $conn = null;
  19. $parser = new \Moxl\Parser;
  20. $buffer = '';
  21. $stdin_behaviour = function ($data) use (&$conn, $loop, &$buffer, &$connector, &$xmpp_behaviour, &$parser) {
  22. if(substr($data, -1) == "") {
  23. $messages = explode("", $buffer . substr($data, 0, -1));
  24. $buffer = '';
  25. foreach ($messages as $message) {
  26. #fwrite(STDERR, colorize($message, 'yellow')." : ".colorize('received from the browser', 'green')."\n");
  27. $msg = json_decode($message);
  28. if(isset($msg)) {
  29. if($msg->func == 'message' && $msg->body != '') {
  30. $msg = $msg->body;
  31. } elseif($msg->func == 'unregister') {
  32. \Moxl\Stanza\Stream::end();
  33. } elseif($msg->func == 'register') {
  34. $cd = new \Modl\ConfigDAO();
  35. $config = $cd->get();
  36. $domain = \Moxl\Utils::getDomain($msg->host);
  37. #fwrite(STDERR, colorize('open a socket to '.$domain, 'yellow')." : ".colorize('sent to XMPP', 'green')."\n");
  38. $connector->create($domain, 5222)->then($xmpp_behaviour);
  39. }
  40. } else {
  41. return;
  42. }
  43. $rpc = new \RPC();
  44. $rpc->handle_json($msg);
  45. $msg = json_encode(\RPC::commit());
  46. \RPC::clear();
  47. if(!empty($msg)) {
  48. echo base64_encode(gzcompress($msg, 9))."";
  49. #fwrite(STDERR, colorize($msg, 'yellow')." : ".colorize('sent to the browser', 'green')."\n");
  50. }
  51. $xml = \Moxl\API::commit();
  52. \Moxl\API::clear();
  53. $loop->tick();
  54. if(!empty($xml) && $conn) {
  55. $conn->write(trim($xml));
  56. fwrite(STDERR, colorize(trim($xml), 'yellow')." : ".colorize('sent to XMPP', 'green')."\n");
  57. }
  58. }
  59. } else {
  60. $buffer .= $data;
  61. }
  62. $loop->tick();
  63. };
  64. $xmpp_behaviour = function (React\Stream\Stream $stream) use (&$conn, $loop, &$stdin, $stdin_behaviour, $parser) {
  65. $conn = $stream;
  66. fwrite(STDERR, colorize(getenv('sid'), 'yellow')." : ".colorize('linker launched', 'blue')."\n");
  67. fwrite(STDERR, colorize(getenv('sid'), 'yellow')." launched : ".\sizeToCleanSize(memory_get_usage())."\n");
  68. $stdin->removeAllListeners('data');
  69. $stdin->on('data', $stdin_behaviour);
  70. // We define a huge buffer to prevent issues with SSL streams, see https://bugs.php.net/bug.php?id=65137
  71. $conn->bufferSize = 1024*32;
  72. $conn->on('data', function($message) use (&$conn, $loop, $parser) {
  73. if(!empty($message)) {
  74. $restart = false;
  75. if($message == '</stream:stream>') {
  76. $conn->close();
  77. $loop->stop();
  78. } elseif($message == "<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"
  79. || $message == '<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>') {
  80. stream_set_blocking($conn->stream, 1);
  81. $out = stream_socket_enable_crypto($conn->stream, 1, STREAM_CRYPTO_METHOD_TLS_CLIENT);
  82. stream_set_blocking($conn->stream, 0);
  83. $restart = true;
  84. }
  85. fwrite(STDERR, colorize($message, 'yellow')." : ".colorize('received', 'green')."\n");
  86. #fwrite(STDERR, colorize(getenv('sid'), 'yellow')." widgets : ".\sizeToCleanSize(memory_get_usage())."\n");
  87. \Moxl\API::clear();
  88. \RPC::clear();
  89. if(!$parser->parse($message)) {
  90. fwrite(STDERR, colorize(getenv('sid'), 'yellow')." ".$parser->getError()."\n");
  91. }
  92. if($restart) {
  93. $session = \Sessionx::start();
  94. \Moxl\Stanza\Stream::init($session->host);
  95. $restart = false;
  96. }
  97. $msg = \RPC::commit();
  98. \RPC::clear();
  99. if(!empty($msg)) {
  100. echo base64_encode(gzcompress(json_encode($msg), 9))."";
  101. #fwrite(STDERR, colorize($msg.' '.strlen($msg), 'yellow')." : ".colorize('sent to browser', 'green')."\n");
  102. }
  103. $xml = \Moxl\API::commit();
  104. \Moxl\API::clear();
  105. if(!empty($xml)) {
  106. $conn->write(trim($xml));
  107. fwrite(STDERR, colorize(trim($xml), 'yellow')." : ".colorize('sent to XMPP', 'green')."\n");
  108. }
  109. }
  110. $loop->tick();
  111. });
  112. $conn->on('error', function($msg) use ($conn, $loop) {
  113. #fwrite(STDERR, colorize(serialize($msg), 'red')." : ".colorize('error', 'green')."\n");
  114. $loop->stop();
  115. });
  116. $conn->on('close', function($msg) use ($conn, $loop) {
  117. #fwrite(STDERR, colorize(serialize($msg), 'red')." : ".colorize('closed', 'green')."\n");
  118. $loop->stop();
  119. });
  120. // And we say that we are ready !
  121. $obj = new \StdClass;
  122. $obj->func = 'registered';
  123. echo base64_encode(gzcompress(json_encode($obj), 9))."";
  124. };
  125. $stdin->on('data', $stdin_behaviour);
  126. $stdin->on('error', function() use($loop) { $loop->stop(); } );
  127. $stdin->on('close', function() use($loop) { $loop->stop(); } );
  128. $loop->run();