Взаимодействие программы FastCGI (с использованием сокета tcp) с Apache2
Там!
Как явно указать порт и хост в файле Apache .conf для внешней программы FastCGI?
я хочу попробовать FastCGI
(это будет сложно - tcp sockets
, просто весело учусь;)) и связался с Apache2 на моей малине. Итак, могу ли я напрямую указать порт и хост в apache.conf
файл при использовании включенного модуля fcgid?
Я знаю о fastcgi
модуль, есть возможность указать FastCgiExternalServer
директива порт и хост в конф. Но я решил много проблем при установке этой библиотеки.
Я исследовал - оба эти модуля дополняются друг другом. Поочередно включив один и отключив другой мод, было обнаружено fastcgi
Ответственный за FastCgiExternalServer
директива, но с отключенным fcgid
браузер просто предлагает сохранить myAppFastFCG.fcg
,
Давайте предположим, что проблема была решена.
Теперь у меня есть другая проблема, это состоит из взаимодействия... Apache выдает сообщение об ошибке 500 Internal Server Error
,
Какая-то часть моего апача .conf
ScriptAlias /fcg-bin/ /var/www/site1/fcg-bin/
<Directory /var/www/site1/fcg-bin>
Options +ExecCGI
AddHandler fcgid-script .fcg .py
Order allow,deny
Allow from all
</Directory>
FastCgiExternalServer /var/www/site1/fcgi-bin/p.fcgi -host 127.0.0.1:9999
код C++:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <cstring>
#include <error.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#define MAX_EVENTS 10
#define CONTENT "Content-type: text/plain\r\n\r\n"
#define CONT_LEN sizeof(CONTENT) / sizeof( * ((const char*) CONTENT) )
int set_nonblock(int fd)
{
#if defined(O_NONBLOCK)
int flags = 0;
if (-1 == (flags=fcntl(fd, F_GETFD,0)))
flags = 0;
return fcntl(fd, F_SETFD, flags | O_NONBLOCK);
#else
int flags = 1;
return ioctl(fd, FIOBIO, flags | O_NONBLOCK);
#endif
}
int main(int argc, char* argv[], char* env[])
{
int const ifd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (-1 == ifd) { perror("socket error!"); exit(EXIT_FAILURE); }
//set_nonblock(ifd);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(9999);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
int stat = bind(ifd, reinterpret_cast<struct sockaddr*>(&addr),
sizeof(addr));
if (-1 == stat) ERROR_EXIT(ifd, "bind error!");
stat = listen(ifd, SOMAXCONN);
if (-1 == stat) ERROR_EXIT(ifd, "listen error!");
int pfd = epoll_create1(0);
if (-1 == pfd) ERROR_EXIT(ifd, "epoll_create1 error!");
struct epoll_event ev = { 0 },
evs[MAX_EVENTS] = { 0 };
ev.data.fd = ifd;
ev.events = EPOLLIN;
if ( -1 == epoll_ctl(pfd, EPOLL_CTL_ADD, ifd, &ev) )
ERROR_EXIT(ifd, "epoll_ctl: add error!");
for (;;)
{
int n = epoll_wait(pfd, evs, MAX_EVENTS, -1 );
for (int i = 0; i < n; ++i)
{
if ( ifd == evs[i].data.fd )
{
int iSlave = accept(ifd, NULL, NULL);
if (-1 == iSlave) ERROR_EXIT(ifd, "accept error!");
set_nonblock(iSlave);
ev.events = EPOLLIN;
ev.data.fd = iSlave;
if (-1 == epoll_ctl(pfd, EPOLL_CTL_ADD, iSlave, &ev))
ERROR_EXIT(ifd, "epoll_ctl: add slave error!");
} else {
static const int iLen = CONT_LEN + 255;
static char chBuff[iLen+1] = CONTENT;
char * pBuff = chBuff + CONT_LEN - 1;
::memset(pBuff, 0, iLen-CONT_LEN + 1);
int const bytes = recv( evs[i].data.fd,
pBuff,
iLen - CONT_LEN,
MSG_NOSIGNAL );
if (bytes == 0 && bytes != EAGAIN)
{
shutdown(evs[i].data.fd, SHUT_RDWR);
close(evs[i].data.fd);
} else if (bytes != EAGAIN) {
printf("recv - %s\n", pBuff);
send( evs[i].data.fd,
chBuff,CONT_LEN+bytes-1,
MSG_NOSIGNAL );
//send(evs[i].data.fd, "HELLO", 5, MSG_NOSIGNAL);
}
}
}
}
}
Этот код работает через telnet. Но во время тестирования в браузере при обновлении веб-страницы, команда sudo strace ./a.fcg
не выявил никаких действий. Вместо этого telnet продолжает регистрироваться.
Кстати логи от apache
[Fri Jan 05 13:32:54.974595 2018] [fcgid:warn] [pid 642] (104)Connection reset by peer: [client 192.168.0.103:54524] mod_fcgid: error reading data from FastCGI server
[Fri Jan 05 13:32:54.974715 2018] [core:error] [pid 642] [client 192.168.0.103:54524] End of script output before headers: a.fcg</code>