web(七)---fastcgi再进阶(请求和响应)官方例子

在fast-cgi源码的examples文件夹下有很多例子, 下面给出echo例子, 编译运行方法同上几节.

fast-cgi的API  google之.

http://fossies.org/dox/fcgi-2.4.0/fcgiapp_8h.html#a32f6950798054a70404ce24c22ea28b9

echo-cpp.cpp

#include <stdlib.h>
#ifdef _WIN32
#include <process.h>
#else
#include <unistd.h>
extern char ** environ;
#endif
#include "fcgio.h"
#include "fcgi_config.h"  // HAVE_IOSTREAM_WITHASSIGN_STREAMBUF

using namespace std;

// Maximum number of bytes allowed to be read from stdin
static const unsigned long STDIN_MAX = 1000000;

static void penv(const char * const * envp)
{
    cout << "<PRE>\n";
    for ( ; *envp; ++envp)
    {
        cout << *envp << "\n";
    }
    cout << "</PRE>\n";
}

static long gstdin(FCGX_Request * request, char ** content)
{
    char * clenstr = FCGX_GetParam("CONTENT_LENGTH", request->envp);
    unsigned long clen = STDIN_MAX;

    if (clenstr)
    {
        clen = strtol(clenstr, &clenstr, 10);
        if (*clenstr)
        {
            cerr << "can‘t parse \"CONTENT_LENGTH="
                 << FCGX_GetParam("CONTENT_LENGTH", request->envp)
                 << "\"\n";
            clen = STDIN_MAX;
        }

        // *always* put a cap on the amount of data that will be read
        if (clen > STDIN_MAX) clen = STDIN_MAX;

        *content = new char[clen];

        cin.read(*content, clen);
        clen = cin.gcount();
    }
    else
    {
        // *never* read stdin when CONTENT_LENGTH is missing or unparsable
        *content = 0;
        clen = 0;
    }

    // Chew up any remaining stdin - this shouldn‘t be necessary
    // but is because mod_fastcgi doesn‘t handle it correctly.

    // ignore() doesn‘t set the eof bit in some versions of glibc++
    // so use gcount() instead of eof()...
    do cin.ignore(1024); while (cin.gcount() == 1024);

    return clen;
}

int main (void)
{
    int count = 0;
    long pid = getpid();

    streambuf * cin_streambuf  = cin.rdbuf();
    streambuf * cout_streambuf = cout.rdbuf();
    streambuf * cerr_streambuf = cerr.rdbuf();

    FCGX_Request request;

    FCGX_Init();
    FCGX_InitRequest(&request, 0, 0);

    while (FCGX_Accept_r(&request) == 0)
    {
        // Note that the default bufsize (0) will cause the use of iostream
        // methods that require positioning (such as peek(), seek(),
        // unget() and putback()) to fail (in favour of more efficient IO).
        fcgi_streambuf cin_fcgi_streambuf(request.in);
        fcgi_streambuf cout_fcgi_streambuf(request.out);
        fcgi_streambuf cerr_fcgi_streambuf(request.err);

#if HAVE_IOSTREAM_WITHASSIGN_STREAMBUF
        cin  = &cin_fcgi_streambuf;
        cout = &cout_fcgi_streambuf;
        cerr = &cerr_fcgi_streambuf;
#else
        cin.rdbuf(&cin_fcgi_streambuf);
        cout.rdbuf(&cout_fcgi_streambuf);
        cerr.rdbuf(&cerr_fcgi_streambuf);
#endif

        // Although FastCGI supports writing before reading,
        // many http clients (browsers) don‘t support it (so
        // the connection deadlocks until a timeout expires!).
        char * content;
        unsigned long clen = gstdin(&request, &content);

        cout << "Content-type: text/html\r\n"
                "\r\n"
                "<TITLE>echo-cpp</TITLE>\n"
                "<H1>echo-cpp</H1>\n"
                "<H4>PID: " << pid << "</H4>\n"
                "<H4>Request Number: " << ++count << "</H4>\n";

        cout << "<H4>Request Environment</H4>\n";
        penv(request.envp);

        cout << "<H4>Process/Initial Environment</H4>\n";
        penv(environ);

        cout << "<H4>Standard Input - " << clen;
        if (clen == STDIN_MAX) cout << " (STDIN_MAX)";
        cout << " bytes</H4>\n";
        if (clen) cout.write(content, clen);

        if (content) delete []content;

        // If the output streambufs had non-zero bufsizes and
        // were constructed outside of the accept loop (i.e.
        // their destructor won‘t be called here), they would
        // have to be flushed here.
    }

#if HAVE_IOSTREAM_WITHASSIGN_STREAMBUF
    cin  = cin_streambuf;
    cout = cout_streambuf;
    cerr = cerr_streambuf;
#else
    cin.rdbuf(cin_streambuf);
    cout.rdbuf(cout_streambuf);
    cerr.rdbuf(cerr_streambuf);
#endif

    return 0;
}
时间: 2024-11-08 23:11:57

