diff --git a/.htaccess b/.htaccess
index 6d983cb1..d2f0478d 100644
--- a/.htaccess
+++ b/.htaccess
@@ -6,6 +6,11 @@ AddType text/x-component .htc
DirectoryIndex index.php index.shtml index.html
+
+ ExpiresActive On
+ ExpiresByType text/html A3600
+
+
RewriteEngine On
RewriteBase /
diff --git a/common/code/boost_archive.php b/common/code/boost_archive.php
index 0addb5a8..02e98e13 100644
--- a/common/code/boost_archive.php
+++ b/common/code/boost_archive.php
@@ -6,6 +6,8 @@
*/
require_once(dirname(__FILE__) . '/boost.php');
+define('BOOST_DOCS_MODIFIED_DATE', 'Tue, 21 Sep 2010 22:19:30 +0100');
+
function get_archive_location(
$pattern,
$vpath,
@@ -53,6 +55,20 @@ function display_from_archive(
$params['charset'] = NULL;
$params['content'] = NULL;
+ // Check file exists.
+
+ $check_file = $params['zipfile'] ? $params['archive'] : $params['file'];
+
+ if (!is_file($check_file)) {
+ file_not_found($params,
+ $params['zipfile'] ?
+ 'Unable to find zipfile.' :
+ 'Unable to find file.');
+ return;
+ }
+
+ // Choose filter to use
+
$info_map = array_merge($content_map, array(
array('@.*@','@[.](txt|py|rst|jam|v2|bat|sh|xml|qbk)$@i','text','text/plain'),
array('@.*@','@[.](c|h|cpp|hpp)$@i','cpp','text/plain'),
@@ -89,85 +105,81 @@ function display_from_archive(
return;
}
- // Check zipfile.
+ // Handle ETags and Last-Modified HTTP headers.
- $check_file = $params['zipfile'] ? $params['archive'] : $params['file'];
+ // Output raw files.
- if (!is_file($check_file)) {
- file_not_found($params,
- $params['zipfile'] ?
- 'Unable to find zipfile.' :
- 'Unable to find file.');
- return;
- }
-
- $last_modified = max(
- strtotime("Sun, 11 Jul 2010 18:55:24 +0100"),
- filemtime($check_file));
-
- if (!conditional_get($last_modified))
- return;
-
- // Extract the file from the zipfile
-
- if ($params['zipfile'])
- {
- $unzip =
- UNZIP
- .' -p '.escapeshellarg($params['archive'])
- .' '.escapeshellarg($params['file']);
-
- if($extractor == 'raw') {
- raw_headers($type, $expires);
- if($_SERVER['REQUEST_METHOD'] != 'HEAD') display_raw_file($unzip, $type);
+ if($extractor == 'raw') {
+ if (!http_headers($type, filemtime($check_file), $expires))
return;
- }
- if ($expires) {
- header('Expires: '.date(DATE_RFC2822, strtotime($expires)));
- header('Cache-Control: max-age='.strtotime($expires, 0)); // 30 days
- }
+ if($_SERVER['REQUEST_METHOD'] != 'HEAD')
+ display_raw_file($params, $type);
+ }
+ else {
+ if (!http_headers('text/html', filemtime($check_file), $expires))
+ return;
+ // Read file from hard drive or zipfile
+
// Note: this sets $params['content'] with either the content or an error
// message:
- if(!extract_file($unzip, $params['content'])) {
+ if(!extract_file($params, $params['content'])) {
file_not_found($params, $params['content']);
return;
}
- }
- else
- {
- if($extractor == 'raw') {
- raw_headers($type, $expires);
- if($_SERVER['REQUEST_METHOD'] != 'HEAD') readfile($params['file']);
- return;
- }
-
- if ($expires) {
- header('Expires: '.date(DATE_RFC2822, strtotime($expires)));
- header('Cache-Control: max-age='.strtotime($expires, 0)); // 30 days
- }
-
- $params['content'] = file_get_contents($params['file']);
- }
- if($type == 'text/html') {
- if(html_headers($params['content'])) {
- if($_SERVER['REQUEST_METHOD'] != 'HEAD') echo $params['content'];
- return;
- }
- }
-
- if($_SERVER['REQUEST_METHOD'] == 'HEAD') return;
-
- if ($preprocess) {
- $params['content'] = call_user_func($preprocess, $params['content']);
- }
+ // Check if the file contains a redirect.
- echo_filtered($extractor, $params);
+ if($type == 'text/html') {
+ if($redirect = detect_redirect($params['content'])) {
+ header("Location: $redirect", TRUE, 301);
+ if($_SERVER['REQUEST_METHOD'] != 'HEAD') echo $params['content'];
+ return;
+ }
+ }
+
+ // Finally process the file and display it.
+
+ if($_SERVER['REQUEST_METHOD'] != 'HEAD') {
+ if ($preprocess) {
+ $params['content'] = call_user_func($preprocess, $params['content']);
+ }
+
+ echo_filtered($extractor, $params);
+ }
+ }
}
-function conditional_get($last_modified) {
+// HTTP header handling
+
+function http_headers($type, $last_modified, $expires = null)
+{
+ header('Content-type: '.$type);
+ switch($type) {
+ case 'image/png':
+ case 'image/gif':
+ case 'image/jpeg':
+ case 'text/css':
+ case 'application/x-javascript':
+ case 'application/pdf':
+ case 'application/xml-dtd':
+ header('Expires: '.date(DATE_RFC2822, strtotime("+1 year")));
+ header('Cache-Control: max-age=31556926'); // A year, give or take a day.
+ break;
+ default:
+ if($expires) {
+ header('Expires: '.date(DATE_RFC2822, strtotime($expires)));
+ header('Cache-Control: max-age='.strtotime($expires, 0));
+ }
+ break;
+ }
+
+ return conditional_get(max(strtotime(BOOST_DOCS_MODIFIED_DATE), $last_modified));
+}
+
+function conditional_get($last_modified)
+{
if(!$last_modified) return true;
$last_modified_text = date(DATE_RFC2822, $last_modified);
@@ -197,240 +209,83 @@ function conditional_get($last_modified) {
return false;
}
-class boost_archive_render_callbacks {
- var $content_callback, $params;
-
- function boost_archive_render_callbacks($content, $params) {
- $this->content_callback = $content;
- $this->archive = $params;
- }
+// General purpose render callbacks.
- function content_head()
- {
- $charset = $this->archive['charset'] ? $this->archive['charset'] : 'us-ascii';
- $title = $this->archive['title'] ? 'Boost C++ Libraries - '.$this->archive['title'] : 'Boost C++ Libraries';
+function boost_archive_render_callbacks($content, $params) {
+ $charset = $params['charset'] ? $params['charset'] : 'us-ascii';
+ $title = $params['title'] ? 'Boost C++ Libraries - '.$params['title'] : 'Boost C++ Libraries';
- print <<
${title}
HTML;
- }
-
- function content()
- {
- if ($this->content_callback)
- {
- call_user_func($this->content_callback, $this->archive);
- }
- }
+
+ return Array(
+ 'head' => $head,
+ 'content' => $content
+ );
}
-function raw_headers($type, $expires = null)
-{
- header('Content-type: '.$type);
- switch($type) {
- case 'image/png':
- case 'image/gif':
- case 'image/jpeg':
- case 'text/css':
- case 'application/x-javascript':
- case 'application/pdf':
- case 'application/xml-dtd':
- header('Expires: '.date(DATE_RFC2822, strtotime("+1 year")));
- header('Cache-Control: max-age=31556926'); // A year, give or take a day.
- default:
- if($expires) {
- header('Expires: '.date(DATE_RFC2822, strtotime($expires)));
- header('Cache-Control: max-age='.strtotime($expires, 0));
- }
- }
-}
-
-function display_raw_file($unzip, $type)
+function display_raw_file($params, $type)
{
## header('Content-Disposition: attachment; filename="downloaded.pdf"');
- $file_handle = popen($unzip,'rb');
- fpassthru($file_handle);
- $exit_status = pclose($file_handle);
+ if($params['zipfile']) {
+ $file_handle = popen(unzip_command($params), 'rb');
+ fpassthru($file_handle);
+ $exit_status = pclose($file_handle);
- // Don't display errors for a corrupt zip file, as we seemd to
- // be getting them for legitimate files.
+ // Don't display errors for a corrupt zip file, as we seemd to
+ // be getting them for legitimate files.
- if($exit_status > 3)
- echo 'Error extracting file: '.unzip_error($exit_status);
-};
-
-function extract_file($unzip, &$content) {
- header('Expires: '.date(DATE_RFC2822, strtotime("+1 month")));
- header('Cache-Control: max-age=2592000'); // 30 days
-
- $file_handle = popen($unzip,'r');
- $text = '';
- while ($file_handle && !feof($file_handle)) {
- $text .= fread($file_handle,8*1024);
- }
- $exit_status = pclose($file_handle);
-
- if($exit_status == 0) {
- $content = $text;
- return true;
+ if($exit_status > 3)
+ echo 'Error extracting file: '.unzip_error($exit_status);
}
else {
- $content = strstr($_SERVER['HTTP_HOST'], 'beta') ? unzip_error($exit_status) : null;
- return false;
+ readfile($params['file']);
}
}
+function extract_file($params, &$content) {
+ if($params['zipfile']) {
+ $file_handle = popen(unzip_command($params),'r');
+ $text = '';
+ while ($file_handle && !feof($file_handle)) {
+ $text .= fread($file_handle,8*1024);
+ }
+ $exit_status = pclose($file_handle);
+
+ if($exit_status == 0) {
+ $content = $text;
+ return true;
+ }
+ else {
+ $content = strstr($_SERVER['HTTP_HOST'], 'beta') ? unzip_error($exit_status) : null;
+ return false;
+ }
+ }
+ else {
+ $content = file_get_contents($params['file']);
+ return true;
+ }
+}
+
+function unzip_command($params) {
+ return
+ UNZIP
+ .' -p '.escapeshellarg($params['archive'])
+ .' '.escapeshellarg($params['file']);
+}
+
//
// Filters
//
function echo_filtered($extractor, $params) {
+ require_once(dirname(__FILE__)."/boost_filter_$extractor.php");
$extractor_name = $extractor.'_filter';
call_user_func($extractor_name, $params);
}
-function text_filter($params)
-{
- $params['title'] = htmlentities($params['key']);
-
- display_template($params['template'],
- new boost_archive_render_callbacks('text_filter_content', $params));
-}
-
-function text_filter_content($params)
-{
- print "".htmlentities($params['key'])."
\n";
- print "\n";
- print_encoded_text($params, 'text');
- print "
\n";
-}
-
-function cpp_filter($params) {
- $params['title'] = htmlentities($params['key']);
-
- display_template($params['template'],
- new boost_archive_render_callbacks('cpp_filter_content', $params));
-}
-
-function cpp_filter_content($params)
-{
- print "".htmlentities($params['key'])."
\n";
- print "\n";
- print_encoded_text($params, 'cpp');
- print "
\n";
-}
-
-function boost_book_html_filter($params) {
- html_init($params);
- display_template($params['template'],
- new boost_archive_render_callbacks('boost_book_html_filter_content', $params));
-}
-
-function boost_book_html_filter_content($params)
-{
- $text = prepare_html($params['content'], true);
-
- $text = substr($text,strpos($text,''));
- $text = substr($text,0,strpos($text,''));
- $text = str_replace('
','',$text);
- $text = str_replace('