INDEVELOPMENTbeta






Subskrybuj m1chu.eu – another devblog
 
  •  Marcin: Takie strony to jak to się mówi STATE OF THE ART… tu nie ma co komentować nawet…po prostu
  •  Michał: document.body.firstChild.appen dChild(p); chyba powinno być: document.body.firstChild.ap...
  •  michal: Witam Pilnie prosze Cie o kontakt mailowy w sprawie strony http://regexp.m1chu.eu/. Z gory dzieki za...
  •  Pawel: Witam Na stronie http://www.rozenek.com/polski, 198 opisalem podobny problem:...
  •  wwww: Geniusze IT w Warszawie http://capital24.tv/film/4c336 f2d7c878/geniusze_it_w_warszaw ie
  •  Kpc21: Na Operze 10.53 działa już w postaci docelowej, bez „-o-”.
  •  m1chu: Prawda, to nie są strony zbyt funkcjonalne. Dlatego większość z nich to portfolia/personalne...

Ankieta!

  • Jak oceniasz poziom artykułów? (dokładną opinię umieść w komentarzu)

    View Results

    Loading ... Loading ...




Edycja wpisów w ShoutBox – phpBB by Przemo


Pierwszy wpis w tej kategorii. Pierwszy opisywany przeze mnie bug. Przyznaję, nie jest on żadnych wysokich lotów – nie mniej jednak tak jak zawsze z tego typu lub cięższymi sprawami dzieliłem się bezpośrednio z danymi osobami, tak teraz postanowiłem je pisać. Może dlatego, że mam gdzie.

Sprawa jest na tyle nieskomplikowana, że dłużej dociekałem przyczyny, niż ją naprawiałem. Błąd wykryłem przypadkiem, dzięki użytkownikom mojego forum. Wiem, że znany był on wcześniej, a nawet niektórzy próbowali go naprawiać, ale jednoznacznego rozwiązania nie widziałem nigdzie. Na czym polega bug? Na tym, że w przypadku jeśli PHP wspomagane jest obsługą CGI z wyłączonym zlib.output_compression w czasie edycji wpisów w shoutboxie jest wysyłany tekst przed wysłaniem nagłówków powodujący błąd skryptu. Problem ten dotyczy wersji 1.12.5, z tego co wiem podobne problemy były zauważane w wersjach 1.9.x.

Jak wygląda to od strony technicznej? W phpBB by Przemo takie akcje jak edycja, czy usuwanie wpisów z shoutboxa są wykonywane w pliku shoutbox_view.php. W momencie kiedy w Panelu Administracyjnym ustawimy, aby skrypt korzystał z kompresji gzip w pliku w zależności od typu przeglądarki ustawiane jest standardowe buforowanie wyjścia, wysyłany nagłówek szyfrowania treści strony, wyliczana suma kontrolnej i w końcu kompresowanie lub po prostu ustawienie buforowania wyjścia z atrybutem kompresji gzipa.

// Gecko
@ob_start('ob_gzhandler');
// Opera
$do_gzip_compress = TRUE;
@ob_start();
@ob_implicit_flush(0);

@header('Content-Encoding: gzip');
$gzip_contents = @ob_get_contents();
@ob_end_clean();

$gzip_size = strlen($gzip_contents);
$gzip_crc = @crc32($gzip_contents);

$gzip_contents = @gzcompress($gzip_contents, 9);
$gzip_contents = substr($gzip_contents, 0, strlen($gzip_contents) - 4);

echo "x1fx8bx08x00x00x00x00x00";
echo $gzip_contents;
echo pack('V', $gzip_crc);
echo pack('V', $gzip_size);

W tym drugim przypadku dotyczącym przeglądarek opartych na silniku Gecko każda próba edycji jakiegokolwiek wpisu kończy się wyświetleniem białej strony, w przypadku pierwszym dotyczącym Opery edycja jest możliwa, ale zamiast listowania wiadomości otrzymujemy ciąg skompresowanych danych, w postaci różnorodnych znaków. Co najdziwniejsze przynajmniej na Internet Explorerze w wersji siódmej wszystko działa dobrze ;]

Jak już napisałem prawie na początku problem stwarza fakt, że przy podanej wcześniej przeze mnie konfiguracji parsera PHP wysyłanie tekstu przed wysłaniem nagłówków powoduje automatyczne zatrzymanie i zerowanie zawartości sparsowanego pliku. Jeśli posiadamy własny serwer lub po prostu mamy możliwość konfiguracji naszego konta np. poprzez zmianę php.ini sprawa jest stosunkowo prosta. Możemy dla przykładu ustawić zlib.output_compression i zlib.output_compression_level na 1. Na przykład poprzez użycie PHP w wersji co najmniej 4.3:

ini_set('zlib.output_compression', true);
ini_set('zlib.output_compression_level', '1');

Natomiast jeśli nie mamy takich możliwości konfiguracyjnych wystarczy, że znajdziemy poniższy kod.

$do_gzip_compress = FALSE;
if ( $board_config['gzip_compress'] && !@headers_sent() )
{
	$phpver = phpversion();
	$useragent = (isset($HTTP_SERVER_VARS['HTTP_USER_AGENT'])) ? $HTTP_SERVER_VARS['HTTP_USER_AGENT'] : getenv('HTTP_USER_AGENT');
	$is_ob_gzhandler_started = false;
	if ( @ini_get('zlib.output_compression') && (int)@ini_get('zlib.output_compression') != 0 && strtolower(@ini_get('zlib.output_compression')) != 'off' )
	{
		$is_ob_gzhandler_started = true;
	}
	else if ( @ini_get('output_handler') && strtolower(@ini_get('output_handler'))=='ob_gzhandler' )
	{
		$is_ob_gzhandler_started = true;
	}
	if ( $phpver>= '4.0.4pl1' && ( strstr($useragent,'compatible') || strstr($useragent,'Gecko') ) )
	{
		if ( extension_loaded('zlib') && !$is_ob_gzhandler_started )
		{
			@ob_start('ob_gzhandler');
		}
	}
	else if ( $phpver> '4.0' )
	{
		if ( strstr($HTTP_SERVER_VARS['HTTP_ACCEPT_ENCODING'], 'gzip') )
		{
			if ( extension_loaded('zlib') && !$is_ob_gzhandler_started )
			{
				$do_gzip_compress = TRUE;
				@ob_start();
				@ob_implicit_flush(0);
				@header('Content-Encoding: gzip');
			}
		}
	}
}

I przeniesiemy go powyżej następującego kodu.

// ShoutBox auth
$is_jr_admin = ($userdata['user_jr']) ? true : false;
$is_mod = ($userdata['user_level'] == MOD) ? true : false;

W takim wypadku niezbędne do kompresji gzip nagłówki zostaną wysłane przed wyświetleniem tekstu i wszelkie związane z tą przypadłością błędy zostaną zaniechane.


10 komentarzy

Dodaj własny komentarz

Możesz użyć następujących tagów XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>