]> jfr.im git - irc/unrealircd/unrealircd-webpanel.git/blob - api/common_api.php
Fix issue with @ob_end_flush() still throwing an error
[irc/unrealircd/unrealircd-webpanel.git] / api / common_api.php
1 <?php
2 include "../inc/common.php";
3
4 if(session_status() !== PHP_SESSION_ACTIVE) session_start();
5
6 if (!isset($_SESSION['id']))
7 die("Access denied");
8
9 // Close the session now, otherwise other pages block
10 session_write_close();
11
12 // Only now make the connection (this can take a short while)
13 include "../inc/connection.php";
14
15 // Server Side Events
16 if (!defined('NO_EVENT_STREAM_HEADER'))
17 header('Content-Type: text/event-stream');
18
19 // Explicitly disable caching so Varnish and other upstreams won't cache.
20 header("Cache-Control: no-cache, must-revalidate");
21
22 // Setting this header instructs Nginx to disable fastcgi_buffering and disable
23 // gzip for this request.
24 header('X-Accel-Buffering: no');
25
26 // No time limit
27 set_time_limit(0);
28
29 // Send content immediately
30 ob_implicit_flush(1);
31
32 // Flush and stop output buffering (eg fastcgi w/NGINX)
33 while (1)
34 {
35 try {
36 $ret = @ob_end_flush();
37 if ($ret === false)
38 break;
39 } catch(Exception $e)
40 {
41 break;
42 }
43 };
44
45 /* Send server-sent events (SSE) message */
46 function send_sse($json)
47 {
48 echo "data: ".json_encode($json)."\n\n";
49 }
50
51 function api_log_loop($sources)
52 {
53 GLOBAL $rpc;
54
55 $rpc->log()->subscribe($sources);
56 if ($rpc->error)
57 {
58 echo $rpc->error;
59 die;
60 }
61
62 for(;;)
63 {
64 $res = $rpc->eventloop();
65 if (!$res)
66 {
67 /* Output at least something every timeout (10) seconds,
68 * otherwise PHP may not
69 * notice when the webclient is gone.
70 */
71 echo "\n";
72 continue;
73 }
74 send_sse($res);
75 }
76 }
77
78 function api_timer_loop(int $every_msec, string $method, array|null $params = null)
79 {
80 GLOBAL $rpc;
81
82 $rpc->rpc()->add_timer("timer", $every_msec, $method, $params);
83 if ($rpc->error)
84 {
85 /* Have to resort to old style: client-side timer */
86 while(1)
87 {
88 $res = $rpc->query($method, $params);
89 if (!$res)
90 die;
91 send_sse($res);
92 usleep($every_msec * 1000);
93 }
94 }
95
96 /* New style: use server-side timers */
97 for(;;)
98 {
99 $res = $rpc->eventloop();
100 if (!$res)
101 {
102 /* Output at least something every timeout (10) seconds,
103 * otherwise PHP may not
104 * notice when the webclient is gone.
105 */
106 echo "\n";
107 continue;
108 }
109 send_sse($res);
110 }
111 }