Write in front
The code is already hosted on https://git.oschina.net/augustus/TinyWS.git
You can clone it down with Git. Since I may occasionally make changes, there is no guarantee that the code on the GIT library will be exactly the same as in the blog (it is not really possible to post all the code here). In addition, TINYWS is written on Linux (Ubuntu 14.10 + Eclipse Luna,eclipse Project I also push to the Git library), so it may not compile properly on Windows (mainly the system calls section may be different).
The previous content can refer to the previous article http://www.cnblogs.com/cuiluo/p/4217205.html
Getrequest
Next, this class is forced to handle the Get method. It inherits from request and requires the override Doexecute method. Its function is to parse out the requested URI and pass it on to the object of the response class for further processing. In the current implementation, the use of CGI to handle dynamic requests (so-called dynamic requests, which is the browser's request to run a server-side program, and get the results returned), but this part of the code is not tested. In this class, the following three methods handle the URI and parameters of the dynamic request.
//GetRequest.h
ClassGetrequest: Publicrequest{Virtual voidDoexecute (); BOOLParseuri (std::string& filename, std::string&Cgiargs); BOOLParsestaticcontenturi (std::string&filename); BOOLParsedynamiccontenturi (std::string& filename, std::string&Cgiargs); voidAssigncigargs (std::string&Cgiargs); voidDoassigncigargs (std::string:: Size_type POS, std::string&Cgiargs);};
In the implementation, the storage path of the static Web page is "test-files", this is mainly to test, if the request does not carry the specified file name, then return to this path " Index.html" file. Programs that serve dynamic requests are stored in the "cgi-bin" directory, and of course there are no programs under this path. In the Doexecute method, after parsing the URI, a response object is created for further processing.
//GetRequest.cppvoidgetrequest::d oexecute () {std::stringfilename, Cgiargs; BOOLIsStatic =Parseuri (filename, Cgiargs); Response (Getfiledescriptor (), filename, Cgiargs, isStatic). respond ();BOOLGetrequest::p Arseuri (std::string& filename, std::string&Cgiargs) { if(GetURI (). Find ("Cgi-bin") = = std::string:: NPOs)returnParsestaticcontenturi (filename); Else returnParsedynamiccontenturi (filename, Cgiargs);}BOOLGetrequest::p Arsestaticcontenturi (std::string&filename) {std::stringURI =GetURI (); FileName="Test-files"+URI; if(Uri[uri.length ()-1] =='/') filename+="index.html"; return true;}BOOLGetrequest::p Arsedynamiccontenturi (std::string& filename, std::string&Cgiargs) {Assigncigargs (Cgiargs); FileName="."+GetURI (); return false;}voidGetrequest::assigncigargs (std::string&Cgiargs) {std::stringURI =GetURI (); STD::string:: Size_type pos = uri.find_first_of ("?"); Doassigncigargs (POS, Cgiargs);}voidGetrequest::d Oassigncigargs (std::string:: Size_type POS, std::string&Cgiargs) { if(pos! = std::string:: NPOs) Cgiargs= GetURI (). substr (POS, GetURI (). Length ()-1); Elsecgiargs.clear ();}
Response
The purpose of the response class is to return the requested file according to the requested URI, and to execute the associated program if it is a dynamic request.
The design of response is not good. First, his constructor requires a bool value to identify whether it is a static web page, which causes many if ... else branches, which I really hate, and then one of its members is the struct stat type, This is a structure that the Linux system calls to provide an identity file attribute, it should not belong to this level, response should be focused on the business, and the operating system to deal with the work should be handed over to others.
So here is the emphasis behind my refactoring, perhaps using a factory or state mode, and so on, but for a state with only two choices, it is too selectmen to use the factory. Currently, we are going to use the state mode, which has added an enum, {STATIC, DYNAMIC}, but has not yet continued. If you modify the code later, you will be referred to the GIT library, which will no longer be modified synchronously.
classresponse{ Public: Response (intFD, std::stringName, std::stringCgiargs,BOOLISSTC); voidrespond ();Private: ConstSTD::stringGetfiletype (); voidPreresond (); voidRespondok (); voidrespondstatic (); voidresponddynamic (); Const voidExecvecgiprogram (); Const voidDoexecvecgiprogram (); ConstSTD::stringbuildrespond0kheaders (); ConstSTD::stringbuildrespondstaticheaders (); ConstSTD::stringbuildforbiddenmsg (); ConstSTD::stringBuildresponderrorheaders (ConstSTD::stringErrnum,ConstSTD::stringshortmsg); ConstSTD::stringBuildresponderrorbody (ConstSTD::stringErrnum,ConstSTD::stringShortmsg,ConstSTD::stringlongmsg); voidResponderror (ConstSTD::stringErrnum,ConstSTD::stringShortmsg,ConstSTD::stringlongmsg);Private: enumState {STATIC, DYNAMIC}; structstat sbuf; intFileDescriptor; STD::stringFileName; STD::stringCgiargs; BOOLisStatic;};
Next
Now, the section on Tinyws's upper-level business is covered. The later section will cover the socket and IO operations related content, left for the next time.
tinyws--a simple Web server written in C + + (ii)