From 9907c91477f5a5ccddd438ec708c438ade2dd93a Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Sun, 23 Oct 2011 09:36:35 +0000 Subject: [PATCH] Added a basic thumb-handler.php file, configured via thumb.config.php. The code is based on the wmf thumb handler, but simplified. It is disabled by default. * The thumb.php parameter extraction can also be overridden by the config to handle more complex setups and things like OggHandler and PagedTiffHandler. * A simple 404 error page is also included. It can be overridden by the config. * Additional HTTP headers can be passed through cURL via the config. --- 404.php | 29 ++++++ thumb-handler.php | 230 ++++++++++++++++++++++++++++++++++++++++++++ thumb.config.sample | 39 ++++++++ 3 files changed, 298 insertions(+) create mode 100644 404.php create mode 100644 thumb-handler.php create mode 100644 thumb.config.sample diff --git a/404.php b/404.php new file mode 100644 index 0000000000..c115c62b08 --- /dev/null +++ b/404.php @@ -0,0 +1,29 @@ + + +404 Not Found + +

Not Found

+

The requested URL $encUrl was not found on this server.

+ +ENDTEXT; + +echo $standard_404; diff --git a/thumb-handler.php b/thumb-handler.php new file mode 100644 index 0000000000..2d9fd420c5 --- /dev/null +++ b/thumb-handler.php @@ -0,0 +1,230 @@ +Bad request" . + "The URI contained bytes with the high bit set, this is not allowed." . + ""; + return; + } elseif ( strpos( $params['f'], '%20' ) !== false ) { + header( 'HTTP/1.0 404 Not found' ); + header( 'Content-Type: text/html' ); + header( 'X-Debug: filename contains a space' ); // useful for debugging + echo "Not found" . + "The URL contained spaces, we don't have any thumbnail files with spaces." . + ""; + return; + } + + wfStreamThumbViaCurl( $params, $uri ); +} + +/** + * Extract the required params for thumb.php from the thumbnail request URI. + * At least 'width' and 'f' should be set if the result is an array. + * + * @param $uri String Thumbnail request URI + * @return Array|null associative params array or null + */ +function wfExtractThumbParams( $uri ) { + global $thgThumbServer, $thgThumbFragment, $thgThumbHashFragment; + + $thumbRegex = '!^(?:' . preg_quote( $thgThumbServer ) . ')?/' . + preg_quote( $thgThumbFragment ) . '(/archive|/temp|)/' . + $thgThumbHashFragment . '([^/]*)/' . '(page(\d*)-)*(\d*)px-([^/]*)$!'; + + # Is this a thumbnail? + if ( preg_match( $thumbRegex, $uri, $matches ) ) { + list( $all, $archOrTemp, $filename, $pagefull, $pagenum, $size, $fn2 ) = $matches; + $params = array( 'f' => $filename, 'width' => $size ); + if ( $pagenum ) { + $params['page'] = $pagenum; + } + if ( $archOrTemp == '/archive' ) { + $params['archived'] = 1; + } elseif ( $archOrTemp == '/temp' ) { + $params['temp'] = 1; + } + } else { + $params = null; + } + + return $params; +} + +/** + * cURL to thumb.php and stream back the resulting file or give an error message. + * + * @param $params Array Parameters to thumb.php + * @param $uri String Thumbnail request URI + * @return void + */ +function wfStreamThumbViaCurl( array $params, $uri ) { + global $thgThumbScriptPath, $thgThumbCurlProxy, $thgThumbCurlTimeout; + + if ( !function_exists( 'curl_init' ) ) { + header( 'HTTP/1.0 404 Not found' ); + header( 'Content-Type: text/html' ); + header( 'X-Debug: cURL is not enabled' ); // useful for debugging + echo "Not found" . + "cURL is not enabled for PHP on this wiki. Unable to send request thumb.php." . + ""; + return; + } + + # Build up the request URL to use with CURL... + $reqURL = "{$thgThumbScriptPath}?"; + $first = true; + foreach ( $params as $name => $value ) { + if ( $first ) { + $first = false; + } else { + $reqURL .= '&'; + } + // Note: value is already urlencoded + $reqURL .= "$name=$value"; + } + + $ch = curl_init( $reqURL ); + if ( $thgThumbCurlProxy ) { + curl_setopt( $ch, CURLOPT_PROXY, $thgThumbCurlProxy ); + } + + $headers = array(); // HTTP headers + # Set certain headers... + $headers[] = "X-Original-URI: " . str_replace( "\n", '', $uri ); + if ( function_exists( 'wfCustomThumbRequestHeaders' ) ) { + wfCustomThumbRequestHeaders( $headers ); // add on any custom headers (like XFF) + } + # Pass through some other headers... + $passthrough = array( 'If-Modified-Since', 'Referer', 'User-Agent' ); + foreach ( $passthrough as $headerName ) { + $serverVarName = 'HTTP_' . str_replace( '-', '_', strtoupper( $headerName ) ); + if ( !empty( $_SERVER[$serverVarName] ) ) { + $headers[] = $headerName . ': ' . + str_replace( "\n", '', $_SERVER[$serverVarName] ); + } + } + + curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers ); + curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); + curl_setopt( $ch, CURLOPT_TIMEOUT, $thgThumbCurlTimeout ); + + # Actually make the request + $text = curl_exec( $ch ); + + # Send it on to the client + $errno = curl_errno( $ch ); + $contentType = curl_getinfo( $ch, CURLINFO_CONTENT_TYPE ); + $httpCode = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); + if ( $errno ) { + header( 'HTTP/1.1 500 Internal server error' ); + header( 'Cache-Control: no-cache' ); + list( $text, $contentType ) = wfCurlErrorText( $ch ); + } elseif ( $httpCode == 304 ) { + header( 'HTTP/1.1 304 Not modified' ); + $contentType = ''; + $text = ''; + } elseif ( strval( $text ) == '' ) { + header( 'HTTP/1.1 500 Internal server error' ); + header( 'Cache-Control: no-cache' ); + list( $text, $contentType ) = wfCurlEmptyText( $ch ); + } elseif ( $httpCode == 404 ) { + header( 'HTTP/1.1 404 Not found' ); + header( 'Cache-Control: s-maxage=300, must-revalidate, max-age=0' ); + } elseif ( $httpCode != 200 + || substr( $contentType, 0, 9 ) == 'text/html' + || substr( $text, 0, 5 ) == ' +Thumbnail error +Error retrieving thumbnail from scaling server: $error + +EOT; + return array( $text, $contentType ); +} + +/** + * Get error message and content type for when the cURL response is an error. + * + * @param $ch cURL handle + * @return Array (error html, content type) + */ +function wfCurlEmptyText( $ch ) { + $contentType = 'text/html'; + $error = htmlspecialchars( curl_error( $ch ) ); + $text = << +Thumbnail error +Error retrieving thumbnail from scaling server: empty response + +EOT; + return array( $text, $contentType ); +} + +# Entry point +wfHandleThumb404(); diff --git a/thumb.config.sample b/thumb.config.sample new file mode 100644 index 0000000000..05df568966 --- /dev/null +++ b/thumb.config.sample @@ -0,0 +1,39 @@ +