Я пытаюсь перенести старое приложение CGI с существующего сервера Windows 2003 (IIS 6.0), где оно отлично работает, на новый сервер Windows 2008 с IIS 7.0, где возникает следующая проблема:
После настройки обработчика модуля и всего остального я обнаружил, что могу получить доступ к файлу приложения CGI (rdbweb.exe), только если я вызываю его через запрос POST (отправка формы с другой страницы).
Если я просто попытаюсь ввести URL-адрес файла (отправив запрос GET), я получаю следующую ошибку:
Ошибка HTTP 502.2 - неверный шлюз
Указанное приложение CGI вело себя неправильно, не возвращая полный набор заголовков HTTP. Он вернул следующие заголовки: «Исключение EInOutError в модуле rdbweb.exe по адресу 00039B44. Ошибка ввода-вывода 6.».
Это очень старое приложение для одного из наших клиентов. Когда мы попытались позвонить поставщику, они сказали, что нам нужно платить около 3000 долларов в год за поддержку, чтобы начать разговор об этом. Конечно, я пытаюсь этого избежать!
Обратите внимание, что:
Мы пробовали следующее:
Теперь единственная оставшаяся возможность, которую мы инициировали, - это следующая статья базы знаний Microsoft: http://support.microsoft.com/kb/145661 - О чем:
Ошибка CGI: указанное приложение CGI неправильно вело себя, не возвращая полный набор заголовков HTTP. Он вернул следующие заголовки:
в статье предлагается следующее решение:
Измените исходный код для вывода заголовка приложения CGI. Ниже приведен пример правильного заголовка:
print "HTTP/1.0 200 OK\n"; print "Content-Type: text/html\n\n\n";
К сожалению, у нас нет источника, чтобы попробовать это, и я все равно не уверен, есть ли у нас проблема.
Вы можете мне помочь с этой проблемой? Есть ли способ заставить приложение работать без запроса POST? Обратите внимание, что на старом сервере IIS6 приложение работает нормально, и я не смог найти какой-либо специальной конфигурации IIS, которую я мог бы попробовать ее эквивалент в IIS7.
У нас есть приложение Delphi 5 CGI, которое столкнулось с той же проблемой в IIS 7. Наше решение было похоже на то, что Стивен опубликовал выше, однако мы не комментируем полностью строку, упомянутую Мариусом выше. Когда я это сделал, я увидел, что любой оператор Request.ContentString вернет в приложение пустую строку. Нашим решением было реализовать исправление кода, предложенное на Эта статья около дна. Для справки, вот фрагмент кода нашей копии CGIApp.pas с изменением.
procedure TCGIApplication.Run;
var
HTTPRequest: TCGIRequest;
HTTPResponse: TCGIResponse;
begin
inherited Run;
if IsConsole then
begin
Rewrite(Output);
//Win 7/2008 IIS7
//Reset(Input);
{$i-} {!!IIS7}
Reset(Input);
if IOResult <>0 then ;
{$i+}
end;
try
HTTPRequest := NewRequest;
try
HTTPResponse := NewResponse(HTTPRequest);
try
HandleRequest(HTTPRequest, HTTPResponse);
finally
HTTPResponse.Free;
end;
finally
HTTPRequest.Free;
end;
except
HandleServerException(Exception(ExceptObject), FOutputFileName);
end;
end;
Вкратце: это может быть приложение Delphi CGI, скомпилированное с версией Delphi, предшествующей последнему обновлению D2007 (11.0.2902.10471). В этом случае вам понадобятся исходные коды и установка Delphi, а также перекомпилируйте приложение. В качестве альтернативы вы должны попросить их просто перекомпилировать приложение, используя последнюю версию Delphi.
(из http://forums.iis.net/t/1100323.aspx?PageIndex=2)
Мы обнаружили проблему, из-за которой наш CGI не отвечал на IIS 7. Мы фактически сузили причину до строки кода в базовом классе всех приложений CGI, написанных на Delphi (по крайней мере, до версии 2005). Эта строка кода находится в методе Run TCGIApplication и просто сбрасывает стандартный ввод. В IIS 6 и ранее эта строка выполняется без проблем, но в IIS 7 возникает исключение, которое вызывает сбой приложения CGI и, следовательно, не отвечает на запросы. Мы все еще изучаем побочные эффекты комментирования этой строки, но это наше текущее решение. После удаления этой строки наши приложения CGI теперь корректно работают в IIS 7.
Оригинальный автор: Стивен
У меня была эта проблема (CGI GET не работает с CGI, созданным Delphi), и я также хотел сохранить расширение .cgi для моего CGI, а не .exe (что пугает пользователей!). IIS 7.5, похоже, не позволяет CGI иметь расширение, отличное от .exe или .dll.
Вот отличный способ работы с PHP (!):
По сути, вы собираетесь заставить PHP вызывать ваш CGI и возвращать результаты.
В конфигурации IIS сопоставьте * .cgi с php так же, как * .php. Вместо прямого вызова CGI вызовите файл .cgi со следующим кодом PHP:
<?php
putenv('QUERY_STRING=' . $_SERVER['QUERY_STRING']);
echo system('C:... path your cgi...//...delphicgi.exe');
?>
Замените 'C: ... path your cgi ... // ... delphicgi.exe' своим исходным Delphi CGI.
Вот и все! Ваши пользователи не должны заметить никакой разницы. Очевидно, использование PHP снижает производительность. Но, по крайней мере, вам не нужно было перестраивать ваши CGI, и у вас может быть расширение .cgi!
Поставщик CGI подтвердил, что приложение несовместимо с IIS 7.0, и они будут поддерживать его в будущих выпусках.
Я думаю, это говорит о том, что единственное исправление - это изменение кода, упомянутое в статье базы знаний Microsoft.