MediaWiki
REL1_22
|
00001 <?php 00030 function wfOutputHandler( $s ) { 00031 global $wgDisableOutputCompression, $wgValidateAllHtml; 00032 $s = wfMangleFlashPolicy( $s ); 00033 if ( $wgValidateAllHtml ) { 00034 $headers = headers_list(); 00035 $isHTML = false; 00036 foreach ( $headers as $header ) { 00037 $parts = explode( ':', $header, 2 ); 00038 if ( count( $parts ) !== 2 ) { 00039 continue; 00040 } 00041 $name = strtolower( trim( $parts[0] ) ); 00042 $value = trim( $parts[1] ); 00043 if ( $name == 'content-type' && ( strpos( $value, 'text/html' ) === 0 00044 || strpos( $value, 'application/xhtml+xml' ) === 0 ) 00045 ) { 00046 $isHTML = true; 00047 break; 00048 } 00049 } 00050 if ( $isHTML ) { 00051 $s = wfHtmlValidationHandler( $s ); 00052 } 00053 } 00054 if ( !$wgDisableOutputCompression && !ini_get( 'zlib.output_compression' ) ) { 00055 if ( !defined( 'MW_NO_OUTPUT_COMPRESSION' ) ) { 00056 $s = wfGzipHandler( $s ); 00057 } 00058 if ( !ini_get( 'output_handler' ) ) { 00059 wfDoContentLength( strlen( $s ) ); 00060 } 00061 } 00062 return $s; 00063 } 00064 00073 function wfRequestExtension() { 00075 if ( isset( $_SERVER['REQUEST_URI'] ) ) { 00076 // Strip the query string... 00077 list( $path ) = explode( '?', $_SERVER['REQUEST_URI'], 2 ); 00078 } elseif ( isset( $_SERVER['SCRIPT_NAME'] ) ) { 00079 // Probably IIS. QUERY_STRING appears separately. 00080 $path = $_SERVER['SCRIPT_NAME']; 00081 } else { 00082 // Can't get the path from the server? :( 00083 return ''; 00084 } 00085 00086 $period = strrpos( $path, '.' ); 00087 if ( $period !== false ) { 00088 return strtolower( substr( $path, $period ) ); 00089 } 00090 return ''; 00091 } 00092 00101 function wfGzipHandler( $s ) { 00102 if ( !function_exists( 'gzencode' ) ) { 00103 wfDebug( __FUNCTION__ . "() skipping compression (gzencode unavailable)\n" ); 00104 return $s; 00105 } 00106 if ( headers_sent() ) { 00107 wfDebug( __FUNCTION__ . "() skipping compression (headers already sent)\n" ); 00108 return $s; 00109 } 00110 00111 $ext = wfRequestExtension(); 00112 if ( $ext == '.gz' || $ext == '.tgz' ) { 00113 // Don't do gzip compression if the URL path ends in .gz or .tgz 00114 // This confuses Safari and triggers a download of the page, 00115 // even though it's pretty clearly labeled as viewable HTML. 00116 // Bad Safari! Bad! 00117 return $s; 00118 } 00119 00120 if ( wfClientAcceptsGzip() ) { 00121 wfDebug( __FUNCTION__ . "() is compressing output\n" ); 00122 header( 'Content-Encoding: gzip' ); 00123 $s = gzencode( $s, 6 ); 00124 } 00125 00126 // Set vary header if it hasn't been set already 00127 $headers = headers_list(); 00128 $foundVary = false; 00129 foreach ( $headers as $header ) { 00130 if ( substr( $header, 0, 5 ) == 'Vary:' ) { 00131 $foundVary = true; 00132 break; 00133 } 00134 } 00135 if ( !$foundVary ) { 00136 header( 'Vary: Accept-Encoding' ); 00137 global $wgUseXVO; 00138 if ( $wgUseXVO ) { 00139 header( 'X-Vary-Options: Accept-Encoding;list-contains=gzip' ); 00140 } 00141 } 00142 return $s; 00143 } 00144 00152 function wfMangleFlashPolicy( $s ) { 00153 # Avoid weird excessive memory usage in PCRE on big articles 00154 if ( preg_match( '/<\s*cross-domain-policy\s*>/i', $s ) ) { 00155 return preg_replace( '/<\s*cross-domain-policy\s*>/i', '<NOT-cross-domain-policy>', $s ); 00156 } else { 00157 return $s; 00158 } 00159 } 00160 00166 function wfDoContentLength( $length ) { 00167 if ( !headers_sent() && isset( $_SERVER['SERVER_PROTOCOL'] ) && $_SERVER['SERVER_PROTOCOL'] == 'HTTP/1.0' ) { 00168 header( "Content-Length: $length" ); 00169 } 00170 } 00171 00179 function wfHtmlValidationHandler( $s ) { 00180 00181 $errors = ''; 00182 if ( MWTidy::checkErrors( $s, $errors ) ) { 00183 return $s; 00184 } 00185 00186 header( 'Cache-Control: no-cache' ); 00187 00188 $out = Html::element( 'h1', null, 'HTML validation error' ); 00189 $out .= Html::openElement( 'ul' ); 00190 00191 $error = strtok( $errors, "\n" ); 00192 $badLines = array(); 00193 while ( $error !== false ) { 00194 if ( preg_match( '/^line (\d+)/', $error, $m ) ) { 00195 $lineNum = intval( $m[1] ); 00196 $badLines[$lineNum] = true; 00197 $out .= Html::rawElement( 'li', null, 00198 Html::element( 'a', array( 'href' => "#line-{$lineNum}" ), $error ) ) . "\n"; 00199 } 00200 $error = strtok( "\n" ); 00201 } 00202 00203 $out .= Html::closeElement( 'ul' ); 00204 $out .= Html::element( 'pre', null, $errors ); 00205 $out .= Html::openElement( 'ol' ) . "\n"; 00206 $line = strtok( $s, "\n" ); 00207 $i = 1; 00208 while ( $line !== false ) { 00209 $attrs = array(); 00210 if ( isset( $badLines[$i] ) ) { 00211 $attrs['class'] = 'highlight'; 00212 $attrs['id'] = "line-$i"; 00213 } 00214 $out .= Html::element( 'li', $attrs, $line ) . "\n"; 00215 $line = strtok( "\n" ); 00216 $i++; 00217 } 00218 $out .= Html::closeElement( 'ol' ); 00219 00220 $style = <<<CSS 00221 .highlight { background-color: #ffc } 00222 li { white-space: pre } 00223 CSS; 00224 00225 $out = Html::htmlHeader( array( 'lang' => 'en', 'dir' => 'ltr' ) ) . 00226 Html::rawElement( 'head', null, 00227 Html::element( 'title', null, 'HTML validation error' ) . 00228 Html::inlineStyle( $style ) ) . 00229 Html::rawElement( 'body', null, $out ) . 00230 Html::closeElement( 'html' ); 00231 00232 return $out; 00233 }