Added ETag support and increased caching settings to try and speed the system up. Result of a YSlow audit.
--- a/cron.php Sun May 04 21:57:48 2008 -0400
+++ b/cron.php Mon May 05 20:06:37 2008 -0400
@@ -42,9 +42,22 @@
}
}
-header('Pragma: no-cache');
-header('Cache-control: no-cache');
-header('Expires: Thu, 1 Jan 1970 00:00:01 GMT');
+$expiry_date = date('r', get_cron_next_run());
+
+$etag = sha1($expiry_date);
+
+if ( isset($_SERVER['HTTP_IF_NONE_MATCH']) )
+{
+ if ( "\"$etag\"" == $_SERVER['HTTP_IF_NONE_MATCH'] )
+ {
+ header('HTTP/1.1 304 Not Modified');
+ exit();
+ }
+}
+
+header("ETag: $etag");
+
+header('Expires: ' . $expiry_date);
header('Content-type: image/gif');
echo ENANO_GIF_SPACER;
--- a/includes/clientside/jsres.php Sun May 04 21:57:48 2008 -0400
+++ b/includes/clientside/jsres.php Mon May 05 20:06:37 2008 -0400
@@ -82,6 +82,19 @@
require('includes/json2.php');
require('includes/js-compressor.php');
+// try to gzip the output
+$do_gzip = false;
+if ( isset($_SERVER['HTTP_ACCEPT_ENCODING']) )
+{
+ $acceptenc = str_replace(' ', '', strtolower($_SERVER['HTTP_ACCEPT_ENCODING']));
+ $acceptenc = explode(',', $acceptenc);
+ if ( in_array('gzip', $acceptenc) )
+ {
+ $do_gzip = true;
+ ob_start();
+ }
+}
+
// Output format will always be JS
header('Content-type: text/javascript');
$everything = '';
@@ -177,9 +190,27 @@
$everything .= "\n" . $file_contents;
}
+// generate ETag
+$etag = base64_encode(hexdecode(sha1($everything)));
+
+if ( isset($_SERVER['HTTP_IF_NONE_MATCH']) )
+{
+ if ( "\"$etag\"" == $_SERVER['HTTP_IF_NONE_MATCH'] )
+ {
+ header('HTTP/1.1 304 Not Modified');
+ exit();
+ }
+}
+
$date = date('r', $apex);
header("Date: $date");
header("Last-Modified: $date");
+header("ETag: \"$etag\"");
echo $everything;
+if ( $do_gzip )
+{
+ gzip_output();
+}
+
--- a/includes/clientside/static/faders.js Sun May 04 21:57:48 2008 -0400
+++ b/includes/clientside/static/faders.js Mon May 05 20:06:37 2008 -0400
@@ -178,16 +178,8 @@
var buttondiv = document.createElement('div');
- if ( is_iPhone )
- {
- mydiv.style.width = '120px';
- buttondiv.style.width = '120px';
- }
- else
- {
- mydiv.style.width = '400px';
- buttondiv.style.width = '400px';
- }
+ mydiv.style.width = '400px';
+ buttondiv.style.width = '400px';
w = getWidth();
h = getHeight();
--- a/includes/functions.php Sun May 04 21:57:48 2008 -0400
+++ b/includes/functions.php Mon May 05 20:06:37 2008 -0400
@@ -2854,11 +2854,11 @@
$gzip_contents = ob_get_contents();
ob_end_clean();
- $return = @ob_gzhandler($gzip_contents);
+ $return = @ob_gzhandler($gzip_contents, PHP_OUTPUT_HANDLER_START);
if ( $return )
{
header('Content-encoding: gzip');
- echo $gzip_contents;
+ echo $return;
}
else
{
@@ -3351,6 +3351,19 @@
}
/**
+ * Gets the timestamp for the next estimated cron run.
+ * @return int
+ */
+
+function get_cron_next_run()
+{
+ global $cron_tasks;
+ $lowest_ivl = min(array_keys($cron_tasks));
+ $last_run = intval(getConfig("cron_lastrun_ivl_$lowest_ivl"));
+ return intval($last_run + ( 3600 * $lowest_ivl )) - 30;
+}
+
+/**
* Installs a language.
* @param string The ISO-639-3 identifier for the language. Maximum of 6 characters, usually 3.
* @param string The name of the language in English (Spanish)
--- a/includes/pageprocess.php Sun May 04 21:57:48 2008 -0400
+++ b/includes/pageprocess.php Mon May 05 20:06:37 2008 -0400
@@ -1178,7 +1178,11 @@
else
{
- $q = $db->sql_query('SELECT page_text, char_tag FROM '.table_prefix.'page_text WHERE page_id=\'' . $this->page_id . '\' AND namespace=\'' . $this->namespace . '\';');
+ $q = $db->sql_query('SELECT t.page_text, t.char_tag, l.time_id FROM '.table_prefix."page_text AS t\n"
+ . " LEFT JOIN " . table_prefix . "logs AS l\n"
+ . " ON ( l.page_id = t.page_id AND l.namespace = t.namespace )\n"
+ . " WHERE t.page_id='$this->page_id' AND t.namespace='$this->namespace'\n"
+ . " ORDER BY l.time_id DESC LIMIT 1;");
if ( !$q )
{
$this->send_error('Error during SQL query.', true);
--- a/includes/sessions.php Sun May 04 21:57:48 2008 -0400
+++ b/includes/sessions.php Mon May 05 20:06:37 2008 -0400
@@ -1139,7 +1139,7 @@
{
// Stash it in a cookie
// For now, make the cookie last forever, we can change this in 1.1.x
- setcookie( 'sid', $session_key, time()+315360000, scriptPath.'/', null, ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ) );
+ setcookie( 'sid', $session_key, time()+15552000, scriptPath.'/', null, ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ) );
$_COOKIE['sid'] = $session_key;
}
// $keyhash is stored in the database, this is for compatibility with the older DB structure
@@ -3223,7 +3223,7 @@
if ( $dh_supported && $dh_pubkey )
{
$code .= <<<EOF
- if ( frm.$dh_supported.value == 'true' )
+ if ( frm.$dh_supported.value == 'true' && !is_iPhone )
use_diffiehellman = true;
EOF;
}
--- a/index.php Sun May 04 21:57:48 2008 -0400
+++ b/index.php Mon May 05 20:06:37 2008 -0400
@@ -45,6 +45,7 @@
require('includes/common.php');
global $db, $session, $paths, $template, $plugins; // Common objects
+ $page_timestamp = time();
if ( !isset($_GET['do']) )
{
@@ -63,6 +64,7 @@
$pagepass = ( isset($_REQUEST['pagepass']) ) ? sha1($_REQUEST['pagepass']) : '';
$page->password = $pagepass;
$page->send(true);
+ $page_timestamp = $page->revision_time;
break;
case 'comments':
$template->header();
@@ -564,6 +566,23 @@
// Re-enable output buffering to allow the Gzip function (below) to work
ob_start();
+ // Generate an ETag
+ // format: first 10 digits of SHA1 of page name, user id in hex, page timestamp in hex
+ $etag = substr(sha1($paths->namespace . ':' . $paths->page_id), 0, 10) . '-' .
+ dechex($session->user_id) . '-' .
+ dechex($page_timestamp);
+
+ if ( isset($_SERVER['HTTP_IF_NONE_MATCH']) )
+ {
+ if ( "\"$etag\"" == $_SERVER['HTTP_IF_NONE_MATCH'] )
+ {
+ header('HTTP/1.1 304 Not Modified');
+ exit();
+ }
+ }
+
+ header("ETag: \"$etag\"");
+
// Done, send it to the user
echo( $html );
}
@@ -571,4 +590,6 @@
$db->close();
gzip_output();
+ @ob_end_flush();
+
?>
--- a/plugins/SpecialUserFuncs.php Sun May 04 21:57:48 2008 -0400
+++ b/plugins/SpecialUserFuncs.php Mon May 05 20:06:37 2008 -0400
@@ -2014,18 +2014,31 @@
else
$lang_local = new Language($lang_id);
+ $lang_strings = enano_json_encode($lang_local->strings);
+ $etag = substr(sha1($lang_strings), 0, 20) . '-' . dechex($lang_local->lang_timestamp);
+
+ if ( isset($_SERVER['HTTP_IF_NONE_MATCH']) )
+ {
+ if ( "\"$etag\"" == $_SERVER['HTTP_IF_NONE_MATCH'] )
+ {
+ header('HTTP/1.1 304 Not Modified');
+ exit();
+ }
+ }
$timestamp = enano_date('D, j M Y H:i:s T', $lang_local->lang_timestamp);
header("Last-Modified: $timestamp");
header("Date: $timestamp");
+ header("ETag: \"$etag\"");
header('Content-type: text/javascript');
$lang_local->fetch();
echo "if ( typeof(enano_lang) != 'object' )
var enano_lang = new Object();
-enano_lang[{$lang->lang_id}] = " . enano_json_encode($lang_local->strings) . ";";
+enano_lang[{$lang->lang_id}] = " . $lang_strings . ";";
+ exit(0);
}
/**
--- a/themes/oxygen/css/bleu.css Sun May 04 21:57:48 2008 -0400
+++ b/themes/oxygen/css/bleu.css Mon May 05 20:06:37 2008 -0400
@@ -129,8 +129,9 @@
td.recttoptop {
width: 100%;
height: 12px;
- background-image: url(../images/bleu/border-menu-t.gif);
+ background-image: url(../images/bleu/sprite-horiz.gif);
background-repeat: repeat-x;
+ background-position: 0 -12px;
margin: 0;
padding: 0;
}
@@ -138,8 +139,9 @@
td.recttoptop:hover {
width: 100%;
height: 12px;
- background-image: url(../images/bleu/border-menu-t-h.gif);
+ background-image: url(../images/bleu/sprite-horiz.gif);
background-repeat: repeat-x;
+ background-position: 0 -24px;
margin: 0;
padding: 0;
cursor: pointer;
@@ -155,8 +157,9 @@
td.rectbottop {
width: 100%;
height: 12px;
- background-image: url(../images/bleu/border-btm.gif);
+ background-image: url(../images/bleu/sprite-horiz.gif);
background-repeat: repeat-x;
+ background-position: 0 -48px;
margin: 0;
padding: 0;
}
@@ -477,28 +480,28 @@
}
/* Rounded corners on nearly everything */
-td#mdg-tl { width: 12px; height: 12px; background: url(../images/bleu/border-tl.gif); }
-td#mdg-tr { width: 12px; height: 12px; background: url(../images/bleu/border-tr.gif); }
-td#mdg-top { background: url(../images/bleu/border-top.gif); }
-td#mdg-l { width: 12px; height: 12px; background: url(../images/bleu/border-l.gif); }
-td#mdg-r { width: 12px; height: 12px; background: url(../images/bleu/border-r.gif); }
-td#mdg-bl { width: 12px; height: 12px; background: url(../images/bleu/border-tb-l.gif); }
-td#mdg-br { width: 12px; height: 12px; background: url(../images/bleu/border-tb-r.gif); }
-td#mdg-ml { width: 12px; height: 12px; background: url(../images/bleu/border-m-l.gif); }
-td#mdg-mr { width: 12px; height: 12px; background: url(../images/bleu/border-m-r.gif); }
-td#mdg-brl { width: 12px; height: 1px; background: url(../images/bleu/border-m-l.gif); }
-td#mdg-brr { width: 12px; height: 1px; background: url(../images/bleu/border-m-r.gif); }
-td#mdg-btl { width: 12px; height: 1px; background: url(../images/bleu/border-btm-l.gif); }
-td#mdg-btr { width: 12px; height: 1px; background: url(../images/bleu/border-btm-r.gif); }
-td#mdg-btcl { width: 12px; height: 12px; background: url(../images/bleu/border-bl.gif); }
-td#mdg-btcr { width: 12px; height: 12px; background: url(../images/bleu/border-br.gif); }
-td#mdg-btm { height: 12px; background: url(../images/bleu/border-btm.gif); }
-td.mdg-menu-top { width: 84%; height: 12px; background: url(../images/bleu/border-menu-t.gif); margin: 0; padding: 0; background-repeat: repeat-x; font-size: 2px; }
-td.mdg-menu-tl { width: 12px; height: 12px; background: url(../images/bleu/border-menu-l.gif); background-position: left top; background-repeat: no-repeat; }
-td.mdg-menu-tr { width: 12px; height: 12px; background: url(../images/bleu/border-menu-r.gif); background-position: right top; background-repeat: no-repeat; }
-td.mdg-menu-bl { width: 12px; height: 12px; background: url(../images/bleu/border-bl.gif); }
-td.mdg-menu-br { width: 12px; height: 12px; background: url(../images/bleu/border-br.gif); }
-td.mdg-menu-btm { height: 12px; background: url(../images/bleu/border-btm.gif); }
+td#mdg-tl { width: 12px; height: 12px; background-image: url(../images/bleu/sprite-horiz.gif); background-position: -48px 0; }
+td#mdg-tr { width: 12px; height: 12px; background-image: url(../images/bleu/sprite-horiz.gif); background-position: -60px 0; }
+td#mdg-top { background-image: url(../images/bleu/sprite-horiz.gif); background-position: 0 -36px; }
+td#mdg-l { width: 12px; height: 12px; background-image: url(../images/bleu/sprite-vert.gif); background-position: -24px 0; }
+td#mdg-r { width: 12px; height: 12px; background-image: url(../images/bleu/sprite-vert.gif); background-position: -36px 0; }
+td#mdg-bl { width: 12px; height: 12px; background-image: url(../images/bleu/sprite-vert.gif); background-position: -72px 0; }
+td#mdg-br { width: 12px; height: 12px; background-image: url(../images/bleu/sprite-vert.gif); background-position: -84px 0; }
+td#mdg-ml { width: 12px; height: 12px; background-image: url(../images/bleu/sprite-vert.gif); background-position: -48px 0; }
+td#mdg-brl { width: 12px; height: 1px; background-image: url(../images/bleu/sprite-vert.gif); background-position: -48px 0; }
+td#mdg-mr { width: 12px; height: 12px; background-image: url(../images/bleu/sprite-vert.gif); background-position: -60px 0; }
+td#mdg-brr { width: 12px; height: 1px; background-image: url(../images/bleu/sprite-vert.gif); background-position: -60px 0; }
+td#mdg-btl { width: 12px; height: 1px; background-image: url(../images/bleu/sprite-vert.gif); background-position: 0 0 ; }
+td#mdg-btr { width: 12px; height: 1px; background-image: url(../images/bleu/sprite-vert.gif); background-position: -12px 0; }
+td#mdg-btcl { width: 12px; height: 12px; background-image: url(../images/bleu/sprite-horiz.gif); background-position: -24px 0; }
+td.mdg-menu-bl { width: 12px; height: 12px; background-image: url(../images/bleu/sprite-horiz.gif); background-position: -24px 0; }
+td#mdg-btcr { width: 12px; height: 12px; background-image: url(../images/bleu/sprite-horiz.gif); background-position: -36px 0; }
+td.mdg-menu-br { width: 12px; height: 12px; background-image: url(../images/bleu/sprite-horiz.gif); background-position: -36px 0; }
+td.mdg-menu-top { width: 84%; height: 12px; background-image: url(../images/bleu/sprite-horiz.gif); background-position: 0 0 ; margin: 0; padding: 0; background-repeat: repeat-x; font-size: 2px; }
+td.mdg-menu-tl { width: 12px; height: 12px; background-image: url(../images/bleu/sprite-horiz.gif); background-position: 0 0 ; background-position: left top; background-repeat: no-repeat; }
+td.mdg-menu-tr { width: 12px; height: 12px; background-image: url(../images/bleu/sprite-horiz.gif); background-position: 0 0 ; background-position: right top; background-repeat: no-repeat; }
+td.mdg-menu-btm { height: 12px; background-image: url(../images/bleu/sprite-horiz.gif); background-position: 0 0 ; }
+td#mdg-btm { height: 12px; background-image: url(../images/bleu/sprite-horiz.gif); background-position: 0 -48px; }
/* Buttons and textboxes - these settings are used almost everywhere */
input, textarea, select, button {
--- a/themes/oxygen/elements.tpl Sun May 04 21:57:48 2008 -0400
+++ b/themes/oxygen/elements.tpl Mon May 05 20:06:37 2008 -0400
@@ -18,9 +18,9 @@
<div class="recttop">
<table border="0" width="100%" cellspacing="0" cellpadding="0" style="font-size: 1px;">
<tr>
- <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-menu-l.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/images/spacer.gif" style="background-image: url({SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/sprite-horiz.gif); background-position: 0 0; background-repeat: no-repeat;" width="12" height="12" /> </td>
<td style="margin: 0; padding: 0; height: 12px;" class="recttoptop" onclick="var id = this.parentNode.parentNode.parentNode.parentNode.parentNode.id; var side = id.substr(0, id.indexOf('-')); collapseSidebar(side);"></td>
- <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-menu-r.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/images/spacer.gif" style="background-image: url({SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/sprite-horiz.gif); background-position: -12px 0; background-repeat: no-repeat;" width="12" height="12" /> </td>
</tr>
</table>
</div>
@@ -55,9 +55,9 @@
<div class="rectbot">
<table border="0" width="100%" cellspacing="0" cellpadding="0" style="font-size: 1px;">
<tr>
- <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-bl.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/images/spacer.gif" style="background-image: url({SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/sprite-horiz.gif); background-position: -24px 0; background-repeat: no-repeat;" width="12" height="12" /> </td>
<td style="margin: 0; padding: 0; height: 12px;" class="rectbottop"></td>
- <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-br.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/images/spacer.gif" style="background-image: url({SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/sprite-horiz.gif); background-position: -36px 0; background-repeat: no-repeat;" width="12" height="12" /> </td>
</tr>
</table>
</div>