Use and encapsulation of fastcgi

Source: Internet
Author: User

Fastcgi is indispensable in server development. Its usage is as follows:


[Cpp]
While (FCGI_Accept ()> = 0 ){
Printf ("Content-type: text/plain \ r \ n"
"Content-Length: % d \ r \ n"
"Connection: close \ r \ n % s \ r \ n", strlen (buffer), buffer );
}

While (FCGI_Accept ()> = 0 ){
Printf ("Content-type: text/plain \ r \ n"
"Content-Length: % d \ r \ n"
"Connection: close \ r \ n % s \ r \ n", strlen (buffer), buffer );
}

 


The facgcgi header file has the following macros:


[Cpp]
# Undef fprintf
# Define fprintf FCGI_fprintf
# Undef printf
# Define printf FCGI_printf

# Undef fprintf
# Define fprintf FCGI_fprintf
# Undef printf
# Define printf 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:


[Cpp]
# Undef _ fprintf
# Define _ fprintf FCGI_fprintf
# Undef _ printf
# Define _ printf FCGI_printf

# 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:


[Cpp]
Char * getenv (const char * name)

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:


[Cpp]
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.1
Host: www.baidu.com
Connection: keep-alive
Content-Type: text/html; charset = UTF-8
Accept: text/html, application/xhtml + xml, application/xml; q = 0.9, */*; q = 0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31
Referer: 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 = 2835
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN, zh; q = 0.8
Accept-Charset: GBK, UTF-8; q = 0.7, *; q = 0.3
Cookie: BAIDUID = a83324e58ae26486e46fc49ed0000891b: FG = 1; BDSVRTM = 163; H_PS_PSSID = 1439_2448_2454_2256_1788_2249; WWW_ST = 1369271667063

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.1
Host: www.baidu.com
Connection: keep-alive
Content-Type: text/html; charset = UTF-8
Accept: text/html, application/xhtml + xml, application/xml; q = 0.9, */*; q = 0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31
Referer: 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 = 2835
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN, zh; q = 0.8
Accept-Charset: GBK, UTF-8; q = 0.7, *; q = 0.3
Cookie: BAIDUID = a83324e58ae26486e46fc49ed0000891b: 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


[Cpp]
# Ifndef _ FCGI_NET_H __
# Define _ FCGI_NET_H __
 
# Define FCGI_NET_ OK 0
# Define FCGI_NET_ERROR 1
# Define FCGI_NET_PARAM_ERROR 2
 
Enum fcgi_net_type
{
FCGI_NET_TEXT = 0,
FCGI_NET_APP_STREAM,
FCGI_NET_IMAGE,
};
 
Fcclass gi_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 * 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 * 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;
 
};

# Ifndef _ FCGI_NET_H __
# Define _ FCGI_NET_H __

# Define FCGI_NET_ OK 0
# Define FCGI_NET_ERROR 1
# Define FCGI_NET_PARAM_ERROR 2

Enum fcgi_net_type
{
FCGI_NET_TEXT = 0,
FCGI_NET_APP_STREAM,
FCGI_NET_IMAGE,
};

Fcclass gi_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 * 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 * 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


[Cpp]
Void fcgi_net_duty: do_request ()
{
While (FCGI_Accept ()> = 0 ){
Do_prev ();
Do_cast ();
Do_handle ();
Do_write ();
Do_finish ();
}
}

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


[Cpp]
# 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 __

# 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
[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 ();
}

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:

[Cpp]
INC =-I ./
LIB =-L/usr/lib64-lfcgi
 
CPPFLAGS =-g-w $ (INC)
CC = g ++
 
BUSI1 =./build/busi1
Bui2 =./build/bui2
BUSI3 =./build/busi3
 
All: $ (BUSI1) $ (bui2) $ (BUSI3)
 
$ (BUSI1):./fcgi_net_duty.o./fcgi_busi1.o
$ (CC)-O $ @ $ ^ $ (LIB)
 
$ (Bui2):./fcgi_net_duty.o./fcgi_busi2.o
$ (CC)-O $ @ $ ^ $ (LIB)
 
$ (BUSI3):./fcgi_net_duty.o./fcgi_busi3.o
$ (CC)-O $ @ $ ^ $ (LIB)

INC =-I ./
LIB =-L/usr/lib64-lfcgi

CPPFLAGS =-g-w $ (INC)
CC = g ++

BUSI1 =./build/busi1
Bui2 =./build/bui2
BUSI3 =./build/busi3

All: $ (BUSI1) $ (bui2) $ (BUSI3)

$ (BUSI1):./fcgi_net_duty.o./fcgi_busi1.o
$ (CC)-O $ @ $ ^ $ (LIB)

$ (Bui2):./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.

 


 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.