Use C ++ to implement HTTP server-Windows platform (Open Source Code)

Source: Internet
Author: User
Tags http 200

Use C ++ to implement HTTP server-Windows Platform
Software name: Que's HTTP Server (click to download the latest version with source code)
Author: Que rongwen-Que's C ++ Studio
Copyright description:Free, open source code, prohibited for commercial use.
Date: 2011.7.8

1. Purpose and purpose

Use C ++ to implement a simple HTTP Server Model in Windows and use it as a file sharing tool in the LAN.
I used to share large files (more than 2 GB) with my colleagues in the company. If I share the Windows directory directly, it is very insecure, it is often caused by various problems, such as the disabled guest user and firewall interception. now, I only need to open this program (a very simple program with only a few hundred K size EXE files), the other party can use the browser (IE, Firefox, and so on, is there a wider range of clients than browsers ?) Accessing my shared files also supports resumable data transfer.
In addition, this is an HTTP server that meets the Protocol requirements. In theory, it is acceptable to put it on the public network, but the functions are not mature, such as Apache and IIS, and the security performance is also insufficient, however, as a learning model, it is still okay to provide the file download service.

2. Principles

(1) about HTTP.
I personally like HTTP very much. This is a simple, text-based, and responsive protocol.
One of the major advantages of text-based debugging is that debugging is particularly convenient, because all the data is texts that can be directly read, and the program results are correct or not at a glance, there are many other advantages, for more information, see <UNIX programming art>, which describes the benefits of text-based protocols.
The communication process of the HTTP protocol can be simply described as: the two sides establish a TCP connection, the client (usually a browser) sends a fixed format of text (so-called requests ), the server generates and responds to a fixed format of text (so-called response header) and file content (if the client requests a file download) based on the content of the client request. After the data is sent, disconnect.
This is the foundation of today's online world.
Of course, both client requests and Server Response Headers have format requirements. You can read W3C documentation on HTTP. (The Que's HTTP Server Release package also contains a copy. Please click the link at the beginning of the article to download it .)

(2) Windows network model.
In Windows, when the network performance of the complete port model is the best, as an HTTP Server that may face huge network pressure, the complete port model is the only choice.
After the port model is completed, network operations are processed in a way similar to callback. All network operations are not blocked, but are returned directly after queuing. After the operation is completed, the system will trigger a complete port event to notify the application. therefore, as long as the application uses a thread to check the corresponding port for completion, the results of network operations can be obtained. unlike callback, the system allows multiple threads to wait for the same completed port event at the same time. In Windows, ensure that only one waiting thread is awakened for a completed port time. in this way, for machines with multiple CPUs, we can create multiple threads (one CPU corresponds to one thread) wait for the same completed port event to process network events in parallel to give full play to the performance of the machine.
For instructions on port programming, see Chapter 8 <Windows Network Programming Technology> (published by Microsoft, by Anthony Jones.

3. Program Structure

CHTTPServer object
The CHTTPServer object represents the existence of the entire HTTP server in the memory. It is responsible for creating the port model, creating the required thread, monitoring the port events, and maintaining the correspondence between the URL and the real files on the server. in addition to maintaining the network module, the CHTTPServer object also generates the correct server response based on the received client request. its role and ASP. the predefined Server objects used in NET or JSP programming are similar.

CHTTPRequest object
The CHTTPRequest object is the packaging of client requests. Because the client request is a formatted text, it is a string in programming language. For programming convenience, I created a CHTTPRequest object to manage this string, the CHTTPRequest object provides several methods to easily access various parameters of client requests. its role and ASP. the predefined Request object used in NET or JSP programming is similar.

CHTTPResponse object
The CHTTPResponse object is the packaging of the server response. The CHTTPServer object sets the parameters of the CHTTPResponse object based on the content of the CHTTPRequest object. Finally, the CHTTPResponse object outputs these parameters as text conforming to the HTTP protocol requirements. its role and ASP. the predefined Response object used in NET or JSP programming is similar.

CHTTPContent object
The CHTTPContent object represents the resource (URL) requested by the client ). it may be a file, or an HTML/TEXT generated by a server, such as a file list in a directory or an error message, such as a prompt that the HTTP404 file cannot be found.

The process for running the program is as follows:
The CHTTPServer object starts and monitors the network module. After a new client connection is established, the CHTTPServer object starts to read the new connection until it receives a complete request header.
When the CHTTPServer object receives a complete request header, it creates a new CHTTPRequest object with the parameter, analyzes the CHTTPRequest object, and generates the correct CHTTPResponse object and CHTTPContent object, then, the text output by the CHTTPResponse object and the content of the CHTTPContent object are sent to the client in order, and the connection is closed after the data is sent to recycle the above objects.

4. Core code analysis

Next, paste a CHTTPServer object to generate the key code of the CHTTPResponse object and CHTTPContent object based on the content of the CHTTPRequest object.

// A complete Request header has been received. Processing // Objective: To analyze the Request object and prepare the Response object, and, if possible, generate a Content Object and associate it with the Response object. void CHTTPServer: OnRequest (PCLIENTINF pSockInf) {ASSERT (pSockInf); ASSERT (pSockInf-> pRequest); ASSERT (pSockInf-> pResponse); std :: wstring strUrlObject (L ""); std: wstring strServerFilePath (L ""); // whether the request header is valid if (! PSockInf-> pRequest-> Verify () {// The Request Header Format is incorrect, return HTTP 400 and a predefine text pSockInf-> pResponse-> SetServerCode (SC _BADREQUEST); // HTTP 400 CHTTPContent * pContent = new CHTTPContent; pContent-> OpenText (g_HTTP_Bad_Request, strlen (g_HTTP_Bad_Request); pSockInf-> pResponse-> AttachContent (pContent); goto exit ;} // whether the request method is GET or HEADHTTP_METHOD method = pSockInf-> pRequest-> GetMethod (); pSockInf-> pResponse-> SetMethod (Method); if (method! = METHOD_GET & method! = METHOD_HEAD) {// currently only two HTTP methods are supported: pSockInf-> pResponse-> SetServerCode (SC _BADMETHOD); // HTTP 405 CHTTPContent * pContent = new CHTTPContent; pContent-> OpenText (g_HTTP_Bad_Method, strlen (g_HTTP_Bad_Method); pSockInf-> pResponse-> AttachContent (pContent); goto exit ;} // obtain strUrlObject = pSockInf-> pRequest-> GetUrlObject (); if (strUrlObject. size () <= 0) {// The URL Object is empty, indicating a problem with the client request. pSockInf-> pResponse-> SetServerCode (SC _BADREQUEST); // Request Header Format error HTTP 400 CHTTPContent * pContent = new CHTTPContent; pContent-> OpenText (g_HTTP_Bad_Request, strlen (g_HTTP_Bad_Request )); pSockInf-> pResponse-> AttachContent (pContent); goto exit;} // map to the server file name. mapServerFile (strUrlObject, strServerFilePath); // if the last character of the URL is '/', the list of requested files; otherwise, a specific file is requested. if (strUrlObject. back () = l'/') {// browse the directory to create the Content Object of the directory list and associate it with the Response object CHTTPContent * pContent = new CHTTPContent; if (m_bNavDir) {if (pContent-> OpenDir (strUrlObject, strServerFilePath) {pSockInf-> pResponse-> SetServerCode (SC _ OK ); // HTTP 200} else {// the list of objects in the directory cannot be listed. pContent-> OpenText (g_HTTP_Server_Error, strlen (g_HTTP_Server_Error); pSockInf-> pResponse-> SetServerCode (SC _SERVERERROR ); // HTTP 500} else {// The browsing directory pContent-> OpenText (g_HTTP_Forbidden, strlen (g_HTTP_Forbidden); pSockInf-> pResponse-> SetServerCode (SC _FORBIDDEN ); // HTTP 403} pSockInf-> pResponse-> AttachContent (pContent);} else {// The client requests a file on the server // 1. whether the client has requested the resumable upload content // 2. create a file content object and associate it with the Response object _ int64 lFrom = 0 ;__ int64 lTo =-1; if (pSockInf-> pRequest-> GetRange (lFrom, lTo )) {pSockInf-> pResponse-> SetServerCode (SC _PARTIAL); // HTTP 206} else {pSockInf-> pResponse-> SetServerCode (SC _ OK ); // HTTP 200} CHTTPContent * pContent = new CHTTPContent; if (pContent-> OpenFile (WtoA (strServerFilePath. c_str ()). c_str (), lFrom, lTo) {// file opened successfully .} else {// the file does not exist or for any other reason, opening failed. pContent-> OpenHtml (g_HTTP_Content_NotFound, strlen (g_HTTP_Content_NotFound); pSockInf-> pResponse-> SetServerCode (SC _NOTFOUND ); // HTTP 404} pSockInf-> pResponse-> AttachContent (pContent);} exit: ///////// prepare the Response Header pSockInf-> pResponse-> CookResponse (); // output the above parameters as a text that complies with the HTTP protocol. // write logs. LOGGER_CINFO (theLogger, _ T ("connection [% s: % d] request resource [% s], response [HTTP % d]. \ r \ n "), AtoW (pSockInf-> pRequest-> GetIP (). c_str ()). c_str (), pSockInf-> pRequest-> GetPort (), strUrlObject. c_str (), pSockInf-> pResponse-> GetServerCode (); return ;}
 


5. Instructions for use

This is a very lightweight program that does not need to be installed. There is only one EXE file. After running it, you can set the location and service port as the root directory of the HTTP server. if the check box "allow browsing directories" is selected, allow the client browser to list all files in a directory on the server. For example, enter "http: // xxxxx/CAR image/", you will see a list of all files in the" car image "subdirectory under the root directory of the server. if this option is not selected, the message "403 Forbidden" is displayed.

Shows the program running effect:

The following figure shows the effect of using Firefox to browse directories:

========================================================== ==================================
Update log
Note: The code structure before V1.51 is poor, messy, and the interface is also very simple. It is only used as a convenient file sharing tool within the company and has not been released.

V1.51 Beta
1. enable the new interface.
2. Rewrite the kernel and start to display the CHTTPContent object.
3. enable the new log system.

V1.52 Beta

The server now supports downloading large files larger than 2 GB, and internally uses 64-bit long integers (previously 32-bit integers, only 2 GB files are supported) to record the file length.

V1.52 Beta Build 15279
When browsing directories, system files and hidden files are no longer listed, and all subdirectories appear in front.

V1.52 Beta Build 152710
New: The current bandwidth is displayed in the status bar (refreshed every 2 seconds ).
New: displays the total number of connections in the status bar (real-time ).
Fixed: When browsing the directory, files larger than 2 GB can be correctly displayed.
Modify: Now, only the first 100 rows of logs are removed (the first 200 rows are removed ).
New: when a connection is closed, the log shows the time used by the server to process the connection.
New: You can now set the maximum number of connections to the server.
Modification: the kernel has been modified to make the program logic clearer.

V1.52 Beta Build 152711
Correction: an internal synchronization error is corrected, and the bandwidth calculation result is more accurate now.

V1.52 Beta Build 152712
Correction: when the data sent by a connection exceeds 2 GB, it can be correctly displayed in the log.

V1.52 Beta Build 152713
Fixed: fixed an error in downstream bandwidth statistics.

V1.52 Beta Build 152714
Added: Now you can set session timeout.
New: If a connection does not send or receive any data within the specified time, it is determined to be a dead connection and removed. This time can be set on the setting page.
Modify: When browsing the directory, if a file exceeds 1 GB, it is displayed as "xxx gb" instead of the original "xxxx mb ".
Modify: Some page prompt text is slightly modified.

V1.52 Beta Build 152715
Modify: re-draw the toolbar icon.
New: You can now set the maximum number of connections per customer (based on the IP address.
New: Now you can set the maximum bandwidth for each connection. Note: To keep the connection active, the minimum bandwidth for each connection will not be less than 250B/s.
Modify: instead of creating a separate thread for the listening socket, it uses AcceptEx to call it to save server system resources and improve efficiency.
New: when the connection is closed, the average bandwidth used by the connection is displayed in the log.
Fixed: when a request header is divided into multiple recipients, the connection will be closed.
New: Supports file logs and can be disabled/enabled on the settings page. the log file and the EXE file are in the same folder. The file name is HTTPServerLOG (year, month, and day ). TXT. the maximum size of each log file is 5 MB.
New: allows you to set the default file name when browsing a directory is disabled (multiple file names are separated by commas (,) and can contain a maximum of 260 characters ).
Modify: Now the kernel uses three timer queues corresponding to three applications to improve performance.

Note: New features will not be added in V1.5X, but will continue testing to identify and fix bugs.


V1.52 Build 152716
Fixed: when the server is stopped, if there is still a connection, the timer deletion error is not prompted.

V1.52 Build 152717
Modify: when the connection ends, the average speed in the log is displayed as "xxx mb/s ".

V1.52 Build 152718
Modify: adjusted the format of some log text to make it more organized.
Open source code.

Related Article

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.