From f03ca5784cc63eb3b78ef2f368d8e05e790c0488 Mon Sep 17 00:00:00 2001 From: "Committo,Ergo:sum" <esj@rezo.net> Date: Sat, 12 Apr 2008 11:05:03 +0000 Subject: [PATCH] =?UTF-8?q?Ajouts=20d'arguments=20optionnels=20=C3=A0=20la?= =?UTF-8?q?=20fonction=20http=5Finit,=20afin=20de=20pouvoir=20l'utiliser?= =?UTF-8?q?=20en=20HTTP/1.1=20avec=20connexions=20persistentes=20(sous=20r?= =?UTF-8?q?=C3=A9serve=20que=20KeepAlive=20soit=20=C3=A0=20On=20dans=20le?= =?UTF-8?q?=20httpd.conf=20du=20serveur=20vis=C3=A9).=20Red=C3=A9coupage?= =?UTF-8?q?=20fonctionnels=20des=20fonctions=20qui=20l'appellent=20afin=20?= =?UTF-8?q?de=20pouvoir=20r=C3=A9utiliser=20leur=20boulot=20dans=20ce=20co?= =?UTF-8?q?ntexte=20un=20peu=20diff=C3=A9rent=20du=20HTTP/1.0=20utilis?= =?UTF-8?q?=C3=A9=20par=20SPIP=20pour=20r=C3=A9cup=C3=A9rer=20une=20page?= =?UTF-8?q?=20unique=20(ce=20qui=20est=20normal).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecrire/inc/distant.php | 191 +++++++++++++++++++++-------------------- 1 file changed, 99 insertions(+), 92 deletions(-) diff --git a/ecrire/inc/distant.php b/ecrire/inc/distant.php index 588ac8bd02..b12a3e2721 100644 --- a/ecrire/inc/distant.php +++ b/ecrire/inc/distant.php @@ -11,7 +11,7 @@ \***************************************************************************/ if (!defined("_ECRIRE_INC_VERSION")) return; - +@define('_COPIE_LOCALE_MAX_SIZE',1048576); // poids (inc/utils l'a fait) // // Cree au besoin la copie locale d'un fichier distant // mode = 'test' - ne faire que tester @@ -171,7 +171,8 @@ function recuperer_page($url, $munge_charset=false, $get_headers=false, if (!empty($datas)) { $get = 'POST'; - $datas = prepare_donnees_post($datas); + list($type, $postdata) = prepare_donnees_post($datas); + $datas = $type . 'Content-Length: '.strlen($postdata)."\r\n\r\n".$postdata; } // dix tentatives maximum en cas d'entetes 301... @@ -191,72 +192,38 @@ function recuperer_page($url, $munge_charset=false, $get_headers=false, // http://doc.spip.org/@recuperer_lapage function recuperer_lapage($url, $trans=false, $get='GET', $taille_max = 1048576, $datas='', $boundary='', $refuser_gz = false, $date_verif = '', $uri_referer = '') { - list($f, $fopen) = init_http($get, $url, $refuser_gz, $uri_referer); - $gz = false; - - // si on a utilise fopen() - passer a la suite - if (!$fopen) { - // Fin des entetes envoyees par SPIP - if($get == 'POST') { - list($content_type, $postdata) = $datas; - @fputs($f, $content_type); - @fputs($f, 'Content-Length: '.strlen($postdata)."\r\n"); - @fputs($f, "\r\n".$postdata); - } else { - @fputs($f,"\r\n"); - } - - // Reponse du serveur distant - $s = @trim(fgets($f, 16384)); - if (preg_match(',^HTTP/[0-9]+\.[0-9]+ ([0-9]+),', $s, $r)) { - $status = $r[1]; - } - else return false; - - // Entetes HTTP de la page - $headers = ''; - while ($s = trim(fgets($f, 16384))) { - $headers .= $s."\n"; - if (preg_match(',^Location: (.*),i', $s, $r)) { - include_spip('inc/filtres'); - $location = suivre_lien($url, $r[1]); - } - if ($date_verif AND preg_match(',^Last-Modified: (.*),', $s, $r)) { - if(strtotime($date_verif)>=strtotime($r[1])) { - //Cas ou la page distante n'a pas bouge depuis - //la derniere visite - return $status; - } - } - if (preg_match(",^Content-Encoding: .*gzip,i", $s)) - $gz = true; - } - if ($status >= 300 AND $status < 400 AND $location) { - fclose($f); - return $location; - } else if ($status != 200){ - spip_log("ECHEC chargement $url : Status $status"); - return false; - } - ; # sinon on est content - } - - // Contenu de la page + // ouvrir la connexion et envoyer la requete et ses en-tetes + list($f, $fopen) = init_http($get, $url, $refuser_gz, $uri_referer, $datas); if (!$f) { - spip_log("ECHEC chargement $url"); + spip_log("ECHEC init_http $url"); return false; } + // Sauf en fopen, envoyer le flux d'entree + // et recuperer les en-tetes de reponses + if ($fopen) + $headers = ''; + else { + $headers = recuperer_entetes($f, $date_verif); + if (!$headers) { + spip_log("ECHEC chargement $url"); + return false; + } + if (!is_array($headers)) + return $headers ; // cas Location ou Modified. + $headers = join('', $headers); + } + +# spip_log("recup $headers" ); if ($trans === NULL) return array($headers, ''); - $result = ''; - while (!feof($f) AND strlen($result)<$taille_max) - $result .= fread($f, 16384); + $result = recuperer_body($f, $taille_max); fclose($f); + if (!$result) return array($headers, $result); - // Decompresser le flux - if ($gz AND $result) + // Decompresser au besoin + if (preg_match(",\bContent-Encoding: .*gzip,i", $headers)) { $result = gzinflate(substr($result,10)); - + } // Faut-il l'importer dans notre charset local ? if ($trans) { include_spip('inc/charsets'); @@ -266,6 +233,54 @@ function recuperer_lapage($url, $trans=false, $get='GET', $taille_max = 1048576, return array($headers, $result); } +function recuperer_body($f, $taille_max=1048576) +{ + $result = ''; + while (!feof($f) AND strlen($result)<$taille_max) + $result .= fread($f, 16384); + return $result; +} + +// Entetes de reponse HTTP sur la socket $f +// Les retourne sous forme de tableau, +// sauf si presence de Location ou Last-Modified, +// ou on renvoie une chaine et on ferme la connexion + +function recuperer_entetes($f, $date_verif='') +{ + $s = @trim(fgets($f, 16384)); + + if (!preg_match(',^HTTP/[0-9]+\.[0-9]+ ([0-9]+),', $s, $r)) { + @fclose($f); + return false; + } + $status = $r[1]; + $headers = array(); + while ($s = trim(fgets($f, 16384))) { + $headers[]= $s."\n"; + if (preg_match(',^Location: (.*),i', $s, $r)) { + include_spip('inc/filtres'); + $location = suivre_lien($url, $r[1]); + } + if ($date_verif AND preg_match(',^Last-Modified: (.*),', $s, $r)) { + if(strtotime($date_verif)>=strtotime($r[1])) { + //Cas ou la page distante n'a pas bouge depuis + //la derniere visite + fclose($f); + return $status; + } + } + } + if ($status >= 300 AND $status < 400 AND $location) { + fclose($f); + return $location; + } else if ($status != 200){ + spip_log("ECHEC chargement $url : Status $status"); + @fclose($f); + return false; + } + return $headers; +} // Si on doit conserver une copie locale des fichiers distants, autant que ca // soit a un endroit canonique -- si ca peut etre bijectif c'est encore mieux, @@ -462,11 +477,11 @@ function need_proxy($host) } // -// Demarre une transaction HTTP (s'arrete a la fin des entetes) -// retourne un descripteur de fichier +// Lance une requete HTTP avec entetes +// retourne le descripteur sur lequel lire la reponse // // http://doc.spip.org/@init_http -function init_http($get, $url, $refuse_gz=false, $uri_referer = '') { +function init_http($method, $url, $refuse_gz=false, $referer = '', $datas="", $vers="HTTP/1.0") { $via_proxy = ''; $proxy_user = ''; $fopen = false; $t = @parse_url($url); @@ -481,45 +496,37 @@ function init_http($get, $url, $refuse_gz=false, $uri_referer = '') { $scheme = $t['scheme']; $scheme_fsock=$scheme.'://'; } if (!isset($t['port']) || !($port = $t['port'])) $port = 80; - $query = $t['query']; if (!isset($t['path']) || !($path = $t['path'])) $path = "/"; + if ($t['query']) $path .= "?" .$t['query']; $http_proxy = need_proxy($host); if ($http_proxy) { - spip_log("connexion vers $url via $http_proxy"); + $path = "$scheme://$host" . (($port != 80) ? ":$port" : "") . $path; $t2 = @parse_url($http_proxy); - $proxy_host = $t2['host']; $proxy_user = $t2['user']; $proxy_pass = $t2['pass']; - if (!($proxy_port = $t2['port'])) $proxy_port = 80; - $f = @fsockopen($proxy_host, $proxy_port); - $req = "$get $scheme://$host" . (($port != 80) ? ":$port" : "") . $path . ($query ? "?$query" : "") . " HTTP/1.0\r\n"; - } else { - $f = @fsockopen($scheme_fsock.$host, $port); - spip_log("connexion vers $url sans proxy"); - $req = "$get $path" . ($query ? "?$query" : "") . " HTTP/1.0\r\n"; - } + $first_host = $t2['host']; + if (!($port = $t2['port'])) $port = 80; + + } else $first_host = $scheme_fsock.$host; + $f = @fsockopen($first_host, $port); + spip_log("Recuperer $path sur $first_host:$port par $f"); if ($f) { + $site = $GLOBALS['meta']["adresse_site"]; + + $req = "$method $path $vers\r\n" + . "Host: $host\r\n" + . "User-Agent: SPIP-".$GLOBALS['spip_version_affichee']." (http://www.spip.net/)\r\n" + . ($refuse_gz ? '' : "Accept-Encoding: gzip\r\n") + . (!$site ? '' : "Referer: $site/$referer\r\n") + . (!$proxy_user ? '' : + ("Proxy-Authorization: Basic " + . base64_encode($proxy_user . ":" . $proxy_pass) . "\r\n")); + +# spip_log("Requete\n$req"); fputs($f, $req); - fputs($f, "Host: $host\r\n"); - fputs($f, "User-Agent: SPIP-".$GLOBALS['spip_version_affichee']." (http://www.spip.net/)\r\n"); - - // Proxy authentifiant - if ($proxy_user) { - fputs($f, "Proxy-Authorization: Basic " - . base64_encode($proxy_user . ":" . $proxy_pass) . "\r\n"); - } - // Referer = c'est nous ! - if ($referer = $GLOBALS['meta']["adresse_site"]) { - $referer .= '/'.$uri_referer; - fputs($f, "Referer: $referer\r\n"); - } - - // On sait lire du gzip - if ($GLOBALS['flag_gz'] AND !$refuse_gz) - fputs($f, "Accept-Encoding: gzip\r\n"); - + fputs($f, $datas ? $datas : "\r\n"); } // fallback : fopen else if (!$GLOBALS['tester_proxy']) { -- GitLab