fcgiapp

FCGX_Stream

该struct定义了FastCGI流的状态。流的状态是私有的,只能通过下面定义的程序访问

FCGX_Request

对一个请求的封装。可供访问的属性:
int requestId       // 是否线程独立?
int role;
FCGX_Stream *in;    // 在post方法中用来读取数据?
FCGX_Stream *out;      // 输出应答内容
FCGX_Stream *err;
char **envp;       // 系统 + Request的环境变量

int FCGX_Init()

Initialize the FCGX library.  Call in multi-threaded apps
before calling FCGX_Accept_r().
Returns 0 upon success.

int FCGX_InitRequest(FCGX_Request *request, int sock, int flags)

Initialize a FCGX_Request for use with FCGX_Accept_r().
参数sock是0(默认)或者是FCGX_OpenSocket()的返回值。
参数flags当前只支持FCGI_FAIL_ON_INTR(实现中并没有定义,都是使用0)。

int FCGX_Accept_r(FCGX_Request *request)

接受一个新的请求(多线程安全)。一定要先调用一次FCGX_Init()。
成功放回0,失败返回-1。

结束request(并释放上一次调用中申请的内存)。创建输入,输出,错误流,
并分别赋值给(request中的)*in,*out,*err。创建包含参数的数据结构,并赋值给*envp,
可以通过getenv(如果将数据赋值给了environ)或FCGX_GetParam来访问。

不要一直保留指向envp数组或其中字符串的指针(例如FCGX_GetParam返回的结果),
因为在下一次调用FCGX_Finish或FCGX_Accept之后,它们都会被freed。

不要直接使用FCGX_Request,他的结构可能改变。

 int FCGX_PutChar(int c, FCGX_Stream *stream)

将字符c写入stream。
成功返回c,失败返回EOF(-1)。

int FCGX_PutStr(const char *str, int n, FCGX_Stream *stream)

从str开始,向stream中写入n个连续字节。对输出字节不做任何解释。
用于二进制输出。
成功返回写入的字节数,失败放回EOF(-1)。

int FCGX_PutS(const char *str, FCGX_Stream *stream)

将已null结尾的字符串str写入stream,由FCGX_PutStr实现。
用于输出字符串。
成功返回写入的字节数,失败放回EOF(-1)。

int FCGX_FPrintF(FCGX_Stream *stream, const char *format, ...)

将格式化字符串format写入stream。
成功返回写入的字节数,失败放回EOF(-1)。

int FCGX_GetChar(FCGX_Stream *stream)

从输入读取一个字节。
返回读取的字节,如果到达输入结尾,则返回EOF(-1).

int FCGX_UnGetChar(int c, FCGX_Stream *stream)

将字符c推回输入流stream。读取一个字符后再推回一个字符是确保可以实现的。
到达EOF后不能再执行推回操作。
如果成功返回c,否则返回EOF。

int FCGX_GetStr(char *str, int n, FCGX_Stream *stream)

从stream中读取n个连续字节到str中。对读入字节不做任何解释。
返回读取的字节数,如果返回值小于n,说明已达到结尾。

char *FCGX_GetLine(char *str, int n, FCGX_Stream *stream)

从stream中读取n-1个连续字节到str中。在读取n-1个字节前,如果碰到'\n'或EOF则停止,
结尾的‘\n’会被复制到str中。当复制完最后一个字节后,在str最后添加字节‘\0’。
如果读取的第一个字节就是EOF,那么返回NULL,否则返回str。

int FCGX_HasSeenEOF(FCGX_Stream *stream)

在读取stream时,如果检测到EOF,那么返回EOF,否则返回0。
请注意,FCGX_HasSeenEOF(s)可能会返回0,然后立即调用FCGX_GetChar(s)可能会返回EOF。
这个功能就像C函数feof,没有提供peek ahead功能。

示例代码:

 1 #include <fcgiapp.h>
 2 #include <string>
 3 #include <sstream>
 4 
 5 int main()
 6 {
 7     FCGX_Request request;
 8 
 9     FCGX_Init();
10     FCGX_InitRequest(&request, 0, 0);
11 
12     int count = 0;
13 
14     while (FCGX_Accept_r(&request) == 0)
15     {
16         // 输出http头部
17         std::string headers = 
18             "Content-type: text/html\r\n"
19             "\r\n";
20         FCGX_PutS(headers.c_str(), request.out);
21 
22         // 输出计数
23         FCGX_FPrintF(request.out, "<p>Count:%d</p>", ++count);
24 
25         // 输出数据长度
26         char *len = FCGX_GetParam("CONTENT_LENGTH", request.envp);
27         FCGX_FPrintF(request.out, "<p>Data length:%s\n</p>", (len ? len : "0"));
28 
29         // 环境变量
30         auto envp = request.envp;
31         std::ostringstream output;
32         output << "<PRE>\n";
33         for (; *envp; ++envp)
34         {
35             output << *envp <<"\n";
36         }
37         output << "</PRE>\n";
38 
39         // 输出
40         FCGX_PutS(output.str().c_str(), request.out);
41 
42         // 获取body中数据,然后输出
43         if (len)
44         {
45             long length = -1;
46             try {
47                 length = std::stol(len);
48             } catch (...){}
49 
50             if (length > 0)
51             {
52                 std::string data(length, '\0');
53                 int size = FCGX_GetStr((char *)data.data(), length, request.in);
54 
55                 FCGX_FPrintF(request.out, "<p>read data size:%d</p>", size);
56                 FCGX_PutStr(data.data(), data.size(), request.out);
57             }
58         }
59     }
60 
61     return 0;
62 }

 

posted @ 2018-06-24 19:05  Droplet  阅读(974)  评论(0编辑  收藏  举报