web(七)---fastcgi再进阶(请求和响应)官方例子的相关文章

web(六)---fastcgi再进阶(请求和响应)

接上节, 上节只有响应---cout,  本节获取地址栏的QUERY_STRING, 然后响应. 一. req_resp.cpp. #include <stdlib.h> #include <string.h> #include <unistd.h> #include "fcgio.h" #include "fcgi_config.h" using namespace std; int main (void) { int coun

web(六)---fastcgi进阶(请求和响应)

接上几节, 本节写有请求和响应的demo. 一. myecho.cpp如下: #include <stdlib.h> #include <unistd.h> #include "fcgio.h" #include "fcgi_config.h" using namespace std; int main (void) { int count = 0; long pid = getpid(); streambuf * cin_streambuf

JSP内置对象——九大内置对象简介与四种作用域范围以及Web程序的请求和响应模式

最近在学习JSP相关基础知识,我们都知道JSP当中存在一组不使用new关键字就可以在脚本和表达式中使用的对象,在Web开发中经常使用.为了能更好的理解这些对象,在此对JSP内置对象作一些归纳. 目录: JSP内置对象——九大内置对象简介与四种作用域范围以及Web程序的请求和响应模式 JSP内置对象——out(待更新) JSP内置对象——request/response(待更新) JSP内置对象——session(待更新) JSP内置对象——application(待更新) JSP内置对象——其他

浅谈HTTP请求与响应

HTTP协议用于客户端和服务器之间的通信,请求访问的一段是客户端,提供资源响应的一段是服务器端. HTTP通信是采用请求应答的方式来进行的,客户端发出请求,服务器响应.如果没有客户端的请求,服务器端是不进行任何响应的.HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列4个步骤: (1)建立TCP连接 在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接,该连接是通过TCP /IP完成,这是在网络层进行的.HTTP是比TCP更高层次的应用

Play Framework Web开发教程(16): 处理HTTP请求和响应

设计应用的一个方面是规划HTTP请求的URL规范,超链接,HTTP表单以及可能的公用API接口.在Play这是通过路由配置,然后在控制器中实现相应的接口.Play应用中的路由配置可以Controller类构成了MVC框架中的控制层,如下图所示:在Play应用中Controller为定义了HTTP接口的Scala类,而你的路由配置决定了给定的HTTP请求调用哪个Controller中定义的方法,这些Controller中的方法称为Action(动作),因此Play 的MVC框架也称为基于"动作&q

你知道web项目中Http请求与响应的四种情况吗

[四种情况]: HttpRequest.HttpResponse.HttpServletRequest.HttpServletResponse[什么是HTTP?]超文本传输协议(HyperText Transfer Protocol -- HTTP)是一个设计来使客户端和服务器顺利进行通讯的协议.HTTP在客户端和服务器之间以request-response protocol(请求-回复协议)工作.[Http常用的两个方法]get - 从指定的服务器中获取数据post - 提交数据给指定的服务器

初入网络系列笔记(4)HTTP请求和响应

一.借鉴说明,本博文借鉴以下博文 1.starok,HTTP必知必会,http://www.cnblogs.com/starstone/p/4890409.html 2.CareySon,HTTP协议漫谈,http://www.cnblogs.com/CareySon/archive/2012/04/27/HTTP-Protocol.html 3.逖靖寒,浅析HTTP协议,http://www.cnblogs.com/gpcuster/archive/2009/05/25/1488749.htm

Web安全测试之跨站请求伪造(CSRF)篇

跨站请求伪造(即CSRF)被Web安全界称为诸多漏洞中“沉睡的巨人”,其威胁程度由此“美誉”便可见一斑.本文将简单介绍该漏洞,并详细说明造成这种漏洞的原因所在,以及针对该漏洞的黑盒测试与灰盒子测试具体方法和示例,最后提提了一些防范该攻击的建议,希望本文对读者的安全测试能够有所启发. 一.CSRF概述 我们首先来了解一下什么是跨站请求伪造(CSRF)?跨站请求伪造是一种挟制终端用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法.攻击者只要借助少许的社会工程诡计,例如通过电子邮件或者是聊天

J2EE请求与响应—Servlet

一.什么是Servlet? Servlet是运行Web服务器上的一个特殊Java类,其特殊用途是响应客户端请求并做出处理,使得客户端与服务器端进行交互. 二.生命周期  Servlet生命周期是通过Web容器控制,主要分为以下几个阶段: 创建servlet的实例 初始化阶段,调用init()方法 响应请求,调用service()方法 销毁实例,调用destroy()方法 实例垃圾回收,调用finalize()方法  三.Servlet中几个重要的方法: 在Servlet生命周期中,servlet