htmlfile transport type added
[brisk.git] / web / Obj / sac-a-push.phh
index cd0d6ab..c140192 100644 (file)
@@ -105,26 +105,39 @@ function gpcs_var($name, $get, $post, $cookie)
 
 function headers_render($header, $len)
 {
-    
-    $s = "";
-    $s .= "HTTP/1.1 200 OK\r\n";
-    if (!isset($header['Date']))
-        $s .= sprintf("Date: %s\r\n", date(DATE_RFC822));
-    if (!isset($header['Connection']))
-        $s .= "Connection: close\r\n";
-    if (!isset($header['Content-Type']))
-        $s .= "Content-Type: text/html\r\n";
-    foreach($header as $key => $value) {
-        $s .= sprintf("%s: %s\r\n", $key, $value);
+    $cookies = "";
+
+    if (isset($header['cookies'])) {
+        $cookies = $header['cookies']->render();
+        unset($header['cookies']);
     }
-    if ($len == -1) {
-        $s .= "Cache-Control: no-cache, must-revalidate\r\n";
-        $s .= "Expires: Mon, 26 Jul 1997 05:00:00 GMT\r\n";
-        $s .= "Content-Encoding: chunked\r\n";
-        $s .= "Transfer-Encoding: chunked\r\n";
+    if (isset($header['Location'])) {
+        $s = sprintf("HTTP/1.1 302 OK\r\n%sLocation: %s\r\n", $cookies, $header['Location']);
     }
-    else if ($len > 0) {
-        $s .= sprintf("Content-Length: %d\r\n", $len);
+    else {
+        $s = "HTTP/1.1 200 OK\r\n";
+
+        if (!isset($header['Date']))
+            $s .= sprintf("Date: %s\r\n", date(DATE_RFC822));
+        if (!isset($header['Connection']))
+            $s .= "Connection: close\r\n";
+        if (!isset($header['Content-Type']))
+            $s .= "Content-Type: text/html\r\n";
+        foreach($header as $key => $value) {
+            $s .= sprintf("%s: %s\r\n", $key, $value);
+        }
+        if ($len >= 0) {
+            $s .= sprintf("Content-Length: %d\r\n", $len);
+        }
+        else {
+            $s .= "Cache-Control: no-cache, must-revalidate\r\n";
+            $s .= "Expires: Mon, 26 Jul 1997 05:00:00 GMT\r\n";
+            if (!isset($header['Content-Encoding'])) {
+                $s .= "Content-Encoding: chunked\r\n";
+            }
+            $s .= "Transfer-Encoding: chunked\r\n";
+        }
+        $s .= $cookies;
     }
     $s .= "\r\n";
 
@@ -147,11 +160,18 @@ register_shutdown_function('shutta');
  *  MAIN
  */
 
-function chunked_content($content)
+function chunked_content($zls, $content)
 {
-    $content_l = mb_strlen($content, "ASCII");
+    if ($zls) {
+        $cont_comp = $zls->compress_chunk($content);
+    }
+    else {
+        $cont_comp = $content;
+    }
+    $cont_comp_l = mb_strlen($cont_comp, "ASCII");
+    printf("CHUNK: [%s]\n", $content);
 
-    return (sprintf("%X\r\n%s\r\n", $content_l, $content));
+    return (sprintf("%X\r\n", $cont_comp_l).$cont_comp."\r\n");
 }
 
 function chunked_fini()
@@ -159,6 +179,122 @@ function chunked_fini()
     return sprintf("0\r\n");
 }
 
+function get_encoding($header)
+{
+    $enc = "plain";
+    if (isset($header['Accept-Encoding'])) {
+        $acc = explode(',', $header['Accept-Encoding']);
+
+        if (array_search('gzip', $acc) !== FALSE) {
+            $enc = 'gzip';
+        }
+        else if (array_search('deflate', $acc) !== FALSE) {
+            $enc = 'deflate';
+        }
+    }
+
+    return ($enc);
+}
+
+class Cookie {
+    var $attr;
+    // Set-Cookie: reg_fb_gate=deleted; Expires=Thu, 01-Jan-1970 00:00:01 GMT; Path=/; Domain=.foo.com; HttpOnly
+    // string $name  [, string $value  [, int $expire = 0  [, string $path  [, string $domain  [, bool $secure = false  [, bool $httponly = false  ]]]]]] )
+    function Cookie()
+    {
+        $this->attr = array();
+    }
+
+    static function create($name)
+    {
+        $thiz = new Cookie();
+
+        $thiz->attr[$name] = "";
+
+        $argc = func_num_args();
+        for ($i = 1 ; $i < $argc ; $i++) {
+            $arg = func_get_arg($i);
+            switch ($i) {
+            case 1:
+                $thiz->attr[$name] = urlencode($arg);
+                break;
+            case 2:
+                $thiz->attr['Expires'] = gmdate('D, d M Y H:i:s \G\M\T', $arg); // RFC 1211 format
+                break;
+            case 3:
+                $thiz->attr['Path'] = $arg;
+                break;
+            case 4:
+                $thiz->attr['Domain'] = $arg;
+                break;
+            case 5:
+                if ($arg == TRUE) {
+                    $thiz->attr['Secure'] = NULL;
+                }
+                break;
+            case 6:
+                if ($arg == TRUE) {
+                    $thiz->attr['HttpOnly'] = NULL;
+                }
+                break;
+            default:
+                return FALSE;
+            }
+        }
+
+        return $thiz;
+    }
+
+    function render()
+    {
+        $r = "Set-Cookie: ";
+        $isfirst = TRUE;
+
+        foreach ($this->attr as $k => $v) {
+            if ($v == NULL) {
+                $r .= sprintf("%s%s", ($isfirst ? "" : "; "), $k);
+            }
+            else {
+                $r .= sprintf("%s%s=%s", ($isfirst ? "" : "; "), $k, $v);
+            }
+            $isfirst = FALSE;
+        }
+        $r .= "\r\n";
+
+        return $r;
+    }
+}
+
+class Cookies {
+    var $cookies;
+
+    function Cookies()
+    {
+        $this->cookies = array();
+    }
+
+    function add($name)
+    {
+        if (($cookie = call_user_func_array("Cookie::create", func_get_args())) == FALSE)
+            return (FALSE);
+
+        array_push($this->cookies, $cookie);
+
+        return (TRUE);
+    }
+
+    function render()
+    {
+        $r = "";
+        foreach ($this->cookies as $cookie) {
+            $r .= $cookie->render();
+        }
+
+        return ($r);
+    }
+}
+
+
 class Sac_a_push {
     static $fixed_fd = 2;
     
@@ -204,7 +340,10 @@ class Sac_a_push {
 
         $thiz->rndstr = "";
         for ($i = 0 ; $i < 4096 ; $i++) {
-            $thiz->rndstr .= chr(mt_rand(65, 90));
+            if (($i % 128) == 0)
+                $thiz->rndstr .= "\n";
+            else
+                $thiz->rndstr .= chr(mt_rand(65, 90));
         }
         
         if (file_exists($thiz->file_socket)) {
@@ -243,9 +382,9 @@ class Sac_a_push {
         unset($this->socks[$id]);
     }
 
-    function pgflush_try_add(&$new_socket, $tout, $header_out, $content)
+    function pgflush_try_add($enc, &$new_socket, $tout, $header_out, $content)
     {
-        $pgflush = new PageFlush($new_socket, $this->curtime, $tout, $header_out, $content);
+        $pgflush = new PageFlush($new_socket, $enc, $this->curtime, $tout, $header_out, $content);
 
         if ($pgflush->try_flush($this->curtime) == FALSE) {
             // Add $pgflush to the pgflush array
@@ -258,8 +397,27 @@ class Sac_a_push {
         array_push($this->pages_flush, $pgflush);
     }
 
+    function garbage_manager($force)
+    {
+        $this->app->garbage_manager($force);
+
+        foreach ($this->socks as $k => $sock) {
+            if ($this->s2u[intval($sock)]->sess == '') {
+                if ($this->s2u[intval($sock)]->rd_socket_get() != NULL) {
+                    $this->s2u[intval($sock)]->rd_socket_set(NULL);
+                }
+                unset($this->socks[intval($sock)]);
+                unset($this->s2u[intval($sock)]);
+                fclose($sock);
+                printf("CLOSE ON GARBAGE MANAGER\n");
+            }
+        }
+    }
+
     function run()
     {
+        GLOBAL $DOCUMENT_ROOT, $HTTP_HOST, $G_with_splash;
+
         if ($this->main_loop) {
             return (FALSE);
         }
@@ -284,10 +442,10 @@ class Sac_a_push {
             }
             $write  = NULL;
             $except = NULL;
-            $num_changed_sockets = stream_select($read, $write, $except, 0, 250000);
+            $num_changed_sockets = stream_select($read, $write, $except, 0, 500000);
         
             if ($num_changed_sockets == 0) {
-                printf(" no data in 5 secs ");
+                printf(" no data in 5 secs, splash [%d]\n", $G_with_splash);
             } 
             else if ($num_changed_sockets > 0) {
                 printf("num sock %d num_of_socket: %d\n", $num_changed_sockets, count($read));
@@ -303,7 +461,10 @@ class Sac_a_push {
                     }
                     if ($sock === $this->list) {
                         printf("NUOVA CONNEX\n");
-                        $new_unix = stream_socket_accept($this->list);
+                        if (($new_unix = stream_socket_accept($this->list)) == FALSE) {
+                            printf("SOCKET_ACCEPT FAILED\n");
+                            continue;
+                        }
                         $stream_info = "";
                         $method      = "";
                         $get         = array();
@@ -323,7 +484,6 @@ class Sac_a_push {
                             print_r($post);
                             printf("COOKIE:\n");
                             print_r($cookie);
-
                             $addr = stream_socket_get_name($new_socket, TRUE);
                             $header_out = array();
 
@@ -331,7 +491,7 @@ class Sac_a_push {
                             $subs_l = strlen($subs);
                             $rret = FALSE;
                             if (!strncmp($path, SITE_PREFIX, SITE_PREFIX_LEN)) {
-                                $rret = $this->app->request_mgr($this, $header_out, $new_socket, substr($path, SITE_PREFIX_LEN), $addr, $get, $post, $cookie);
+                                $rret = $this->app->request_mgr($this, $header, $header_out, $new_socket, substr($path, SITE_PREFIX_LEN), $addr, $get, $post, $cookie);
                             }
                             if ($rret == FALSE) { 
                                 // FIXME: manage 404 !!!
@@ -344,15 +504,19 @@ class Sac_a_push {
                         }
                     }
                     else {
-                        if (($buf = fread($sock, 512)) === FALSE) {
-                            printf("error read\n");
-                        }
-                        else if (strlen($buf) === 0) {
+                        $buf = fread($sock, 512);
+                        // if socket is closed
+                        if ($buf == FALSE || strlen($buf) == 0) {
+                            if ($buf == FALSE) {
+                                printf("ERROR READING\n");
+                            }
                             if ($sock === $this->list) {
                                 printf("Arrivati %d bytes da list\n", strlen($buf));
+                                exit(21);
                             }
                             else if ($sock === $this->in) {
                                 printf("Arrivati %d bytes da stdin\n", strlen($buf));
+                                exit(22);
                             }
                             else {
                                 // $user_a[$s2u[intval($sock)]]->disable();
@@ -361,9 +525,10 @@ class Sac_a_push {
                                 }
                                 unset($this->socks[intval($sock)]);
                                 unset($this->s2u[intval($sock)]);
-                                fclose($sock);
-                                printf("CLOSE ON READ\n");
                             }
+                            fclose($sock);
+                            printf("CLOSE ON READ\n");
+
                             if ($this->debug > 1) {
                                 printf("post unset\n");
                                 print_r($this->socks);
@@ -378,6 +543,10 @@ class Sac_a_push {
                             }
                             else if ($sock === $this->in) {
                                 printf("Arrivati %d bytes da stdin\n", strlen($buf));
+                                $line = trim($buf);
+                                if ($line == "reload") {
+                                    require("$DOCUMENT_ROOT/Etc/".BRISK_CONF);
+                                }
                             }
                             else {
                                 $key = array_search("$sock", $this->socks);
@@ -387,10 +556,8 @@ class Sac_a_push {
                     }
                 }
             }
-            
-
-            $this->app->garbage_manager(FALSE);
 
+            $this->garbage_manager(FALSE);
 
             /* manage unfinished pages */
             foreach ($this->pages_flush as $k => $pgflush) {
@@ -399,34 +566,44 @@ class Sac_a_push {
                 }
             }
             
+            /*
+               $response:                        raw stream data not sent
+               $content:                         html consistent data (<script bla bla>)
+               $user->stream_keepalive($w_ping)  ping srv->cli OR srv->cli + cli->srv if $w_ping == TRUE
+            */
+
             /* manage open streaming */
             foreach ($this->socks as $k => $sock) {
                 if (isset($this->s2u[intval($sock)])) {
                     $user = $this->s2u[intval($sock)];
                     $response = $user->rd_cache_get();
-                    if (($this->curtime - $user->lacc) <= (EXPIRE_TIME_RD / 2)) {
+                    $do_ping = FALSE;
+                    if (($this->curtime - $user->lacc) > (EXPIRE_TIME_RD / 3)) {
+                        $do_ping = TRUE;
+                    }
+                    else {
                         $user->ping_req = FALSE;
                     }
+
                     if ($response == "") {
                         $content = "";
                         $user->stream_main($content, $get, $post, $cookie);
                         printf("[%s] [%d] [%d]\n", $user->name, $user->lacc, $this->curtime);
-                        if ($content == "" && $user->ping_req == FALSE 
-                            && (($this->curtime - $user->lacc) > (EXPIRE_TIME_RD / 2))) {
-                            $content = $user->stream_ping();
+                        if ($do_ping && $user->ping_req == FALSE) {
+                            $content .= $user->stream_keepalive(TRUE);
                             $user->ping_req = TRUE;
                         }
-                        if ($content == "" && $user->rd_kalive_is_expired($this->curtime)) {
-                            $content = $user->stream_keepalive();
+                        else if ($content == "" && $user->rd_kalive_is_expired($this->curtime)) {
+                            $content = $user->stream_keepalive(FALSE);
                         }
                         if ($content != "") {
-                            $response = chunked_content($content);
+                            $response = chunked_content($user->rd_zls_get(), $content);
                         }
                     }
                     
                     if ($response != "") {
                         // echo "SPIA: [".substr($response, 0, 60)."...]\n";
-                        echo "SPIA: [".$response."...]\n";
+                        echo "SPIA: [".$response."]\n";
                         $response_l = mb_strlen($response, "ASCII");
                         $wret = @fwrite($sock, $response);
                         if ($wret < $response_l) {
@@ -457,4 +634,4 @@ class Sac_a_push {
     }  // function run(...
 }
 
-?>
\ No newline at end of file
+?>