[RESOLU] Plantage Apache suite a session_start

Eléphanteau du PHP | 18 Messages

14 févr. 2020, 13:20

Bonjour,

J'ai un problème bizarre.

J'ai un script PHP, appelé en POST. Marche bien.
Si je mets un session_start() au début, fait carrément planter Apache quand appelé en POST.
Par contre, un appel direct ne crée pas de plantage.
A priori, rien à voir avec le code. Je le mets au cas où. (Sert pour une console shell interactive. Tout marche, sans appel à session_start())
Quelqu'un a-t-il déjà rencontré ce problème?

Merci par avance.
<?php
session_start(); // plantage général Apache si appelée en post. Pas de plantage si appelée directement?!

$chemin=getcwd()."/env";
$chemin2=getcwd()."/edit/";

$ch=getcwd()."/tmp";
//$script="$ch/script.sh 0< $ch/script.in\n";
$script="$ch/script.sh\n";
if (!isset($_POST['cmd'])){return;}
if (isset($_POST["init"]))
{
	
	file_put_contents("tmp/close"," ");
	sleep(1);
	foreach(scandir('tmp') as $f)
	{if ($f[0]!='.'){@unlink("tmp/".$f);}
	}
	file_put_contents("tmp/in","source $chemin/default 2> /dev/null\ncd ".'$PWD'."\n");
	clearstatcache(true,"tmp/out");
	clearstatcache(true,"tmp/err");
	clearstatcache(true,"tmp/in");
	file_put_contents("tmp/time",time());
}


if (isset($_POST["info"]))
{
	$com=$_POST['cmd']."\n";
	file_put_contents("tmp/in",$com,FILE_APPEND);
	return;
}
if (isset($_POST["script"]))
{	
	file_put_contents("histo.dat",$_POST['save']."\n",FILE_APPEND);
	
	$com='#!/bin/bash
	editer()
	{
	if [ $1 ]
	then
	local ch=`pwd`
	printf "$ch\n$1" > '.$chemin2.'file
	
	
	fi
	}
	
	restore () 
{ 
    local ch='.$chemin.'/;
    if [ $1 ]; then
        ch+=$1;
    else
        ch+="default";
    fi;
    if [ -e $ch ]; then
        source $ch 2> /dev/null;
        cd $PWD;
        #echo "Environnement restauré";
    fi
}
save () 
{ 
    local ch='.$chemin.'/;
    if [ $1 ]; then
        ch+=$1;
    else
        ch+="default";
    fi;
    set > $ch
};
restore 2> /dev/null';
	$com.="\n".$_POST['cmd'];
	$com.="\nsave\n echo `pwd` > $ch/pwd\n";
	file_put_contents("tmp/script.sh",$com);
	chmod("tmp/script.sh",0700);
	file_put_contents("tmp/in",$script,FILE_APPEND);
	return;
}

if (str_replace(" ","",$_POST['cmd'])=="")
{
	return;
}


if (isset($_POST['pwd'])){$cwd='cd '.$_POST['pwd']."\n";}else{$cwd='';}

$descriptorspec = array(
   0 => array("pipe", "r"),  
   1 => array("pipe", "w"), 
   2 => array("pipe","w") 
);


$out=fopen("tmp/out","a");
$err=fopen("tmp/err","a");
$info=fopen("tmp/info","a");


$com=$_POST['cmd'];
$com=$cwd.$com;
fwrite($info,$com);
$process = proc_open($com, $descriptorspec, $pipes);
file_put_contents("tmp/pid",intval(proc_get_status($process)["pid"])+1);
$posin=0;
$read_output = $read_error = false;
$buffer_len  = $prev_buffer_len = 0;
$ms          = 10;
$output      = '';
$read_output = true;
$error       = '';
$read_error  = true;
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);


while (($read_error != false or $read_output != false))
{
	$t=file_get_contents("tmp/time");
	if ($t!==false && strlen($t)>=10 && time()>10+intval($t))
		{$quit=true;}
		else
		{$quit=false;}
    if (file_exists("tmp/close") or $quit)
    {
    foreach(scandir('tmp') as $f)
	{
	if ($f[0]!='.'){@unlink("tmp/".$f);}
	}
    fclose($pipes[1]);
    fclose($pipes[0]);
    fclose($pipes[2]);
    fclose($out);
    fclose($err);
    file_put_contents("tmp/fini"," ");
    return proc_close($process);
    
    }
    if (file_exists("tmp/in"))
    {
    $r=file_get_contents("tmp/in");
    $r=substr($r,$posin);
    $posin+=strlen($r);
    
    if ($r!=""){
    fwrite($info,"ecriture ".$r);
    fwrite($pipes[0],$r);
    }
    }
    
    if ($read_output != false)
    {
        if(feof($pipes[1]))
        {
            fclose($pipes[1]);
            $read_output = false;
        }
        else
        {
            $str = fgets($pipes[1], 1024);
            $len = strlen($str);
            if ($len)
            {
            	fwrite($out,$str);
                $output .= $str;
                $buffer_len += $len;
            }
        }
    }
   
    if ($read_error != false)
    {
        if(feof($pipes[2]))
        {
            fclose($pipes[2]);
            $read_error = false;
        }
        else
        {
            $str = fgets($pipes[2], 1024);
            $len = strlen($str);
            if ($len)
            {
            	fwrite($out,$str);
                $error .= $str;
                $buffer_len += $len;
            }
        }
    }
   
    if ($buffer_len > $prev_buffer_len)
    {
        $prev_buffer_len = $buffer_len;
        $ms = 10;
    }
    else
    {
        usleep($ms * 1000);
        if ($ms < 160)
        {
            $ms = $ms * 2;
        }
    }
}

fclose($pipes[1]);
fclose($pipes[0]);
fclose($pipes[2]);
fclose($out);
fclose($err);
   
    
return proc_close($process);


?>




Eléphanteau du PHP | 18 Messages

14 févr. 2020, 13:48

Précision: rien dans le error.log d'Apache. Disons plutôt que tout est gelé. Quand je ferme la page appelant le script, au bout de quelques secondes, tout se débloque.

Eléphanteau du PHP | 18 Messages

14 févr. 2020, 13:59

Oubli: même comportement sur le serveur local, sur mon serveur distant. Bref, pas spécifique à un serveur Apache.

Eléphanteau du PHP | 18 Messages

16 févr. 2020, 12:26

Résolu.
Apparemment, problème de fichier cookie resté ouvert, et d'appel à session_start() bloquant.
Il suffit de remplacer session_start() par session_start(['read_and_close' => true]);