Skip to content
Extraits de code Groupes Projets
Valider f4cca4fd rédigé par esj's avatar esj
Parcourir les fichiers

Faciliter l'envoi d'en-tetes http dans les squelettes, afin de remplacer les...

Faciliter l'envoi d'en-tetes http dans les squelettes, afin de remplacer les variables PHP $flag_preserver et $flag_dynamique par des entitees independantes du langage d'execution. Pour cela: 

- introduction d'une balise #HTTP{e1, ... en} utilisable en debut de squelette, et dont les arguments sont des chaines, entourees de guillemets ou d'apostrophes, conforme au protocole HTTP1/1 :
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4

- cette balise est compilee en une sequence
<?php header(e1); .... ;header(en) ?>

- Spip repere une telle sequence initiale (c'est donc valable aussi pour un code php ecrit directement sous-reserve que la syntaxe soit exactement la meme) et en fait une meta-donnee pour chaque page produite par l'execution du squelette, afin de disposer facilement des en-tetes au moment de l'envoi;

- Spip repere dans ces meta-donnees la presence de la directive Content-Type. Si elle est absente, elle est automatiquement rajoutee avec comme habituellement la valeur:
	Content-Type: text/html; charset=#CHARSET
Spip n'enverra les boutons d'administration et de previsualisation et n'inserera leur CSS associee que si cette directive a pour valeur text/html ou que le mode debug est actif. 
Cette assertion simple reflete l'usage de la variable $flag_preserver qui n'a ainsi plus de raison d'etre.

- Spip repere aussi dans ces meta-donnees la presence d'une directive "Cache-control", auquel cas il n'enverra aucune autre directive concernant le cache du client. Ainsi, le positionnement a "vrai" de la variable $flag_dynamique, jamais documentee, est equivalent a
	#HTTP{'Pragma: no-cache', 'Cache-Control: no-cache; must-revalidate'}
parent c7bd9075
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
<?php
@header('Content-type: text/xml[; charset=(#CHARSET)]');
echo '<'.'?xml version="1.0"[ encoding="(#CHARSET)"]?'.">\n";
?>
<?php @header("Content-type: text/xml[; charset=(#CHARSET)]"); echo '<'.'?xml version="1.0"[ encoding="(#CHARSET)"]?'.">\n"; ?>
<rss version="2.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
......
<?php header("Content-Type: text/javascript") ?>
#HTTP**{"Content-Type: text/javascript"}
document.write('<table border="0" bgcolor="#000000" cellspacing="0" cellpadding="0"><tr><td>');
document.write('<table border="0" bgcolor="#ffffff" cellspacing="1" cellpadding="2"><tr><td bgcolor="#d0d0d0" align="center">');
document.write('<a href="#URL_SITE_SPIP/"><b>[(#NOM_SITE_SPIP|addslashes)]</b></a>&nbsp;</td></tr><tr><td><ul><small>');
......
#HTTP**{"Cache-Control: no-store, no-cache, must-revalidate",
"Pragma: no-cache"}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="#LANG_DIR" lang="#LANG">
<head>
......
<?php header ("Content-type: text/calendar") ?>
#HTTP**{"Content-type: text/calendar"}
BEGIN:VCALENDAR
CALSCALE:GREGORIAN
X-WR-CALNAME;VALUE=TEXT:[(#NOM_SITE_SPIP|filtrer_ical)]
......
#HTTP**{"Cache-Control: no-store, no-cache, must-revalidate",
"Pragma: no-cache"}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="#LANG_DIR" lang="#LANG">
<head>
......
......@@ -6,6 +6,7 @@
<!-- Ceci est la feuille de style par defaut pour les types internes a SPIP -->
<link rel="stylesheet" href="spip_style.css" type="text/css" />
<link rel="stylesheet" href="spip_admin.css" type="text/css" />
<!-- Les feuilles de style specifiques aux presents squelettes -->
<link rel="stylesheet" href="#DOSSIER_SQUELETTE/typographie.css" type="text/css" />
......
......@@ -528,11 +528,11 @@ function http_last_modified($lastmodified, $expire = 0) {
}
// envoyer le navigateur sur une nouvelle adresse
// en evitant les attaques par la redirection (souvent indique par 1 $_GET)
function redirige_par_entete($url, $fin="") {
# spip_log("redirige $url$fin");
include_ecrire('inc_headers');
spip_header("Location: $url$fin");
header("Location: " . strtr("$url$fin", "\n\r", " "));
echo '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
......@@ -542,7 +542,7 @@ function redirige_par_entete($url, $fin="") {
<h1>302 Found</h1>
<a href="'
.quote_amp("$url$fin")
.'">Click here</a>.<p>
.'">Click here</a>.
</body></html>';
exit;
......
......@@ -12,8 +12,7 @@ $delais = 3600;
// 2. faire des forums uniquement pour affecter des mots-cles
// $afficher_texte = "non";
// En cas de forums sur abonnement, on a un panneau de login
$flag_dynamique = true;
// forum sur abonnement => login; ne pas oublier le header "no-cache"
include ("inc-public.php3");
......
......@@ -598,9 +598,9 @@ function balise_EXTRA_dist ($p) {
$p->code = $_extra;
// Gerer la notation [(#EXTRA|isbn)]
if ($p->params) {
if ($p->param) {
include_ecrire("inc_extra");
list ($key, $champ_extra) = each($p->params); // le premier filtre
list ($key, $champ_extra) = each($p->param); // le premier filtre
$type_extra = $p->type_requete;
$champ = $champ_extra[1];
......@@ -609,7 +609,7 @@ function balise_EXTRA_dist ($p) {
// on aura le type_extra du sous-objet (!)
if (extra_champ_valide($type_extra, $champ))
{
array_shift($p->params);
array_shift($p->param);
# A quoi ca sert ?
# $p->code = "extra($p->code, '".addslashes($champ)."')";
......@@ -766,4 +766,17 @@ function balise_REM_dist($p) {
return $p;
}
//
// #HTTP
// pour les entetes. A n'utiliser qu'en debut de squelette
//
function balise_HTTP_dist($p) {
$a = $p->param[0];
array_shift($a);
$code = "";
foreach($a as $v) $code .= 'header("' . $v[0]->texte . '");';
$p->code="('<'.'?php $code ?' . '>')";
return $p;
}
?>
......@@ -210,6 +210,8 @@ function creer_cache(&$page, $chemin_cache, $duree) {
// Enregistrer le fichier cache qui contient
// 1) la carte d'identite de la page (ses "globals", genre id_article=7)
// 2) son contenu
$page['signal']['process_ins'] = $page['process_ins'];
$page['signal']['entetes'] = $page['entetes'];
$r = ecrire_fichier($chemin_cache,
"<!-- "
. str_replace("\n", " ", serialize($page['signal']))
......
......@@ -207,7 +207,7 @@ function calculer_contexte() {
function calculer_page_globale($cache, $fond) {
global $lastmodified, $_SERVER, $contexte;
global $_SERVER, $contexte;
$contexte = calculer_contexte();
......@@ -253,8 +253,25 @@ function calculer_page_globale($cache, $fond) {
}
$page['signal'] = $signal;
$page['signal']['process_ins'] = $page['process_ins'];
$lastmodified = time();
return $page;
}
function analyse_resultat_skel($nom, $Cache, $corps)
{
$headers = array();
while (preg_match('/^(<[?]php\s+)@?header\s*\(\s*.([^:]*):\s*([^)]*)[^)]\s*\)\s*[;]?/ims',$corps, $r))
{
$corps = $r[1] . substr($corps,strlen($r[0]));
$j=str_replace(' - ','-',ucwords(str_replace('-',' - ',$r[2])));
$headers[$j] = $r[3];
}
if (preg_match('/^<[?]php\s+[?]>\s*/', $corps, $r))
$corps = substr($corps,strlen($r[0]));
return array('texte' => $corps,
'squelette' => $nom,
'process_ins' => ((strpos($corps,'<'.'?')=== false) ? 'html' : 'php'),
'invalideurs' => $Cache,
'entetes' => $headers);
}
?>
......@@ -39,9 +39,6 @@ include_local("inc-compilo-api");
# definition des tables
include_ecrire('inc_serialbase');
// outils pour debugguer le compilateur
#include_local("inc-compilo-debug"); # desactive
//
// Calculer un <INCLURE()>
//
......@@ -385,7 +382,7 @@ function calculer_liste($tableau, $descr, &$boucles, $id_boucle='') {
join(" ,\n$tab", $codes) . "))";
}
function compile_cas($tableau, $descr, &$boucles, $id_boucle='') {
function compile_cas($tableau, $descr, &$boucles, $id_boucle) {
$codes = array();
// cas de la boucle recursive
if (is_array($id_boucle))
......@@ -558,11 +555,12 @@ function code_boucle(&$boucles, $id, $nom)
// Pour appeler la fonction produite, lui fournir 2 tableaux de 1 e'le'ment:
// - 1er: element 'cache' => nom (du fichier ou` mettre la page)
// - 2e: element 0 contenant un environnement ('id_article => $id_article, etc)
// Elle retourne alors un tableau de 4 e'le'ments:
// Elle retourne alors un tableau de 5 e'le'ments:
// - 'texte' => page HTML, application du squelette a` l'environnement;
// - 'squelette' => le nom du squelette
// - 'process_ins' => 'html' ou 'php' selon la pre'sence de PHP dynamique
// - 'invalideurs' => de'pendances de cette page, pour invalider son cache.
// - 'entetes' => tableau des entetes http
// (voir son utilisation, optionnelle, dans invalideur.php)
// En cas d'erreur, elle retourne un tableau des 2 premiers elements seulement
......@@ -690,14 +688,8 @@ function calculer_squelette($squelette, $nom, $gram, $sourcefile) {
// Fonction principale du squelette $sourcefile
//
function $nom (\$Cache, \$Pile, \$doublons=array(), \$Numrows='', \$SP=0) {
\$t0 = $corps;
return array(
'texte' => \$t0,
'squelette' => '$nom',
'process_ins' => ((strpos(\$t0,'<'.'?')=== false) ? 'html' : 'php'),
'invalideurs' => \$Cache
);
return analyse_resultat_skel('$nom', \$Cache, $corps);
}
?".">";
......
......@@ -70,6 +70,7 @@ function calcule_header_et_page ($fond) {
function obtenir_page_ancienne ($chemin_cache, $fond, $inclusion=false) {
global $lastmodified ;
//
// Lire le fichier cache
//
......@@ -114,14 +115,18 @@ function is_preview()
// calculer la page principale et envoyer les entetes
//
function afficher_page_globale ($fond) {
global $flag_dynamique, $flag_ob, $flag_preserver,
$lastmodified, $recherche, $use_cache, $var_mode, $var_preview;
global $_GET, $_POST, $_COOKIE, $_SERVER;
global $flag_dynamique, $flag_ob, $flag_preserver,$lastmodified,
$use_cache, $var_mode, $var_preview;
global $_COOKIE, $_SERVER;
include_local("inc-cache");
// Peut-on utiliser un fichier cache ?
$chemin_cache = determiner_cache($use_cache, NULL, $fond);
if ($chemin_cache)
$lastmodified = @filemtime($chemin_cache);
else
$lastmodified = time();
// demande de previsualisation ?
// -> inc-calcul n'enregistrera pas les fichiers caches
......@@ -130,92 +135,109 @@ function afficher_page_globale ($fond) {
$var_mode = 'recalcul';
$var_preview = true;
spip_log('preview !');
} else
$var_preview = false;
} else $var_preview = false;
$headers_only = ($_SERVER['REQUEST_METHOD'] == 'HEAD');
// une perennite valide a meme reponse qu'une requete HEAD
// Repondre gentiment aux requetes sympas
// (ici on ne tient pas compte d'une obsolence du cache ou des
// eventuels fichiers inclus modifies depuis la date
// HTTP_IF_MODIFIED_SINCE du client)
if ($GLOBALS['HTTP_IF_MODIFIED_SINCE'] AND !$var_mode
AND $chemin_cache AND !$flag_dynamique) {
$lastmodified = @filemtime($chemin_cache);
$headers_only = http_last_modified($lastmodified);
if (!preg_match(',IIS/,', $_SERVER['SERVER_SOFTWARE'])) {
$since = preg_replace('/;.*/', '',
$GLOBALS['HTTP_IF_MODIFIED_SINCE']);
$since = str_replace('GMT', '', $since);
if (trim($since) == http_gmoddate($lastmodified)) {
$status = 304;
$headers_only = true;
}
}
}
$headers_only |= ($_SERVER['REQUEST_METHOD'] == 'HEAD');
// si le last-modified (mis + bas) est suffisant, ne meme pas mettre
// de content-type (pour contrer le bouton admin de inc-public)
if ($headers_only) {
if ($chemin_cache)
$t = @filemtime($chemin_cache);
else
$t = time();
@header('Last-Modified: '.http_gmoddate($t).' GMT');
@header('Connection: close');
// Pas de bouton admin pour un HEAD
$flag_preserver = true;
}
else {
// Obtenir la page
$page['entetes']["Connection"] = "close";
} else {
if (!$use_cache)
$page = obtenir_page_ancienne ($chemin_cache, $fond, false);
else {
include_local('inc-calcul');
$page = calculer_page_globale ($chemin_cache, $fond);
if ($chemin_cache)
creer_cache($page, $chemin_cache, $use_cache);
}
}
if ($chemin_cache) $page['cache'] = $chemin_cache;
if ($chemin_cache) $page['cache'] = $chemin_cache;
if ($page['process_ins'] == 'php') {
if (!isset($flag_preserver))
$flag_preserver = preg_match("/header\s*\(\s*.content\-type:/isx",$page['texte']);
// compatibilite. devrait pouvoir sauter
if ($page['process_ins'] == 'php') {
auto_content_type($page['texte']);
auto_expire($page['texte']);
}
$expire = preg_match("/header\s*\(\s*.Expire:([\s\d])*.\s*\)/is",$php, $r);
if (!isset($flag_dynamique))
$flag_dynamique = $expire && (intval($r[1]) === 0);
}
$flag_preserver |= (headers_sent());
if ($var_preview AND !$flag_preserver) {
include_ecrire('inc_minipres');
$page['texte'] .= afficher_bouton_preview();
}
//
// Envoyer les entetes appropries
// a condition d'etre sur de pouvoir le faire
//
if (!headers_sent() AND !$flag_preserver) {
// Definir les entetes si ce n'est fait
// Content-type: par defaut html+charset (poss surcharge par la suite)
header("Content-Type: text/html; charset=".$GLOBALS['meta']['charset']);
if (!$flag_preserver) {
if ($flag_ob) {
// Si la page est vide, produire l'erreur 404
if (trim($page['texte']) === ''
AND $var_mode != 'debug') {
$page = message_erreur_404();
}
// Interdire au client de cacher un login, un admin ou un recalcul
else if ($flag_dynamique OR $var_mode
OR $_COOKIE['spip_admin']) {
header("Cache-Control: no-cache,must-revalidate");
header("Pragma: no-cache");
if (!isset($page['entetes']['Content-Type'])) {
$page['entetes']['Content-Type'] =
"text/html; charset="
. $GLOBALS['meta']['charset'];
}
// Pour les autres donner l'heure de modif
else if ($lastmodified) {
header("Last-Modified: ".http_gmoddate($lastmodified)." GMT");
if ($flag_ob) {
// Si la page est vide, produire l'erreur 404
if (trim($page['texte']) === ''
AND $var_mode != 'debug') {
$page = message_erreur_404();
$status = 404;
$flag_dynamique = true;
}
// pas de mise en cache pour les observateurs (et si pas deja indique)
if ($flag_dynamique
OR $_COOKIE['spip_admin']
OR $var_mode) {
$page['entetes']["Cache-Control"]= "no-cache,must-revalidate";
$page['entetes']["Pragma"] = "no-cache";
}
}
}
}
// toujours utile
$page['entetes']["Last-Modified"]=http_gmoddate($lastmodified)." GMT";
$page['status'] = $status;
return $page;
}
//
// 2 fonctions pour compatibilite arriere. Sont probablement superflues
//
function auto_content_type($code)
{
global $flag_preserver;
if (!isset($flag_preserver))
$flag_preserver = preg_match("/header\s*\(\s*.content\-type:/isx",$code);
}
function auto_expire($code)
{
global $flag_dynamique;
if (!isset($flag_dynamique)) {
if (preg_match("/header\s*\(\s*.Expire:([\s\d])*.\s*\)/is",$code, $r))
$flag_dynamique = (intval($r[1]) === 0);
}
}
function inclure_page($fond, $contexte_inclus, $cache_incluant='') {
global $lastmodified;
// Peut-on utiliser un fichier cache ?
$chemin_cache = determiner_cache($use_cache, $contexte_inclus, $fond);
......@@ -242,7 +264,6 @@ function inclure_page($fond, $contexte_inclus, $cache_incluant='') {
else {
include_local('inc-calcul');
$page = cherche_page($chemin_cache, $contexte_inclus, $fond, false);
$page['signal']['process_ins'] = $page['process_ins'];
$lastmodified = time();
if ($chemin_cache) creer_cache($page, $chemin_cache, $use_cache);
}
......@@ -319,9 +340,6 @@ function message_erreur_404 ($erreur= "") {
else if (isset($GLOBALS['id_syndic']))
$erreur = 'public:aucun_site';
}
include_ecrire('inc_headers');
http_status(404);
return array('texte' => '<'.'?php
$contexte_inclus = array("fond" => 404,
"erreur" => _T("' . $erreur . '"));
......
......@@ -29,15 +29,29 @@ if (defined("_INC_PUBLIC")) {
}
include_local('inc-public-global');
// Calculer la page en envoyant seulement les en-tetes, pas la page
$tableau_des_erreurs = array();
$page = calcule_header_et_page ($fond);
if ($page['status']) {
include_ecrire('inc_headers');
http_status($page['status']);
}
foreach($page['entetes'] as $k => $v)
{ header("$k: $v");}
$html= preg_match(',^\s*text/html,',$page['entetes']['Content-Type']);
if ($var_preview AND $html) {
include_ecrire('inc_minipres');
$page['texte'] .= afficher_bouton_preview();
}
// est-on admin ?
if ($affiche_boutons_admin = (
(!$flag_preserver AND $GLOBALS['_COOKIE']['spip_admin'])
OR $var_mode == 'debug'))
include_local(find_in_path('inc-formulaire_admin'. _EXTENSION_PHP));
if ($affiche_boutons_admin = ($_COOKIE['spip_admin']
AND ($html OR ($var_mode == 'debug'))))
include_local(find_in_path('inc-formulaire_admin'. _EXTENSION_PHP));
// Execution de la page calculee
// 1. Cas d'une page contenant uniquement du HTML :
......@@ -94,7 +108,7 @@ if (defined("_INC_PUBLIC")) {
}
// Valider/indenter a la demande. garder la compatibilite tidy
if (trim($page) AND $xhtml AND !$flag_preserver AND !headers_sent()) {
if (trim($page) AND $xhtml AND $html AND !headers_sent()) {
$f = include_fonction(($xhtml === true) ? 'tidy' : $xhtml);
$page = $f($page);
}
......
......@@ -12,8 +12,6 @@
$fond = "login";
$delais = 3600;
$flag_dynamique = true;
$flag_preserver = true;
$forcer_lang = true;
// Compatibilite anciennes versions de SPIP : si un 'var_url' (cible du login)
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter