File: /var/www/html/digisferach.sumar.com.py/wp-content/plugins/peepso/sse.php
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('X-Accel-Buffering: no');
header("Connection: Keep-Alive");
header("Keep-Alive: timeout=300");
ini_set('display_errors', 1);
ini_set('error_reporting', E_ALL);
class PeepSoSSE {
private $dir = '../../peepso/sse/'; // wp-content/peepso/sse/
private $user_id = 0;
private $delay = 5000; // miliseconds
private $timeout = 30000; // miliseconds
private $keepalive = 0; // every N loop(s)
private $iterations = 0; // internal iteration count
private $token = NULL; // admin-ajax.php?action=peepso_sse_token
private $events_dir = NULL; // directory to monitor
private $token_expiry = 24 * 60 * 60; // delete token dir after N seconds
private $event_id = 1; // event count is unique to the user_id/token pair
private $event_id_file = ''; // path to file that caches the last event id in case of reconnect
public function __construct() {
$this->user_id = isset($_REQUEST['user_id']) ? intval($_REQUEST['user_id']) : $this->user_id ;
$this->timeout = isset($_REQUEST['timeout']) ? intval($_REQUEST['timeout']) : $this->timeout ;
$this->delay = isset($_REQUEST['delay']) ? intval($_REQUEST['delay']) : $this->delay ;
$this->keepalive = isset($_REQUEST['keepalive']) ? intval($_REQUEST['keepalive']): $this->keepalive ;
$this->token = isset($_REQUEST['token']) ? intval($_REQUEST['token']) : $this->token ;
// invalid user id?
if(!$this->user_id) {
$this->send('error_invalid_user_id');
die();
}
// detect symlinked plugin
if (isset($_SERVER['SCRIPT_FILENAME'])) {
$basedir = dirname($_SERVER['SCRIPT_FILENAME']);
if ($basedir !== dirname(__FILE__)) {
$this->dir = preg_replace('/(\/[^\/]+){2}$/', '/peepso/sse/', $basedir);
}
}
$this->events_dir = $this->dir.'events/'.$this->user_id.'/'.$this->token.'/';
// token is a timestamp with 10000 - 99999 glued to it - expire it after {token_expiry} seconds
if( file_exists($this->events_dir) && time() - substr($this->token, 0, 10) >= $this->token_expiry) {
$events = scandir($this->events_dir);
if(is_array($events) && count($events)) {
foreach($events as $event) {
@unlink($event);
}
}
@rmdir($this->events_dir);
}
// assume that token has expired if the directory does not exist
if(!file_exists($this->events_dir)) {
$this->send('error_invalid_token');
die();
}
// last succesful event id
$this->event_id_file = $this->events_dir.'last_event_id';
if(file_exists($this->event_id_file)) {
$h = fopen($this->event_id_file, 'r');
$this->event_id = fread($h, filesize($this->event_id_file));
$this->event_id++;
}
/**
* Primary loop. Infinite but with built in self-termination based on config;
*/
$this->send(
'debug_start',
array(
'user_id'=>$this->user_id,
'delay'=>$this->delay,
'timeout'=>$this->timeout,
'keepalive'=>$this->keepalive,
'max_execution_time' => ini_get('max_execution_time'),
)
);
while (1) {
$this->iterations++;
if ($data = $this->check()) {
foreach($data as $event) {
$this->send($event);
}
} elseif($this->keepalive>0 && !($this->iterations%$this->keepalive)) {
$this->send('keepalive');
}
if($this->timeout > 0 && $this->iterations*$this->delay >= $this->timeout ){
$this->send('timeout');
die();
}
if (connection_aborted()) { die(); };
sleep(intval($this->delay/1000));
}
}
private function check()
{
$response = array();
$events = scandir($this->events_dir);
if(is_array($events) && count($events)) {
foreach ($events as $event) {
if(in_array($event, array('.','..','last_event_id'))) {
continue;
}
$response[] = $event;
unlink($this->events_dir.$event);
}
}
return $response;
}
/**
* Sends a message to buffer
*
* @param string $event name of the event
* @param array $payload optional array of data to send along with the event
*/
private function send($event, $payload = NULL)
{
$event = array(
'event' => $event,
'event_id' => $this->event_id,
);
if ($payload) {
$event['payload'] = $payload;
}
// cache the event_id and increment
if($this->user_id && $this->event_id_file!='') {
$h = @fopen($this->event_id_file, 'w');
@fwrite($h, $this->event_id);
}
$this->event_id++;
// send to buffer
echo 'data: ' . json_encode($event) . PHP_EOL . PHP_EOL; // two newlines are required
// flush the crap out of it
while (ob_get_level() > 0) {
@ob_end_flush();
}
@ob_end_flush();
@flush();
}
}
$sse = new PeepSoSSE();
// EOF