Implementing a Java HttpServlet-like programming interface in C + +

Source: Internet
Author: User
Tags http post session id

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&nbspThe 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 + +

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.