first set of commands arrive from index_rd_ifra.php handler
[brisk.git] / web / spush / brisk-spush.php
1 #!/usr/bin/php
2 <?php
3 /*
4  *  brisk - spush/brisk-spush.php
5  *
6  *  Copyright (C) 2012 Matteo Nastasi
7  *                          mailto: nastasi@alternativeoutput.it 
8  *                                  matteo.nastasi@milug.org
9  *                          web: http://www.alternativeoutput.it
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * General Public License for more details. You should have received a
20  * copy of the GNU General Public License along with this program; if
21  * not, write to the Free Software Foundation, Inc, 59 Temple Place -
22  * Suite 330, Boston, MA 02111-1307, USA.
23  *
24  * TODO
25  *   setcookie (for tables only)
26  *   keepalive
27  *   chunked 
28  *   index_rd.php porting
29  *   index.php auth part
30  *   generic var management from internet
31  */
32
33 $G_base = "../";
34
35 require_once("./sac-a-push.phh");
36 require_once("./brisk-spush.phh");
37 require_once($G_base."Obj/brisk.phh");
38 require_once($G_base."Obj/auth.phh");
39 // require_once("../Obj/proxyscan.phh");
40 require_once($G_base."index.php");
41 require_once($G_base."index_wr.php");
42 require_once($G_base."index_rd_ifra.php");
43 require_once($G_base."briskin5/Obj/briskin5.phh");
44
45 define('SITE_PREFIX', '/brisk/');
46
47 class SPUser {
48     var $id;
49     var $sess;
50     var $cnt;
51     var $sock;
52     
53     function SPUser($id)
54     {
55         $this->id = $id;
56         $this->cnt = -1;
57         $this->sock = NULL;
58     }
59
60     function enable($sock, $sess)
61     {
62         $this->sess = $sess;
63         $this->cnt = 0;
64         $this->sock = $sock;
65
66         return ($this->id);
67     }
68
69     function disable()
70     {
71         $this->cnt = -1;
72         $this->sock = NULL;
73     }
74
75     function is_enable()
76     {
77         return ($this->cnt < 0 ? FALSE : TRUE);
78     }
79
80     function sock_get()
81     {
82         return $this->sock;
83     }
84
85     function sock_set($sock)
86     {
87         $this->sock = $sock;
88     }
89
90     function id_get()
91     {
92         return $this->id;
93     }
94     
95     function sess_get()
96     {
97         return $this->sess;
98     }
99
100     function cnt_get()
101     {
102         return $this->cnt;
103     }
104
105     function cnt_inc()
106     {
107         return $this->cnt++;
108     }
109 }
110
111 function user_get_free($user_arr)
112 {
113     foreach ($user_arr as $i => $user) {
114         if (!$user->is_enable()) {
115             return ($user);
116         }
117     }
118     return FALSE;
119 }
120
121 function user_get_sess($user_arr, $sess)
122 {
123     foreach ($user_arr as $i => $user) {
124         printf("SESS: [%s]  cur: [%s]\n", $user->sess_get(), $sess);
125         if ($user->sess_get() == $sess) {
126             return ($user);
127         }
128     }
129     return FALSE;
130 }
131
132 function headers_render($header)
133 {
134     
135     $s = "";
136     $s .= "HTTP/1.1 200 OK\r\n";
137     if (!isset($header['Date']))
138         $s .= sprintf("Date: %s\r\n", date(DATE_RFC822));
139     if (!isset($header['Connection']))
140         $s .= "Connection: close\r\n";
141     if (!isset($header['Content-Type']))
142         $s .= "Content-Type: text/html\r\n";
143     foreach($header as $key => $value) {
144         $s .= sprintf("%s: %s\r\n", $key, $value);
145     }
146     $s .= "Mop: was/here\r\n";
147     $s .= "\r\n";
148
149     return ($s);
150 }
151
152
153 /*
154  *  Caching system using ob php system to cache old style pages
155  *  to a var and than send it with more calm
156  */
157 $G_headers = "";
158
159 function shutta()
160 {
161   log_rd2("SHUTTA [".connection_status()."] !");
162 }
163
164 register_shutdown_function('shutta');
165
166 /*
167  *  MAIN
168  */
169 $shutdown = FALSE;
170
171 function main()
172 {
173     GLOBAL $G_headers;
174     GLOBAL $shutdown;
175     $main_loop = TRUE;
176
177     /*
178      *  INIT
179      */
180
181     $FILE_SOCKET = "/tmp/brisk.sock";
182     $UNIX_SOCKET = "unix://$FILE_SOCKET";
183     $debug = 0;
184     $fixed_fd = 2;
185     $socks = array();
186
187     $blocking_mode = 0; // 0 for non-blocking
188
189     if (($room = Room::create()) == FALSE) {
190         log_crit("load_data failed");
191         return FALSE;
192     }
193
194     $s2u  = array();
195
196     $rndstr = "";
197     for ($i = 0 ; $i < 4096 ; $i++) {
198         $rndstr .= chr(mt_rand(65, 90));
199     }
200
201     if (file_exists($FILE_SOCKET)) {
202         unlink($FILE_SOCKET);
203     }
204     
205     $old_umask = umask(0);
206     if (($list = stream_socket_server($UNIX_SOCKET, $err, $errs)) === FALSE) {
207         exit(11);
208     }
209     umask($old_umask);
210
211     if (($in = fopen("php://stdin", "r")) === FALSE) {
212         exit(11);
213     }
214
215     stream_set_blocking($list, $blocking_mode); # Set the stream to non-blocking
216
217     while ($main_loop) {
218         echo "IN LOOP\n";
219         /* Prepare the read array */
220         if ($shutdown) 
221             $read   = array_merge(array("$in" => $in), $socks);
222         else
223             $read   = array_merge(array("$list" => $list, "$in" => $in), $socks);
224
225         if ($debug > 1) {
226             printf("PRE_SELECT\n");
227             print_r($read);
228         }
229         $write  = NULL;
230         $except = NULL;
231         $num_changed_sockets = stream_select($read, $write, $except, 5);
232         
233         if ($num_changed_sockets === FALSE) {
234             printf("No data in 5 secs");
235         } 
236         else if ($num_changed_sockets > 0) {
237             printf("num sock %d num_of_socket: %d\n", $num_changed_sockets, count($read));
238             if ($debug > 1) {
239                 print_r($read);
240             }
241             /* At least at one of the sockets something interesting happened */
242             foreach ($read as $i => $sock) {
243                 if ($sock === $list) {
244                     printf("NUOVA CONNEX\n");
245                     $new_unix = stream_socket_accept($list);
246                     $stream_info = "";
247                     $method      = "";
248                     $get         = array();
249                     $post        = array();
250                     $cookie      = array();
251                     if (($new_socket = ancillary_getstream($new_unix, $stream_info)) !== FALSE) {
252                         printf("RECEIVED HEADER:\n%s", $stream_info);
253                         $path = spu_process_info($stream_info, $method, $header, $get, $post, $cookie);
254                         printf("PATH: [%s]\n", $path);
255                         printf("M: %s\nHEADER:\n", $method);
256                         print_r($header);
257                         printf("GET:\n");
258                         print_r($get);
259                         printf("POST:\n");
260                         print_r($post);
261                         printf("COOKIE:\n");
262                         print_r($cookie);
263
264                         switch ($path) {
265                         case SITE_PREFIX:
266                         case SITE_PREFIX."index.php":
267                             $header_out = array();
268                             ob_start();
269                             index_main($room, $header_out, $get, $post, $cookie);
270                             $content = ob_get_flush();
271
272                             // printf("OUT: [%s]\n", $G_content);
273                             fwrite($new_socket, headers_render($header_out).$content);
274                             fclose($new_socket);
275                             break;
276                         case SITE_PREFIX."index_wr.php":
277                             $G_headers = "";
278                             ob_start();
279                             index_wr_main($room, socket_getpeername($$new_socket), $get, $post, $cookie);
280                             $content = ob_get_flush();
281                             
282                             // printf("OUT: [%s]\n", $G_content);
283                             fwrite($new_socket, headers_render($header_out).$content);
284                             fclose($new_socket);
285                             break;
286                         case SITE_PREFIX."index_rd_ifra.php":
287                             do {
288                                 if (!isset($cookie['sess'])) {
289                                     fclose($new_socket);
290                                     break;
291                                 }
292                                 if (($user = $room->get_user($cookie['sess'], $idx)) == FALSE) {
293                                     fclose($new_socket);
294                                     break;
295                                 }
296                                 if (($prev = $user->rd_socket_get()) != NULL) {
297                                     unset($s2u[intval($user->rd_socket_get())]);
298                                     unset($socks[intval($user->rd_socket_get())]);
299                                     fclose($user->rd_socket_get());
300                                     $user->rd_socket_set(NULL);
301                                 }
302
303                                 $header_out = array();
304                                 $body = "";
305                                 index_rd_ifra_init($room, $user, $header_out, $body, $get, $post, $cookie);
306                                 stream_set_blocking($new_socket, $blocking_mode); // Set the stream to non-blocking
307                                 fwrite($new_socket, headers_render($header_out).$body);
308                                 fflush($new_socket);
309
310                                 $s2u[intval($new_socket)] = $idx;
311                                 $socks[intval($new_socket)] = $new_socket;                                
312                                 $user->rd_socket_set($new_socket);
313                             } while (FALSE);
314
315                             break;
316                         }
317                             
318
319
320
321                         if (0 == 1) {
322                             /* TODO: here stuff to decide if it is old or new user */
323                             if (($user_cur = user_get_sess($user_a, $get['sess'])) != FALSE) {
324                                 /* close the previous socket */
325                                 unset($s2u[intval($user_cur->sock_get())]);
326                                 unset($socks[intval($user_cur->sock_get())]);
327                                 fclose($user_cur->sock_get());
328                                 /* assign the new socket */
329                                 $user_cur->sock_set($new_socket);
330                                 $id = $user_cur->id_get();
331                                 $s2u[intval($new_socket)] = $id;
332                                 $socks[intval($new_socket)] = $new_socket;
333                                 fwrite($new_socket, $rndstr);
334                                 fflush($new_socket);
335                             }
336                             else if (($user_cur = user_get_free($user_a)) != FALSE) {
337                                 stream_set_blocking($new_socket, $blocking_mode); // Set the stream to non-blocking
338                                 $socks[intval($new_socket)] = $new_socket;
339
340                                 $id = $user_cur->id_get();
341                                 $user_a[$id]->enable($new_socket, $get['sess']);
342                                 printf("s2u: ci passo %d\n", intval($new_socket));
343                                 $s2u[intval($new_socket)] = $id;
344
345                                 fwrite($new_socket, $rndstr);
346                                 fflush($new_socket);
347                             }
348                             else {
349                                 printf("Too many opened users\n");
350                                 fclose($new_socket);
351                             }
352                         }
353                     }
354                     else {
355                         printf("WARNING: ancillary_getstream failed\n");
356                     }
357                 }
358                 else {
359                     if (($buf = fread($sock, 512)) === FALSE) {
360                         printf("error read\n");
361                         exit(123);
362                     }
363                     else if (strlen($buf) === 0) {
364                         if ($sock === $list) {
365                             printf("Arrivati %d bytes da list\n", strlen($buf));
366                         }
367                         else if ($sock === $in) {
368                             printf("Arrivati %d bytes da stdin\n", strlen($buf));
369                         }
370                         else {
371                             // $user_a[$s2u[intval($sock)]]->disable();
372                             if ($room->user[$s2u[intval($sock)]]->rd_socket_get() != NULL) {
373                                 $room->user[$s2u[intval($sock)]]->rd_socket_set(NULL);
374                             }
375                             unset($socks[intval($sock)]);
376                             unset($s2u[intval($sock)]);
377                             fclose($sock);
378                         }
379                         if ($debug > 1) {
380                             printf("post unset\n");
381                             print_r($socks);
382                         }
383                     }
384                     else {
385                         if ($debug > 1) {
386                             print_r($read);
387                         }
388                         if ($sock === $list) {
389                             printf("Arrivati %d bytes da list\n", strlen($buf));
390                         }
391                         else if ($sock === $in) {
392                             printf("Arrivati %d bytes da stdin\n", strlen($buf));
393                         }
394                         else {
395                             $key = array_search("$sock", $socks);
396                             printf("Arrivati %d bytes dalla socket n. %d\n", strlen($buf), $key);
397                         }
398                     }
399                 }
400             }
401         }
402
403
404
405
406
407
408         foreach ($socks as $k => $sock) {
409             if (isset($s2u[intval($sock)])) {
410                 $body = "";
411                 
412
413                 $header_out = array();
414                 $body = "";
415                 index_rd_ifra_main($room, $room->user[$s2u[intval($sock)]], $body);
416                 echo "SPIA: [$body]\n";
417                 fwrite($sock, headers_render($header_out).$body);
418                 fflush($sock);
419             }
420         }
421     }
422     
423     exit(0);
424 }
425
426 main();
427 ?>