Since 99, I began to contact with the network programming, the original project is written in C language a lot of CGI, can be described as the pain of the programming, because at that time the domestic technical level is generally relatively low, if you will CGI programming, it is already a person in the industry, if you are more skilled in CGI programming, it could be called "expert ", then the technology continues to progress, a variety of foreign technologies have entered China and continue to be popularized, CGI gradually reduced to a backward technology, later PHP, Jsp/servlet, ASP gradually occupied the WEB programming of the technical market, this time if you say again with C write CGI, Others will feel that they are talking with the ancients. Now the main advantage of the mainstream WEB development language is that there are a variety of relatively mature basic libraries and frameworks, the development efficiency is very high, and CGI is much less. Of course, these languages also have a relatively inefficient implementation of the problem, after all, they are scripting language or semi-compiled language, the need for virtual machine interpretation of execution, like Facebook's WEB front end is basically written in PHP, in order to solve the problem of implementation efficiency, under the leadership of a Chinese to develop the PHP code can be translated into C + + code tool (hiphop), which makes execution much more efficient, and it also reflects on the other side that technicians still want their programs to run faster.
This article mainly describes the Acl_cpp library in the WEB programming method class, in order to make everyone easy to get started, the interface design and naming as far as possible to imitate the JAVA HttpServlet and other related classes. If you are programming in C/D + + and you have experience using Java Servlet for Web programming, you will not have much trouble reading it, but if you have been working on web development for many years, I would like to understand the design and usage of these classes should not be difficult. Okay, here's how to do Web programming using classes under the http/module in the Acl_cpp library.
Under the Acl_cpp/src/http module, there are several classes related to WEB programming: Httpservlet,httpservletrequest, HttpServletResponse, HttpSession, Http_header, Http_mime, Http_client. If you have mastered the use of these classes, then there is no problem with WEB programming, and here are some of these classes:
First, HttpServlet class
Constructors and destructors:
/** * constructor */httpservlet (void);/** * Pure virtual destructor, that is, the class must be instantiated by a subclass */virtual ~httpservlet (void) = 0;
In the build function, in order to support the storage of HttpSession data, users need to give Memcached server address (currently only support the use of Memcached to store session data, in the future should be extended to support redis, etc.), while the user also need to give the SE Ssion the cookie ID identifier to be sent to the browser.
Four virtual interfaces that require subclasses to implement HTTP requests for different browsers:
/** * When HTTP request is GET mode virtual function */virtual bool Doget (httpservletrequest& httpservletresponse&);/** * When HTTP request is POST virtual function */virtual bool DoPost (httpservletrequest&, httpservletresponse&),/** * When HTTP request is PUT mode, virtual function */virtual b Ool DoPut (httpservletrequest&, httpservletresponse&);/** * virtual function when HTTP request is CONNECT mode */virtual bool Doconnect (Ht Tpservletrequest&, httpservletresponse&);/** * virtual function when HTTP request is PURGE mode, this method uses */virtual bool DoP when clearing SQUID cache * Urge (Httpservletrequest&, httpservletresponse&);
The user-implemented HttpServlet subclass can implement one or more of the above virtual interfaces to satisfy different HTTP requests.
The following function starts the function for the HttpServlet class:
The/** * httpservlet object starts running, receives HTTP requests, and callbacks the following doXXX virtual functions * @param session {session&} Storage session Data Objects * @param stream {socket_ stream*} This parameter must be non-empty when under acl_master Server framework control * run, when apache under cgi Run with this parameter * set to NULL; Additionally, the flow connection is not closed inside the function, and the application should handle the closing of the stream object * itself, so that it is easy to acl_master Architecture combined * @param body_parse {bool} for POST method, this parameter specifies whether you want to * read HTTP request the data body and analyze it in n/v mode, and when true , the * part reads HTTP request body data, and analysis, when the user calls getParameter * , not only can get the parameters in URL , but also can get post the parameters of * in the data body, and does not read the data body * @param body_limit {when the parameter is false int} for the POST method, this parameter restricts the length of the data body when the data body is a text parameter * type, when the data body is a data flow or MIME * Format or body_read for false, this parameter is invalid * @return {bool} returns the processing result */bool dorun (session& Session, socket_stream* stream = null,bool body_parse = true, int body_limit = 102400);/** * httpservlet object starts running, receives HTTP requests, and callbacks the following doxxx virtual function, * Calling this function means using memcached to store session data * @param memcached_addr {const char*} memcached server address, format:ip:port * @param stream {socket_stream*} meanings Ibid. * @param body_parse {bool} Meanings Ibid. * @param body_limit {int} meanings Ibid. * @return {bool} return processing result */bool dorun (const char* memcached_addr = "127.0.0.1:11211", Socket_stream* stream = null,bool  BODY_PARSE = TRUE, INT BODY_LIMIT = 102400);
From the five virtual methods above, you can see two important classes: HttpServletRequest and HttpServletResponse. These two classes represent the HTTP request class and the HTTP response class, each of which is created and freed by the HttpServlet class object, so the user does not have to create and destroy the two class object instances. These two classes are described below:
Second, HttpServletRequest class
This class is primarily related to the browser's request process, and you can obtain the browser's request data by means of that class. The methods of this class are much more (basically referencing the functional methods and names of Java HttpServlet), so here are just a few of the main methods:
/** * gets the parameter value in the HTTP request, which has been URL decoded and the character set required by the * conversion cost, for the GET method, is to get the parameter values in * URL ? , and for the POST method, you can get * URL in ? The parameter value in the following argument value or in the request Body */const char* getparameter (const char* name) const;/** * Get HTTP A cookie value for client requests * @param name {const char*} cookie name, must be non-empty * @return {const char*} cookie value when returning NULL * cookie value does not exist */const char* getcookievalue (const char* name) const;/** * get HttpSession object references associated with this HTTP session * @return { Httpsession&} */httpsession& getsession (void);/** * acquisition and HTTP Client connection associated input stream object reference * @return {istream&} */istream& getinputstream (void) const;/** * Get http The data length of the request data * @return {acl_int64} return -1 represents the possible GET method, * or HTTP no Content-Length field */in the request header #ifdef WIN32__int64 Getcontentlength (void) const; #elselong long int getcontentlength (void) const; #endif/* * * Content-Type for * multipart/form-data; boundary= in the HTTP request header xxx format, the description is file upload * data type, you can get http_mime objects * @return by this function {const http_mime*} returns NULL indicates that no MIME object, * The value returned by the user cannot be released manually because the */http_mime* gethttpmime (void) is automatically released in the analysis of httpservletrequest * . const;/** * get HTTP Request data type * @return {http_request_t}, General to POST upload in method * file application, you need to call this function to get whether it is an upload data type */http_request_t getrequesttype (void) const;
The above methods are generally used in the actual use of HttpServletRequest class methods used in the process of more. Such as:
Getparmeter: Used to get HTTP request parameters
Getcookievalue: Get cookie value of browser
GetSession: Gets the session of the HttpServlet class object
getInputStream: Getting an input stream for an HTTP connection
Getcontentlength: For HTTP POST requests, this function obtains the length of the HTTP request data body
Getrequesttype: For HTTP POST requests, this function returns the way the HTTP request data body is transmitted (normal Name=value mode, multipart upload file format, and data stream format)
Third, HttpServletResponse class
This class is primarily related to the process of returning your written program to the browser, and only some of the common functions of that class are described below, if you need more functionality, parameter HTTPSERVLETRESPONSE.HPP header file.
/** * Settings HTTP response data Body Content-Type field values can be field values of: * text/html or text/html; charset=utf8 format * @param value {const char*} field values */void setcontenttype (const char* value);/** * set HTTP response data in the body character set, when already in setContentType set * The character set, you do not have to call this function to set the charset * @param charset {const char*} Character Set */void setcharacterencoding (Const char* charset) of the response body data;/** * Settings HTTP status codes in the response header:1xx, 2xx, 3xx, 4xx, 5xx * @param status {int} HTTP Response status code, such as: 200 */void setstatus (int status);/** * add cookie * @param name {const char*} cookie names * @param value {const char*} cookie Values * @param domain {const char*} cookie Storage domains * @param path {const char*} cookie storage paths * @param expires {time_t} cookie expiration interval, when the current time plus * the value is cookie expiration time truncated (seconds) */void addcookie (const char* name, const char* value,const char* domain = NULL, const char* path = null,time_t expires = 0);/** * Send http response header, the user should send the data body before calling this function to send HTTP * response hair to the client */bool sendheader (void);/** * Gets the output stream object of the HTTP response object, which is sent through the output stream after the user calls sendHeader sends * ends HTTP The response header, http data Body * @return {ostream&} */ostream& getoutputstream (void) Const
Setcharacterencoding: This method sets the character set of the HTTP data body of the HTTP response header, and if you set the character sets through the function, the browser will prefer to use the character set in the HTTP response header, even if you reset the other character sets in the returned HTML data. So the user must pay attention to this;
setContentType: This method is used to set the Content-type field in the HTTP response header, set the text/xml for the XML data, set the text/html for the HTML data, and, of course, you can set the Image/jpeg data type; You can also specify the character set of the data directly by setting the data type, as you can directly write: setContentType ("text/html; Charset=utf8 "), this usage is equivalent to: setContentType (" text/html "); Setcharacterencoding ("UTF8").
SetStatus: Set the status code of the HTTP response header (usually without setting the status code, unless you really need to set it separately);
Addcookie: Adding cookie content to the HTTP response header;
Sendheader: Send HTTP response header;
Getoutputstream: The function returns the output stream object, which you can write to the output stream directly to the data body of the HTTP response (for the use of the Ostream class, parameter header file: INCLUDE/OSTREAM.HPP).
In addition to the above three classes, there is one more important class: The HttpSession class, which implements the functions related to session sessions mainly:
Four, HttpSession class
This class of object instance users also does not have to create and dispose of such object instances automatically in the Httpservet class object content. The main methods used are:
/** * Gets the corresponding session variable name stored by the client on the server side, the subclass can overload the method * @param name {Const CHAR*} session name, non-null * @return {CONST char*} session value, empty description nonexistent or internal * query failed */virtual const char* getattribute (const char* name) const;/** * Set server side session value corresponding to session name, subclass can overload the method * @ param name {Const char*} session name, non-null * @param name {Const CHAR*} session value, non-null * @return {BOOL} return False description setting failed */virtual BOOL SetAttribute (const char* name, const char* value);
The only reason to declare these two methods as virtual is because HttpSession's session data store currently supports only memcached, and if you have the energy you can implement a subclass to support other data storage methods. You can, of course, implement your own method of generating a unique session ID in a subclass of your implementation, which implements the following virtual method:
protected:/** * Creates a unique ID number for a session, the subclass can overload the method * @param buf {char*} to store the result buffer * @param len {size_t} buf buffer size, buf buffer size recommendations * 64 bytes or so */virtual void Createsid (char* buf, size_t len);
Well, there's a whole bunch of classes and class functions, and here's a concrete example of how these classes are used:
V. Examples
The following example is a CGI example, the compiled executable program can be placed directly in the Apache cgi-bin/directory, the user can be accessed by the browser.
http_servlet.cpp : defines the entry point of the console application. #include "LIB_ACL.HPP" using namespace acl;/////////////////////////////////////////////////// Class http_servlet : public httpservlet{public:http_servlet (void) {} ~http_servlet (void) {}// functions that implement processing HTTP GET requests Virtual bool doget ( Httpservletrequest& req, httpservletresponse& res) {return dopost (req, res);} Implement processing HTTP POST request function Virtual bool dopost (Httpservletrequest& req, httpservletresponse& res) {// A variable value of session for a browser user, set a const char* if it does not exist sid = req.getsession (). getattribute ("Sid");if (sid == null | | *sid == 0) req.getsession (). SetAttribute ("Sid", "xxxxxx");// fetch the session of the browser user again A property value of Sid = req.getsession (). getattribute ("Sid");// get two cookie from the browserValue Const char* cookie1 = req.getcookievalue ("name1"); const char* cookie2 = req.getcookievalue ("name2");// start creating HTTP response header// Settings cookie res.addcookie ("name1", " Value1 ");// set the cookieres.addcookie with scope and expiration time (" Name2 ", " value2 ", ". test.com ", "/",  3600 * 24)//res.setstatus; // can set the returned status code// two ways to set the character set if (0) Res.setcontenttype ("text/xml; charset=gb2312");else{// first set the data type Res.setcontenttype ("Text/xml");// Set Data Character set res.setcharacterencoding ("gb2312");} get two parameter values for browser requests const char* param1 = req.getparameter ("name1");const char* Param2 = req.getparameter ("name2");// create xml format the data body xml body;body.get_root (). add_ Child ("root", true). Add_child ("Sessions", true). Add_child ("session", true).Add_attr ("Sid", sid ? sid : "null"). Get_parent (). Get_parent (). Add_child ("Cookies", true). Add_child ("Cookie", true). Add_attr ("name1", cookie1 ? cookie1 : " Null "). Get_parent (). Add_child (" Cookie ", true). Add_attr (" name2 ", cookie2 ? cookie2 : "null"). Get_parent (). Get_parent (). Add_child ("params", true). Add_child ("param", true). Add_attr ( "name1", param1 ? param1 : "null"). Get_parent (). Add_child ("param", true). add_ attr ("name2", param2 ? param2 : "null"); String buf;body.build_xml (BUF);// Send http response header if (Res.sendheader () == false) return false;// send http Response Body if (Res.getoutputstream (). Write (BUF) == -1) return false;return true;} Protected:private:};//////////////////////////////////////////////////////////////////////////int main ( void) {#ifdef win32acl::acl_cpp_iNIT (); // win32 requires initialization of the library #endifhttp_servlet servle;// cgi Start running Servlet.dorun ("127.0.0.1:11211"); // start running, and set the service address for memcached to: 127.0.0.1:11211// operation completed, program exit return 0;}
Users who often use Java HttpServlet and other classes for Web programming must not be unfamiliar with the code above, but it is indeed a C + + program that can be run under Apache and CGI-enabled Webserver (or run as a standalone server). Of course, it should be clear that CGI is inefficient due to process switching at runtime, and in another article, "Writing a Web server program using Acl_cpp's HttpServlet class and server framework" shows the Http_servlet class and combining acl_cpp Server model implementation of a Web server example, more efficient than CGI (the efficiency should be higher than fcgi, because it is less than the Webserver layer of filtering); The article "Acl_cpp Web Programming File Upload" Examples of how to use Acl_cpp on the server side The library handles the browser's ability to upload files.
The above example uses another class: XML class, please refer to the blog: "acl_cpp programming XML streaming parsing and creation"; If you want to understand the HTTP protocol, please refer to the article: "Introduction to HTTP Protocol"
directory where the example is located: acl_cpp/samples/cgi
Personal Micro-blog: Http://weibo.com/zsxxsz
Implementing a Java HttpServlet-like programming interface in C + +