Итак, я создаю интерфейс fastCGI для языка программирования, основанного на времени выполнения и работающего в средах Windows, Linux и UNIX.
Я реализовал протокол fastCGI в программном коде, работающем во время выполнения, но у меня возникла проблема с кодом Windows, который взаимодействует с mod_fcgid. В этом случае я не могу использовать готовые dll для предоставления функций fastCGI, но я могу вызывать большинство функций C из этого языка выполнения. Я не могу изменить среду выполнения, поскольку она принадлежит другой компании... Думайте об этом как о языке, подобном php или perl. То, что я пытаюсь сделать, похоже на создание dll-подобного набора кода (это не dll) для обработки запроса fastCGI. Хотя многие скажут, что я «изобретаю велосипед», у меня нет другого выбора, кроме как использовать чью-то готовую dll для предоставления интерфейса для fastCGI.
Я успешно все реализовал, и я могу получить первоначальный запрос и ответить веб-страницей через мой интерфейс fastCGI. Проблема, с которой я сталкиваюсь, связана со «следующим» запросом при работе под Windows. Мой код при работе под Linux работает потрясающе: я accept() сокет, read() write() для выполнения моей обработки, close() сокет, а затем возвращаюсь и снова accept(), и я получаю следующий запрос и все отлично обрабатывается.
Под Windows mod_fcgid использует именованные каналы. В моем коде я использую GetStdHandle(), чтобы получить дескриптор стандартного ввода, затем использую ReadFile() и WriteFile(), и данные, завернутые в протокол fastCGI, передаются в mod_fcgid, а затем в браузер, когда выполняется запрос, я использую CloseHandle( ), а затем возвращаюсь к GetStdHandle(), чтобы дождаться следующего запроса.
Все отлично работает по первому запросу, браузер получает мой вывод cgi. Тот же код под Linux, использующий сокеты, получает 2-й и последующие запросы и работает как шарм.
Мои проблемы: при работе под Windows после обработки первого запроса я не могу заставить mod_fcgid отправить мне второй запрос. В конечном итоге это убьет мой процесс Windows и запустит новый на его месте. Чего я, конечно, не хочу.
Должно быть, я делаю что-то неправильно между моментом, когда я отправляю fastCGI EndRequest, и когда я зацикливаюсь, чтобы дождаться поступления следующего запроса.
Чтобы получить первоначальный запрос от mod_fcgid, я использую GetStdHandle(), затем я использую ReadFile() и WriteFile() (все из kernel32.dll), и когда я закончил протокол с его EndRequest, я не могу получить правильный код. может получить второй запрос.
Я пробовал fflush() Я пробовал FileFlushBuffers(), я пытался не закрывать дескриптор, полученный от GetStdHandle(), я просто не могу понять, что нужно mod_fcgid от моего приложения Windows, чтобы я мог получить второй и последующие запросы.
После первого запроса, закрывая мой дескриптор, получая дескриптор стандартного ввода из GetStdHandle, а затем сидя на ReadFile, ReadFile() возвращается с 0 байтами, а GetLastError() всегда возвращает 6 (неверный дескриптор).
Я просто не могу понять, какие функции C использовать для очистки после завершения первого запроса и иметь возможность ждать поступления следующего запроса при работе под Windows. Как я уже говорил, код отлично работает под Linux при использовании сокетов вместо Windows, которая использует дескриптор из STDIN, который является именованным каналом.
STDIN/STDOUT
. - person Ctx   schedule 11.01.2017