/**
* Ce fichier gère l'obtention de données distantes
- *
+ *
* @package SPIP\Core\Distant
**/
if (!defined('_ECRIRE_INC_VERSION')) return;
if (!defined('_INC_DISTANT_USER_AGENT')) define('_INC_DISTANT_USER_AGENT', 'SPIP-' . $GLOBALS['spip_version_affichee'] . " (" . $GLOBALS['home_server'] . ")");
if (!defined('_INC_DISTANT_MAX_SIZE')) define('_INC_DISTANT_MAX_SIZE',2097152);
-define('_REGEXP_COPIE_LOCALE', ',' .
+define('_REGEXP_COPIE_LOCALE', ',' .
preg_replace('@^https?:@', 'https?:', $GLOBALS['meta']['adresse_site'])
. "/?spip.php[?]action=acceder_document.*file=(.*)$,");
$chaine = '';
if (is_array($donnees)) {
foreach ($donnees as $cle => $valeur) {
- $chaine .= "\r\n--$boundary\r\n";
- $chaine .= "Content-Disposition: form-data; name=\"$cle\"\r\n";
- $chaine .= "\r\n";
- $chaine .= $valeur;
+ if (is_array($valeur)) {
+ foreach ($valeur as $val2) {
+ $chaine .= "\r\n--$boundary\r\n";
+ $chaine .= "Content-Disposition: form-data; name=\"{$cle}[]\"\r\n";
+ $chaine .= "\r\n";
+ $chaine .= $val2;
+ }
+ } else {
+ $chaine .= "\r\n--$boundary\r\n";
+ $chaine .= "Content-Disposition: form-data; name=\"$cle\"\r\n";
+ $chaine .= "\r\n";
+ $chaine .= $valeur;
+ }
}
$chaine .= "\r\n--$boundary\r\n";
}
foreach ($donnees as $cle => $valeur) {
if (is_array($valeur)) {
foreach ($valeur as $val2) {
- $chaine[] = rawurlencode($cle).'='.rawurlencode($val2);
+ $chaine[] = rawurlencode($cle).'[]='.rawurlencode($val2);
}
} else {
$chaine[] = rawurlencode($cle).'='.rawurlencode($valeur);
return false;
}
+ $result = '';
// Sauf en fopen, envoyer le flux d'entree
// et recuperer les en-tetes de reponses
if ($fopen)
$headers = recuperer_entetes($f, $date_verif);
if (is_numeric($headers)){
fclose($f);
- // Chinoisierie inexplicable pour contrer
+ // Chinoisierie inexplicable pour contrer
// les actions liberticides de l'empire du milieu
if ($headers){
spip_log("HTTP status $headers pour $url");
return false;
}
- elseif ($result = @file_get_contents($url))
- return array('', $result);
+ $t = @parse_url($url);
+ $host = $t['host'];
+ if (!need_proxy($host)
+ AND $result = @file_get_contents($url)){
+ // on peuple les headers de vide et on continue
+ $headers = array('');
+ }
else
return false;
}
$gz = preg_match(",\bContent-Encoding: .*gzip,is", $headers) ?
(_DIR_TMP . md5(uniqid(mt_rand())) . '.tmp.gz') : '';
-# spip_log("entete ($trans $copy $gz)\n$headers");
- $result = recuperer_body($f, $taille_max, $gz ? $gz : ($copy ? $trans : ''));
- fclose($f);
+# spip_log("entete ($trans $copy $gz)\n$headers");
+ if (!$result){
+ $result = recuperer_body($f, $taille_max, $gz ? $gz : ($copy ? $trans : ''));
+ fclose($f);
+ }
if (!$result)
return array($headers, $result);
#$a['taille'] = intval
#$a['extension'] = chaine
#$a['fichier'] = chaine
+#$a['mime_type'] = chaine
// http://doc.spip.org/@recuperer_infos_distantes
function recuperer_infos_distantes($source, $max = 0, $charger_si_petite_image = true){
$a['titre'] = corriger_caracteres(trim($regs[1]));
if (!$a['taille']) $a['taille'] = strlen($page); # a peu pres
}
+ $a['mime_type']=$mime_type;
return $a;
}
$f = lance_requete($method, $scheme, $user, $host, $path, $port, $noproxy, $refuse_gz, $referer, $datas, $vers, $date);
if (!$f){
// fallback : fopen
- if (!_request('tester_proxy')){
+ if (!need_proxy($host)
+ AND !_request('tester_proxy')){
$f = @fopen($url, "rb");
spip_log("connexion vers $url par simple fopen");
$fopen = true;
$http_proxy = need_proxy($host);
if ($user) $user = urlencode($user[0]) . ":" . urlencode($user[1]);
+ $connect = "";
if ($http_proxy){
- $path = (($scheme=='ssl') ? 'https://' : "$scheme://")
- . (!$user ? '' : "$user@")
- . "$host" . (($port!=80) ? ":$port" : "") . $path;
+ if (defined('_PROXY_HTTPS_VIA_CONNECT') AND $scheme=="ssl"){
+ $path_host = (!$user ? '' : "$user@") . $host . (($port!=80) ? ":$port" : "");
+ $connect = "CONNECT " .$path_host." $vers\r\n"
+ ."Host: $path_host\r\n"
+ ."Proxy-Connection: Keep-Alive\r\n";
+ }
+ else {
+ $path = (($scheme=='ssl') ? 'https://' : "$scheme://")
+ . (!$user ? '' : "$user@")
+ . "$host" . (($port!=80) ? ":$port" : "") . $path;
+ }
$t2 = @parse_url($http_proxy);
$first_host = $t2['host'];
if (!($port = $t2['port'])) $port = 80;
else
$first_host = $noproxy . $host;
- $f = @fsockopen($first_host, $port);
- spip_log("Recuperer $path sur $first_host:$port par $f");
- if (!$f) return false;
+ if ($connect){
+ $streamContext = stream_context_create(array('ssl' => array('verify_peer' => false, 'allow_self_signed' => true)));
+ $f = @stream_socket_client("tcp://$first_host:$port", $nError, $sError, 10, STREAM_CLIENT_CONNECT, $streamContext);
+ spip_log("Recuperer $path sur $first_host:$port par $f (via CONNECT)","connect");
+ if (!$f) return false;
+ stream_set_timeout($f, 10);
+
+ fputs($f, $connect);
+ fputs($f, "\r\n");
+ $res = fread($f, 1024);
+ if (!$res
+ OR !count($res = explode(' ',$res))
+ OR $res[1]!=='200'){
+ spip_log("Echec CONNECT sur $first_host:$port","connect"._LOG_INFO_IMPORTANTE);
+ fclose($f);
+ return false;
+ }
+ // important, car sinon on lit trop vite et les donnees ne sont pas encore dispo
+ stream_set_blocking($f, true);
+ // envoyer le handshake
+ stream_socket_enable_crypto($f, true, STREAM_CRYPTO_METHOD_SSLv23_CLIENT);
+ spip_log("OK CONNECT sur $first_host:$port","connect");
+ }
+ else {
+ $f = @fsockopen($first_host, $port);
+ spip_log("Recuperer $path sur $first_host:$port par $f");
+ if (!$f) return false;
+ }
$site = $GLOBALS['meta']["adresse_site"];
return $f;
}
-?>