function url_absolue($url, $base='') { if (strlen($url = trim($url)) == 0) return ''; if (!$base) $base = url_de_base() . (_DIR_RACINE ? _DIR_RESTREINT_ABS : ''); return suivre_lien($base, $url); }
function urls_absolues_css($contenu, $source) { $path = suivre_lien(url_absolue($source), './'); return preg_replace_callback(",url\\s*\\(\\s*['\"]?([^'\"/][^:]*)['\"]?\\s*\\),Uims", create_function('$x', 'return "url(\\"".suivre_lien("' . $path . '",$x[1])."\\")";'), $contenu); }
function recuperer_lapage($url, $trans = false, $get = 'GET', $taille_max = _INC_DISTANT_MAX_SIZE, $datas = '', $refuser_gz = false, $date_verif = '', $uri_referer = '') { // $copy = copier le fichier ? $copy = (is_string($trans) and strlen($trans) > 5); // eviter "false" :-) // si on ecrit directement dans un fichier, pour ne pas manipuler // en memoire refuser gz if ($copy) { $refuser_gz = true; } // ouvrir la connexion et envoyer la requete et ses en-tetes list($f, $fopen) = init_http($get, $url, $refuser_gz, $uri_referer, $datas, _INC_DISTANT_VERSION_HTTP, $date_verif); if (!$f) { 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 (is_numeric($headers)) { fclose($f); // 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); } else { return false; } } if (!is_array($headers)) { // cas Location fclose($f); include_spip('inc/filtres'); return suivre_lien($url, $headers); } $headers = join('', $headers); } if ($trans === NULL) { return array($headers, ''); } // s'il faut deballer, le faire via un fichier temporaire // sinon la memoire explose pour les gros flux $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); if (!$result) { return array($headers, $result); } // Decompresser au besoin if ($gz) { $result = join('', gzfile($gz)); supprimer_fichier($gz); } // Faut-il l'importer dans notre charset local ? if ($trans === true) { include_spip('inc/charsets'); $result = transcoder_page($result, $headers); } return array($headers, $result); }
function concat_url($url1, $path){ # methode spip if(function_exists('suivre_lien')) { return suivre_lien($url1,$path); } $url = $url1 . "/" . $path; //cette operation peut tres facilement avoir genere // ou /// $url = str_replace("///", "/", $url); $url = str_replace("//", "/", $url); //cas particulier de http:// $url = str_replace("http:/", "http://", $url); return $url; }
/** * Resoudre et inliner les @import * ceux-ci ne peuvent etre presents qu'en debut de CSS et on ne veut pas changer l'ordre des directives * * @param string $contenu * @param string $url_base * @return string */ function css_resolve_atimport($contenu, $url_base) { // vite si rien a faire if (strpos($contenu, "@import") === false) { return $contenu; } $imports_non_resolvables = array(); preg_match_all(",@import ([^;]*);,UmsS", $contenu, $matches, PREG_SET_ORDER); if ($matches and count($matches)) { foreach ($matches as $m) { $url = $media = $erreur = ""; if (preg_match(",^\\s*url\\s*\\(\\s*['\"]?([^'\"]*)['\"]?\\s*\\),Ums", $m[1], $r)) { $url = $r[1]; $media = trim(substr($m[1], strlen($r[0]))); } elseif (preg_match(",^\\s*['\"]([^'\"]+)['\"],Ums", $m[1], $r)) { $url = $r[1]; $media = trim(substr($m[1], strlen($r[0]))); } if (!$url) { $erreur = "Compresseur : <tt>" . $m[0] . ";</tt> non resolu dans <tt>{$url_base}</tt>"; } else { $url = suivre_lien($url_base, $url); // url relative ? $root = protocole_implicite($GLOBALS['meta']['adresse_site'] . "/"); if (strncmp($url, $root, strlen($root)) == 0) { $url = _DIR_RACINE . substr($url, strlen($root)); } else { // si l'url a un protocole http(s):// on ne considère qu'on ne peut pas // résoudre le stockage. Par exemple // @import url(https://fonts.googleapis.com/css?family=Ubuntu); // retournant un contenu différent en fonction navigateur // tous les @import restant seront remontes en tete de CSS en fin de concatenation if (preg_match(',^https?://,', $url)) { $url = ""; } else { // protocole implicite // $url = "http:{$url}"; } } if ($url) { // on renvoit dans la boucle pour que le fichier inclus // soit aussi processe (@import, url absolue etc...) $css = compresseur_callback_prepare_css($url); if ($css == $url or !lire_fichier($css, $contenu_imported)) { $erreur = "Compresseur : url {$url} de <tt>" . $m[0] . ";</tt> non resolu dans <tt>{$url_base}</tt>"; } else { if ($media) { $contenu_imported = "@media {$media}{\n{$contenu_imported}\n}\n"; } $contenu = str_replace($m[0], $contenu_imported, $contenu); } } } if ($erreur) { $contenu = str_replace($m[0], "/* erreur @ import " . $m[1] . "*/", $contenu); erreur_squelette($erreur); } } } return $contenu; }
/** * Récupère le contenu d'une URL * au besoin encode son contenu dans le charset local * * @uses init_http() * @uses recuperer_entetes() * @uses recuperer_body() * @uses transcoder_page() * * @param string $url * @param array $options * bool transcoder : true si on veut transcoder la page dans le charset du site * string methode : Type de requête HTTP à faire (HEAD, GET ou POST) * int taille_max : Arrêter le contenu au-delà (0 = seulement les entetes ==> requête HEAD). Par defaut taille_max = 1Mo ou 16Mo si copie dans un fichier * string|array datas : Pour faire un POST de données (force la methode POST si non vide) * string boundary : boundary pour formater les datas au format array * bool refuser_gz : Pour forcer le refus de la compression (cas des serveurs orthographiques) * int if_modified_since : Un timestamp unix pour arrêter la récuperation si la page distante n'a pas été modifiée depuis une date donnée * string uri_referer : Pour préciser un référer différent * string file : nom du fichier dans lequel copier le contenu * int follow_location : nombre de redirections a suivre (0 pour ne rien suivre) * string version_http : version du protocole HTTP a utiliser (par defaut defini par la constante _INC_DISTANT_VERSION_HTTP) * @return array|bool * false si echec * array sinon : * int status : le status de la page * string headers : les entetes de la page * string page : le contenu de la page (vide si copie dans un fichier) * int last_modified : timestamp de derniere modification * string location : url de redirection envoyee par la page * string url : url reelle de la page recuperee * int length : taille du contenu ou du fichier * * string file : nom du fichier si enregistre dans un fichier */ function recuperer_url($url, $options = array()) { $default = array('transcoder' => false, 'methode' => 'GET', 'taille_max' => null, 'datas' => '', 'boundary' => '', 'refuser_gz' => false, 'if_modified_since' => '', 'uri_referer' => '', 'file' => '', 'follow_location' => 10, 'version_http' => _INC_DISTANT_VERSION_HTTP); $options = array_merge($default, $options); // copier directement dans un fichier ? $copy = $options['file']; if ($options['methode'] == "HEAD") { $options['taille_max'] = 0; } if (is_null($options['taille_max'])) { $options['taille_max'] = $copy ? _COPIE_LOCALE_MAX_SIZE : _INC_DISTANT_MAX_SIZE; } if (!empty($options['datas'])) { $options['methode'] = 'POST'; list($head, $postdata) = prepare_donnees_post($options['datas'], $options['boundary']); if (stripos($head, "Content-Length:") === false) { $head .= 'Content-Length: ' . strlen($postdata); } $options['datas'] = $head . "\r\n\r\n" . $postdata; } // Accepter les URLs au format feed:// ou qui ont oublie le http:// ou les urls relatives au protocole $url = preg_replace(',^feed://,i', 'http://', $url); if (!tester_url_absolue($url)) { $url = 'http://' . $url; } elseif (strncmp($url, "//", 2) == 0) { $url = 'http:' . $url; } $result = array('status' => 0, 'headers' => '', 'page' => '', 'length' => 0, 'last_modified' => '', 'location' => '', 'url' => $url); // si on ecrit directement dans un fichier, pour ne pas manipuler en memoire refuser gz $refuser_gz = ($options['refuser_gz'] or $copy) ? true : false; // ouvrir la connexion et envoyer la requete et ses en-tetes list($handle, $fopen) = init_http($options['methode'], $url, $refuser_gz, $options['uri_referer'], $options['datas'], $options['version_http'], $options['if_modified_since']); if (!$handle) { 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) { $res = recuperer_entetes_complets($handle, $options['if_modified_since']); if (!$res) { fclose($handle); $t = @parse_url($url); $host = $t['host']; // Chinoisierie inexplicable pour contrer // les actions liberticides de l'empire du milieu if (!need_proxy($host) and $res = @file_get_contents($url)) { $result['length'] = strlen($res); if ($copy) { ecrire_fichier($copy, $res); $result['file'] = $copy; } else { $result['page'] = $res; } $res = array('status' => 200); } else { return false; } } elseif ($res['location'] and $options['follow_location']) { $options['follow_location']--; fclose($handle); include_spip('inc/filtres'); $url = suivre_lien($url, $res['location']); spip_log("recuperer_url recommence sur {$url}"); return recuperer_url($url, $options); } elseif ($res['status'] !== 200) { spip_log("HTTP status " . $res['status'] . " pour {$url}"); } $result['status'] = $res['status']; if (isset($res['headers'])) { $result['headers'] = $res['headers']; } if (isset($res['last_modified'])) { $result['last_modified'] = $res['last_modified']; } if (isset($res['location'])) { $result['location'] = $res['location']; } } // on ne veut que les entetes if (!$options['taille_max'] or $options['methode'] == 'HEAD' or $result['status'] == "304") { return $result; } // s'il faut deballer, le faire via un fichier temporaire // sinon la memoire explose pour les gros flux $gz = false; if (preg_match(",\\bContent-Encoding: .*gzip,is", $result['headers'])) { $gz = _DIR_TMP . md5(uniqid(mt_rand())) . '.tmp.gz'; } // si on a pas deja recuperer le contenu par une methode detournee if (!$result['length']) { $res = recuperer_body($handle, $options['taille_max'], $gz ? $gz : $copy); fclose($handle); if ($copy) { $result['length'] = $res; $result['file'] = $copy; } elseif ($res) { $result['page'] =& $res; $result['length'] = strlen($result['page']); } } if (!$result['page']) { return $result; } // Decompresser au besoin if ($gz) { $result['page'] = implode('', gzfile($gz)); supprimer_fichier($gz); } // Faut-il l'importer dans notre charset local ? if ($options['transcoder']) { include_spip('inc/charsets'); $result['page'] = transcoder_page($result['page'], $result['headers']); } return $result; }
/** * fonction sans finesse mais efficace * on parcourt ligne par ligne a la recherche de balise <a> ou <link> * si dans le corps de celle-ci on trouve les mots rss, xml, atom ou rdf * alors on recupere la valeur href='<url>', on adapte celle-ci si elle * est relative et on verifie que c'est bien un feed si oui on l'ajoute * au tableau des feed si on ne trouve rien ou si aucun feed est trouve on retourne * un tableau vide * * @param string $url * L'URL à analyser * @param $buffer * @return array $feed_list * Le tableau des feed trouvés dans la page */ function get_feed_from_url($url, $buffer = false) { global $verif_complete; //j'ai prevenu ce sera pas fin if (!preg_match("/^http:\\/\\/.*/", $url)) { $url = "http://www." . $url; } if (!$buffer) { $buffer = @file_get_contents($url); } include_spip("inc/filtres"); $feed_list = array(); //extraction des <link> if ($links = extraire_balises($buffer, "link")) { //y a t-y rss atom rdf ou xml dans ces balises foreach ($links as $link) { if ((strpos($link, "rss") || strpos($link, "rdf") || strpos($link, "atom") || strpos($link, "xml")) && (!strpos($link, 'opensearch') && !strpos($link, 'oembed'))) { //voila un candidat on va extraire sa partie href et la placer dans notre tableau if ($href = extraire_attribut($link, "href")) { //on aura pris soin de verifier si ce lien est relatif d'en faire un absolu $href = suivre_lien($url, $href); if (!$verif_complete or is_feed($href)) { $feed_list[] = $href; } } } } } //extraction des <a> if ($links = extraire_balises($buffer, "a")) { //y a t-y rss atom rdf ou xml dans ces balises foreach ($links as $link) { if ((strpos($link, "rss") || strpos($link, "rdf") || strpos($link, "atom") || strpos($link, "xml")) && (!strpos($link, 'opensearch') && !strpos($link, 'oembed'))) { //voila un candidat on va extraire sa partie href et la placer dans notre tableau if ($href = extraire_attribut($link, "href")) { //on aura pris soin de verifier si ce lien est relatif d'en faire un absolu $href = suivre_lien($url, $href); if (!$verif_complete or is_feed($href)) { $feed_list[] = $href; } } } } } // si c'est un site SPIP, tentons l'url connue if (!count($feed_list) and (strpos($url, "spip") or stripos($buffer, "spip"))) { $href = suivre_lien($url, "spip.php?page=backend"); if (is_feed($href)) { $feed_list[] = $href; } } return $feed_list; }
function ajouter_tags($matches, $item) { include_spip('inc/filtres'); $tags = array(); foreach ($matches as $match) { $type = ($match[3] == 'category' or $match[3] == 'directory') ? 'directory' : 'tag'; $mot = supprimer_tags($match[0]); if (!strlen($mot) and !strlen($mot = extraire_attribut($match[0], 'label'))) { break; } // rechercher un url if ($url = extraire_attribut($match[0], 'domain')) { // category@domain est la racine d'une url qui se prolonge // avec le contenu text du tag <category> ; mais dans SPIP < 2.0 // on donnait category@domain = #URL_RUBRIQUE, et // text = #TITRE_RUBRIQUE ; d'ou l'heuristique suivante sur le slash if (substr($url, -1) == '/') { $url .= rawurlencode($mot); } } else { if ($url = extraire_attribut($match[0], 'resource') or $url = extraire_attribut($match[0], 'url')) { } else { if (extraire_attribut($match[0], 'scheme') == 'urn:flickr:tags') { foreach (explode(' ', $mot) as $petit) { if ($t = creer_tag($petit, $type, 'http://www.flickr.com/photos/tags/' . rawurlencode($petit) . '/')) { $tags[] = $t; } } $mot = ''; } else { if ($term = extraire_attribut($match[0], 'term')) { if ($scheme = extraire_attribut($match[0], 'scheme')) { $url = suivre_lien($scheme, $term); } else { $url = $term; } } else { # type delicious.com foreach (explode(' ', $mot) as $petit) { if (preg_match(',<rdf\\b[^>]*\\bresource=["\']([^>]*/' . preg_quote(rawurlencode($petit), ',') . ')["\'],i', $item, $m)) { $mot = ''; if ($t = creer_tag($petit, $type, $m[1])) { $tags[] = $t; } } } } } } } if ($t = creer_tag($mot, $type, $url)) { $tags[] = $t; } } return $tags; }
function urls_absolues_css($contenu, $source) { $path = suivre_lien(url_absolue($source),'./'); $contenu = preg_replace_callback( ",url\s*\(\s*['\"]?([^'\"/][^:]*)['\"]?\s*\),Uims", create_function('$x', 'return "url(\"".suivre_lien("'.$path.'",$x[1])."\")";' ), $contenu); // les directives filter ... progid:DXImageTransform.Microsoft.AlphaImageLoader(src=...,..) // de IEx prennent des urls relatives a la page, et non a la css // ne pas y toucher. /* $contenu = preg_replace_callback( ";\(\s*src=['\"]?([^'\"/][^:]*)['\"]?\s*(,|\));Uims", create_function('$x', 'return "(src=\"".suivre_lien("'.$path.'",$x[1])."\"".$x[2];' ), $contenu); */ return $contenu; }