Взаимодействие программы 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>

0 ответов

Другие вопросы по тегам