" . "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();