/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
- * Copyright (c) 2001-2014 *
+ * Copyright (c) 2001-2016 *
* Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
* *
* Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
if (!defined('_INC_DISTANT_CONTENT_ENCODING')) define('_INC_DISTANT_CONTENT_ENCODING', "gzip");
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);
+if (!defined('_INC_DISTANT_CONNECT_TIMEOUT')) define('_INC_DISTANT_CONNECT_TIMEOUT',10);
define('_REGEXP_COPIE_LOCALE', ',' .
preg_replace('@^https?:@', 'https?:', $GLOBALS['meta']['adresse_site'])
* 'force' - charger toujours (mettre a jour)
* @param string $local
* permet de specifier le nom du fichier local (stockage d'un cache par exemple, et non document IMG)
+ * @param int $taille_max
+ * taille maxi de la copie local, par defaut _COPIE_LOCALE_MAX_SIZE
* @return bool|string
*/
-function copie_locale($source, $mode='auto', $local = null) {
+function copie_locale($source, $mode='auto', $local=null, $taille_max=null){
// si c'est la protection de soi-meme, retourner le path
if ($mode !== 'force' AND preg_match(_REGEXP_COPIE_LOCALE, $source, $match)) {
// passer par un fichier temporaire unique pour gerer les echecs en cours de recuperation
// et des eventuelles recuperations concurantes
include_spip("inc/acces");
- $res = recuperer_page($source, $localrac, false, _COPIE_LOCALE_MAX_SIZE, '', '', false, $t ? filemtime($localrac) : '');
+ if (!$taille_max) $taille_max = _COPIE_LOCALE_MAX_SIZE;
+ $res = recuperer_page($source, $localrac, false, $taille_max, '', '', false, $t ? filemtime($localrac) : '');
if (!$res) {
if (!$t) // si $t c'est sans doute juste un not-modified-since qui fait renvoyer false
spip_log("copie_locale : Echec recuperation $source sur $localrac",_LOG_INFO_IMPORTANTE);
return array($entete, $chaine);
}
+/**
+ * Convertir une URL dont le host est en utf8 en ascii
+ * Utilise la librairie https://github.com/phlylabs/idna-convert/tree/v0.9.1
+ * dans sa derniere version compatible toutes version PHP 5
+ * La fonction PHP idn_to_ascii depend d'un package php5-intl et est rarement disponible
+ *
+ * @param string $url_idn
+ * @return array|string
+ */
+function url_to_ascii($url_idn) {
+
+ if ($parts = parse_url($url_idn)) {
+ $host = $parts['host'];
+ if (!preg_match(',^[a-z0-9_\.\-]+$,i', $host)) {
+ include_spip('inc/idna_convert.class');
+ $IDN = new idna_convert();
+ $host_ascii = $IDN->encode($host);
+ $url_idn = explode($host, $url_idn, 2);
+ $url_idn = implode($host_ascii, $url_idn);
+ }
+ }
+
+ return $url_idn;
+}
+
//
// Recupere une page sur le net
// et au besoin l'encode dans le charset local
// Accepter les URLs au format feed:// ou qui ont oublie le http://
$url = preg_replace(',^feed://,i', 'http://', $url);
if (!preg_match(',^[a-z]+://,i', $url)) $url = 'http://' . $url;
+ $url = url_to_ascii($url);
if ($taille_max==0)
$get = 'HEAD';
// http://doc.spip.org/@recuperer_infos_distantes
function recuperer_infos_distantes($source, $max = 0, $charger_si_petite_image = true){
+ // pas la peine de perdre son temps
+ if (!tester_url_absolue($source)) {
+ return false;
+ }
+
# charger les alias des types mime
include_spip('base/typedoc');
global $mime_alias;
$a = recuperer_infos_distantes($source, _INC_DISTANT_MAX_SIZE);
}
+ // si on a rien trouve pas la peine d'insister
+ if (!$a) {
+ return false;
+ }
+
// S'il s'agit d'une image pas trop grosse ou d'un fichier html, on va aller
// recharger le document en GET et recuperer des donnees supplementaires...
if (preg_match(',^image/(jpeg|gif|png|swf),', $mime_type)){
$scheme = 'http';
$noproxy = '';
} elseif ($t['scheme']=='https') {
- $scheme = 'ssl';
- $noproxy = 'ssl://';
+ $scheme = 'tls';
+ $noproxy = 'tls://';
if (!isset($t['port']) || !($port = $t['port'])) $t['port'] = 443;
}
else {
if (!$f){
// fallback : fopen
if (!need_proxy($host)
- AND !_request('tester_proxy')){
+ AND !_request('tester_proxy')
+ AND (!isset($GLOBALS['inc_distant_allow_fopen']) OR $GLOBALS['inc_distant_allow_fopen'])){
$f = @fopen($url, "rb");
spip_log("connexion vers $url par simple fopen");
$fopen = true;
$connect = "";
if ($http_proxy){
- if (defined('_PROXY_HTTPS_VIA_CONNECT') AND $scheme=="ssl"){
+ if (defined('_PROXY_HTTPS_VIA_CONNECT') AND $scheme=="tls"){
$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://")
+ $path = (($scheme=='tls') ? 'https://' : "$scheme://")
. (!$user ? '' : "$user@")
. "$host" . (($port!=80) ? ":$port" : "") . $path;
}
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);
+ $f = @stream_socket_client("tcp://$first_host:$port", $nError, $sError, _INC_DISTANT_CONNECT_TIMEOUT, 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);
+ stream_set_timeout($f, _INC_DISTANT_CONNECT_TIMEOUT);
fputs($f, $connect);
fputs($f, "\r\n");
spip_log("OK CONNECT sur $first_host:$port","connect");
}
else {
- $f = @fsockopen($first_host, $port);
+ $f = @fsockopen($first_host, $port, $errno, $errstr, _INC_DISTANT_CONNECT_TIMEOUT);
spip_log("Recuperer $path sur $first_host:$port par $f");
- if (!$f) return false;
+ if (!$f) {
+ spip_log("Erreur connexion $errno $errstr",_LOG_ERREUR);
+ return false;
+ }
+ stream_set_timeout($f, _INC_DISTANT_CONNECT_TIMEOUT);
}
$site = $GLOBALS['meta']["adresse_site"];