使用FastCGI检测中止的客户端请求

时间:2013-06-27 11:01:10

标签: fastcgi mod-fastcgi

我正在使用Apache,mod_fastcgifcgapp.h API开发FastCGI应用程序。一切都工作到目前为止,但我没有检测到中止的连接。我们需要控制它们,因为我们有时会进行昂贵的操作,当用户中止请求时必须中止这些操作。

我正在尝试使用文档中指出的SIGPIPE,但它似乎不起作用。

我写了一个简化的测试用例来显示我的问题:

#include <iostream>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <fstream>

#include "fcgio.h"

using namespace std;

void signal_handler(int signo) {
  cerr << "SIGNAL RECEIVED: " << signo << endl;
}


int main(void) {
  streambuf * cin_streambuf  = cin.rdbuf();
  streambuf * cout_streambuf = cout.rdbuf();
  streambuf * cerr_streambuf = cerr.rdbuf();

  struct sigaction sa;
  sigemptyset(&sa.sa_mask);
  sa.sa_handler = signal_handler;
  sa.sa_flags = 0;
  sigaction(SIGPIPE, &sa, NULL);
  sigaction(SIGUSR1, &sa, NULL);
  sigaction(SIGTERM, &sa, NULL);

  FCGX_Request request;

  int socketfd = FCGX_OpenSocket("/home/guillermo/fastcgi/socket", 10);
  FCGX_Init();
  FCGX_InitRequest(&request, socketfd, 0);

  while (FCGX_Accept_r(&request) == 0) {
    fcgi_streambuf cin_fcgi_streambuf(request.in);
    fcgi_streambuf cout_fcgi_streambuf(request.out);
    fcgi_streambuf cerr_fcgi_streambuf(request.err);

    cin.rdbuf(&cin_fcgi_streambuf);
    cout.rdbuf(&cout_fcgi_streambuf);
    cerr.rdbuf(&cerr_fcgi_streambuf);

    sleep(5);

    cout << "Content-type: text/html\r\n"
         << "\r\n"
         << "<html>\n"
         << "  <head>\n"
         << "    <title>Hello, World!</title>\n"
         << "  </head>\n"
         << "  <body>\n"
         << "    <h1>Hello!</h1>\n"
         << "  </body>\n"
         << "</html>\n";

    cerr << "All right" << endl;

  }
                                                                                             cin.rdbuf(cin_streambuf);
  cout.rdbuf(cout_streambuf);
  cerr.rdbuf(cerr_streambuf);

  return 0;

}

我尝试了mod_fastcgi的这两种不同配置:

FastCGIExternalServer $file -socket $socket
FastCGIServer         $file -socket $socket

无论我是否中断连接,我都会在5秒后在Apache错误日志中获得“All right”。我已经使用curl(Ctrl-C)和来自不同浏览器(停止按钮)以及来自Javascript的XMLHttpRequest.abort(这是真实场景)测试了它。

这是我的系统配置:

  • Linux Debian 3.2.46-1 x86_64
  • Apache2(2.2.22-13)
  • mod_fastcgi(2.4.1-SNAP-0910052249)

0 个答案:

没有答案