У меня на сервере запущен nph-script.cgi.
Сервер продолжает добавлять
HTTP / 1.1 200 OK Дата: 5 ноября 2009 г., 02:28:53 GMT Сервер: Apache / 2.2.8 (Ubuntu) PHP / 5.2.8-1hardy ~ ppa1 с Suhosin-Patch mod_perl / 2.0.3 Perl / v5. 8.8 Content-Length: 0 Keep-Alive: timeout = 15, max = 100 Connection: Keep-Alive Content-Type: text / plain X-Pad: избегать ошибок браузера
Внизу каждой страницы, загруженной через скрипт .cgi. Почему это так? Как мне удалить это надоедливое сообщение, которое появляется на всех страницах?
Мы наблюдаем аналогичную проблему с nph-файлом, который действует как шлюз для Intersystems Caché (база данных и сервер веб-приложений). Работает нормально, пока мы не используем перезапись URL. Любой запрос, обработанный путем перезаписи URL-адреса, создает ложный заголовок, описанный выше (в нижней части содержимого ответа или рядом с ним).
Мы попытались изолировать ошибку с помощью небольшого nph-скрипта Perl, и у нас возникла та же проблема. Протестировано на разных серверах: Apache / 2.2.11 на Ubuntu 9.04, Apache / 2.2.9 на Debian 5.0 и Apache / 2.0.52 на Red Hat EL 4.
Сценарий nph-test.cgi в обычном каталоге cgi-bin:
#!/usr/bin/perl -wT
use strict;
print "$ENV{SERVER_PROTOCOL} 200 OK\n";
print "Server: $ENV{SERVER_SOFTWARE}\n";
print "Content-Type: text/plain\n\n";
# Tell Perl not to buffer our output
$| = 1;
print "OK.";
Перезапись URL
RewriteEngine On
RewriteRule ^test/([0-9]+)$ /cgi-bin/nph-test.cgi
(в файле Apache .conf, в Directory /var/www/
)
отклик
OK.
HTTP/1.1 200 OK
Date: Mon, 07 Dec 2009 09:44:40 GMT
Server: Apache/2.2.11 (Ubuntu) PHP/5.2.6-3ubuntu4.2 with Suhosin-Patch
Content-Length: 0
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/plain
Другие источники, описывающие те же или похожие проблемы:
Использование Content-Length работает для тестового сценария, но не решает нашу проблему, поскольку мы, очевидно, не можем изменить исполняемый файл nph-cgi, поставляемый с Intersystems Caché.
Как вы говорите, это, вероятно, следует отправить в Apache, но правила, изложенные на httpd.apache.org/bug_report.html, довольно устрашающие. (У меня ограниченные знания об Apache.)
Это проблема, которую я иногда видел на нашем собственном сервере WAMP, а также в средах хостинга LAMP. Более поздние выпуски Apache 1.3 и 2.0, казалось, ограничили проблему, но это регулярно проблема с 2.2.
Проблема проявляется в основном, когда скрипты NPH сочетаются с перезаписью. Проблема еще больше усугубляется, если вы обрабатываете собственное сжатие gzip, что в значительной степени является требованием при использовании сценариев NPH. Если вы не используете перезапись URL, проблема практически исчезнет.
Это нигде НЕ задокументировано, и мне пришлось самостоятельно определять возможные причины и решения. Мне удалось (В большинстве случаев) решить проблему следующим образом: добавив заголовок Content-Length. Это будет работать ТОЛЬКО в том случае, если вы накапливаете вывод страницы перед отправкой клиенту, чтобы вы могли рассчитать размер байта для заголовка.
Например, если вы создаете свою страницу, если вы используете Perl, вы будете накапливать их в переменной, такой как $HTML
а затем, когда вы обработаете всю страницу, вы отправите ее в подпрограмму, которая обрабатывает окончательный результат. Что я также делаю, так это накапливаю заголовки отдельно в переменную по мере необходимости до окончательного вывода, и это эффективно избавляет меня от необходимости обрабатывать вывод более одного раза, что очень помогает при отладке.
Вот фрагмент кода без поддержки вывода gzip:
sub finish { my ($STATUS, $HEADER, $TYPE, $HTML, $ISNPH) = @_; my $HTTP_PROTOCOL = $ENV{'SERVER_PROTOCOL'} if ($ENV{'SERVER_PROTOCOL'} && $ENV{'SERVER_PROTOCOL'} =~ m/^HTTP\/\d\.\d\$/); $HTTP_PROTOCOL ||= 'HTTP/1.1'; $STATUS ||= 200; $TYPE ||= 'text/html'; if ($STATUS =~ m/^30[123]$/) { $HEADER .= "Content-Length: 0\n"; print "$HTTP_PROTOCOL $STATUS\n"; print $HEADER; print "Content-type: $TYPE\n"; print "Location: $HTML\n\n"; exit; } print "$HTTP_PROTOCOL $STATUS\n" if ($ISNPH); print $HEADER; print "Content-type: $TYPE\n"; print 'Content-Length: ' . length($HTML) . "\n" if ($ISNPH); print "\n"; print $HTML; exit; }
Это будет называться так:
&finish('200', $HEADER, 'text/html', $HTML, 1);
Если вы тестируете свой скрипт перед тем, как заставить его поддерживать NPH, просто передайте 0
в качестве последнего параметра. Просто не печатайте на клиенте до вызова этой функции и создавайте свои заголовки в $HEADER
и HTML в $HTML
.
Если вы выполняете перенаправление, передайте URL-адрес, на который вы перенаправляете, в $HTML
параметр. В сценарии перенаправления нет необходимости в фактическом выводе HTML.
Для дальнейшего решения проблем, если они все еще появляются, протестируйте свой скрипт с буферизацией вывода. on
& off
.
По-прежнему существуют ситуации, когда это может не решить проблему, и я еще не нашел решения, его следует передать группе Apache. Я знаю только программирование CGI, поэтому у меня не было бы возможности исследовать исходный код Apache или отправлять исправления, но, надеюсь, кто-то этим займется.
~ Джей
Вы уверены, что сервер настроен правильно? Учитывая, что в сообщении утверждается, что тип содержимого - text / plain вместо text / html или что-то еще, я думаю, что что-то не так с тем, как вы настраиваете CGI или ваш сценарий .cgi.