FastCGI is indispensable in server development. Its usage is as follows:
while( FCGI_Accept() >= 0 ){ printf( "Content-type: text/plain \r\n" "Content-Length: %d\r\n" "Connection: close\r\n\r\n%s\r\n", strlen( buffer ), buffer ); }
The facgcgi header file has the following macros:
#undef fprintf#definefprintf FCGI_fprintf#undef printf#defineprintf FCGI_printf
We can see that the printf function has been macro-switched, and the printf in the program is no longer a standard output. In this way, there is a problem. If you want to debug and print the information to stdout, it will not work.
In actual development, various problems may occur, and sometimes some information needs to be printed. At this time, you can modify the fcgi_stdio.h header file and change it to the following:
#undef _fprintf#define _fprintf FCGI_fprintf#undef _printf#define_printf FCGI_printf
The corresponding macro should also be replaced in the corresponding place in the program.
FastCGI can be parsed using this function:
char *getenv(const char *name)
There are several types of parameters:
Content_type
Content_type |
Request type |
Content_length |
Body segment length |
QUERY_STRING |
Request string |
Take the following HTTP request message as an example:
GET /s?ie=utf-8&bs=%E8%BF%99%E6%98%AF&f=8&rsv_bp=1&rsv_spt=3&wd=%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%BC%80%E5%8F%91&rsv_sug3=11&rsv_sug=0&rsv_sug4=609&rsv_sug1=2&inputT=32681 HTTP/1.1Host: www.baidu.comConnection: keep-aliveContent-Type: text/html;charset=utf-8Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31Referer: http://www.baidu.com/s?wd=%E8%BF%99%E6%98%AF&rsv_bp=0&ch=&tn=baidu&bar=&rsv_spt=3&ie=utf-8&rsv_sug3=4&rsv_sug=0&rsv_sug4=240&rsv_sug1=3&inputT=2835Accept-Encoding: gzip,deflate,sdchAccept-Language: zh-CN,zh;q=0.8Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3Cookie: BAIDUID=A83324E58AE26486E46FC49ED127891B:FG=1; BDSVRTM=163; H_PS_PSSID=1439_2448_2454_2256_1788_2249; WWW_ST=1369271667063
Content_type corresponds to row 5th, and QUERY_STRING corresponds to the first row.
FastCGI is not object-oriented, and all tasks are completed in the main loop, including parsing, processing, and response.
In actual development, to improve efficiency, developers do not have to worry about the underlying layer. I encapsulate it into a class: fcgi_net_duty
#ifndef __FCGI_NET_H__#define __FCGI_NET_H__#define FCGI_NET_OK 0#define FCGI_NET_ERROR 1#define FCGI_NET_PARAM_ERROR 2enum fcgi_net_type{ FCGI_NET_TEXT = 0, FCGI_NET_APP_STREAM, FCGI_NET_IMAGE,};class fcgi_net_duty{public: fcgi_net_duty(); ~fcgi_net_duty(); void do_request();protected: void do_prev(); void do_cast(); virtual void do_handle(); void do_write(); void do_finish(); int get_req_int( const char* param, int *value ); int get_req_ll( const char* param, long long *value ); int get_req_str( const char* param, const char **value ); int get_cookie_int( const char* param, int *value ); int get_cookie_ll( const char* param, long long *value ); int get_cookie_str( const char* param, const char **value );private: std::map< const char*, const char* > m_req; std::map< const char*, const char* > m_cookie; int rtn; int content_type; int content_length; char* content_buf;};
Put the main loop in the do_request Function
Fcgi_net_duty.cpp
void fcgi_net_duty::do_request(){ while( FCGI_Accept() >= 0 ){ do_prev(); do_cast(); do_handle(); do_write(); do_finish(); }}
Subclass only needs to care about the corresponding business. Each business can be completed by a subclass. For example, there are three existing businesses: busi1, bui2, and busi3. Let's take one of them as an example:
Fcig_busi1.h
#ifndef __FCGI_BUSI1_H__#define __FCGI_BUSI1_H__class fcgi_busi1 : public fcgi_net_duty{public: fcgi_busi1(); ~fcgi_busi1(); void do_handle();};#endif //__FCGI_BUSI1_H__
Fcgi_busi1.cpp
void fcgi_busi1::do_handle(){ const char* busi1; int flag; rtn = FCGI_NET_ERROR; flag = get_req_str( "busi1", &busi1 ); if( flag ){ rtn = FCGI_NET_PARAM_ERROR; return; } sprintf( content_buf, "%s","your busi is ok" ); rtn = FCGI_NET_OK;}int main(){ fcgi_busi1 busi1; busi1.do_request();}
Corresponding makefile:
INC=-I./ LIB=-L/usr/lib64 -lfcgiCPPFLAGS=-g -w $(INC)CC=g++BUSI1=./build/busi1BUSI2=./build/busi2BUSI3=./build/busi3all: $(BUSI1) $(BUSI2) $(BUSI3)$(BUSI1): ./fcgi_net_duty.o ./fcgi_busi1.o $(CC) -O $@ $^ $(LIB)$(BUSI2): ./fcgi_net_duty.o ./fcgi_busi2.o $(CC) -O $@ $^ $(LIB)$(BUSI3): ./fcgi_net_duty.o ./fcgi_busi3.o $(CC) -O $@ $^ $(LIB)
Okay. Now a lightweight FastCGI development framework has been built. In real-world development, a member can develop network processing, and others can specialize in corresponding business processing, my philosophy is to let professional people do professional things, so that they can better improve their professional skills.