Назад | Перейти на главную страницу

Windows Apache 2.2 мучительно медленно выполняет CGI

Недавно я установил Apache 2.2 и git на одном из наших ПК с Windows XP для доступа к gitweb, используя настройку по адресу https://git.wiki.kernel.org/index.php/MSysGit:GitWeb Как отмечено в вики, единственная версия Perl, которая, похоже, работает с gitweb в том виде, в котором он написан, - это версия, включенная в MSysGit. ActivePerl и StrawberryPerl не реализуют определенные обязательные функции, поэтому другой интерпретатор не подходит.

C:\Program Files\Git\bin>perl.exe --version
This is perl, v5.8.8 built for msys

В любом случае, он настроен и работает, но по какой-то причине при каждой загрузке страницы есть задержка примерно в 10 секунд. Чтобы решить эту проблему, я создал простой helloworld.cgi и поместил его в каталог рядом с gitweb.cgi. Он настроен на использование того же интерпретатора perl, что и gitweb:

#!C:\Program Files\Git\bin\perl.exe
print "Content-type: text/html\n\n";
print "Hello, world!\n";

Этот сценарий тоже выполняется на сервере более 10 секунд. Если я запускаю командную строку и выполняю ее напрямую с тем же исполняемым файлом perl, она выполняется мгновенно.

mod_cgi загружается в конфигурацию Apache, и я использую разделы конфигурации, показанные в git wiki, измененной для моей системы:

# Config to make the gitweb CGI available through Apache.
Alias /git "C:/Program Files/Git/share/gitweb"
<Directory "C:/Program Files/Git/share/gitweb">
  AddHandler cgi-script .cgi
  <Files ~ "\.cgi$">
    Options +ExecCGI
  </Files>
  AllowOverride None
  Order allow,deny
  Allow from all
  DirectoryIndex gitweb.cgi
</Directory>

Есть ли какие-то другие директивы конфигурации, которые мне не хватает? Кажется, не имеет значения, обращаюсь ли я к нему с другого ПК или через localhost непосредственно на машине, поэтому я думаю, что это исключает DNS. Он также ничего не сбрасывает в журнал ошибок Apache.

Я исправил это, используя версию Perl для cygwin вместо msysgit. Это действительно ускорит ваше время ответа.

Для этого вам нужно будет изменить скрипт gitweb.cgi в трех местах. Первая строка должна сказать следующее:

#!C:/cygwin/bin/perl

Я предпочитаю использовать версию git для cygwin вместо msysgit, поэтому вам нужно убедиться, что корневой каталог проекта находится в формате cygwin:

our $GIT = "C:/cygwin/bin/git";
our $projectroot = "/cygdrive/c/temp/repos";

Это связано с тем, что Apache очищает переменные среды перед запуском процессора cgi. Единственные переменные, которые он оставляет нетронутыми:

  • ДОРОЖКА
  • ПОДСКАЗКА
  • SystemRoot
  • COMSPEC
  • ПУТЬ
  • WINDIR

Он также добавляет множество переменных, специфичных для Apache (таких как SCRIPT_NAME).

Таким образом, решение состоит в том, чтобы использовать какую-то оболочку (я использую сценарий Python cgi, используя обычный Python W32), который устанавливает некоторые переменные обратно перед запуском оболочки msys или msys perl (правильный способ запуска материала msys извне - c:/path/to/sh.exe --login -c "perl /path/to/script.cgi").

Переменные, которые необходимо установить (в дополнение к тем, которые Apache передает или устанавливает самостоятельно):

  • LOGONSERVER = \\MACHINENAME
  • TMP = C:\Users\USERNAME\AppData\Local\Temp

TMP не требуется, но msys пожалуется, если не сможет его найти.

Очевидно, вы можете использовать любой каталог для TMP.

Я не имею понятия почему LOGONSERVER нужен, извините.

Убедитесь, что сценарий / приложение-оболочка устанавливает stdout в двоичный режим, в противном случае Apache выбрасывает Premature end of script headers ошибка.

Просто добавьте эту строку в httpd.conf:

SetEnv LOGONSERVER \\\\machine