Internet-related development (VC)

Source: Internet
Author: User
Tags file url gopher

1.1 How to Write CGI programs


CGI (Common Gateway Interface) is a standard Interface for WEB servers to provide information services. Through this Interface, WEB servers can execute programs, and return the information output by the program to the browser. Because data on the WEB is static, CGI programs can dynamically process viewer requests, such as saving user input information and returning relevant information based on user information. After the client sends a CGI request to the WEB server, the WEB server determines the data transmission method to the CGI program based on the CGI program type, generally, data is transmitted with CGI programs through standard input/output streams and environment variables.


CGI Input and Output principles

CGI Input/Output Method: CGI program uses standard input (STDIN) and standard output (STDOUT) for input and output. STDIN and STDOUT are two pre-defined file pointers. You can use the file read/write function to manipulate it.

In addition, the CGI program obtains input through environment variables, except that the environment variables provide some common information, this usually does not include the information you enter on the WEB page (except when using the GET method described below, you can check the environment variable QUERY_STRING to obtain the input data ), STDIN is usually used to transmit user input information. In general CGI program development, we need to care about the following environment variables:

Some are environment variables related to WEB servers:

  • SERVER_NAME WEB server name
  • SERVER_PORT WEB server listening address
  • SERVER_PROTOCOL indicates the protocol name and version used to send the request.
  • SERVER_SOFTWARE WEB server name and version

Some of them are related to running CGI:

  • REQUEST_METHOD data transfer (Information Transfer) Method
  • CONTENT_LENGTH Data Length
  • Data Transmitted by QUERY_STRING
  • REMOTE_ADDR Client IP Address
  • REMOTE_HOST client host name

Some of them are related to the customer:

  • HTTP_USER_AGENT client browser name
  • List of MIME types supported by the HTTP_ACCEPT Client
  • The URL of the previous document in the HTTP_REFERER Client

 

The POST/GET Method Used for input: usually two methods are used for sending data to CGI on the web page: GET/POST. The GET method attaches the data to the URL and sends the data, for example: /cgi/a_cgi_test.exe? Your_data, CGI program checks the environment variable QUERY_STRING to obtain the input data. The POST method sends the data to the STDIN input stream of the CGI program. Each variable in FORM will be sent to the WEB server in the FORM of name = value. Multiple Data are separated by &, for example, name = value & name2 = value2. The name (name, name2) is the INPUT, SELECT, TEXTAREA, and other Tag names defined in Form. The value is the value entered or selected by the user.

With the above knowledge, we can immediately write a simple CGI program. The Code is as follows:

Void main (void) {// This program prints the user input data out of fprintf (stdout, "content-type: text/plain/n "); // output a CGI title. The meaning of this line of code will be explained later in char * pszMethod; pszMethod = getenv ("REQUEST_METHOD"); if (strncmp (pszMethod, "GET ") = 0) {// GET method // read the environment variable to obtain the data fprintf (stdout, "input data is:/n % s ", getenv ("QUERY_STRING");} else {// POST method // read STDIN to get data int iLength = atoi (getenv ("CONTENT_LENGTH"); fprintf (stdout, "input data is:/n"); for (int I = 0; I <iLength; I ++) {char cGet = fgetchar (stdin); fputchar (stdout, cGet );}}}

 

As mentioned above, a CGI title must be output in the CGI program. There are three types of titles:

  • Location: title that specifies the URL to output another document, such as fprintf (stdout, "Location: http://www.vchelp.net//n/n ");
  • Content-Type: title, indicating the MIME Type of the sent data, such as fprintf (stdout, "Content-Type: text/html/n ");
  • Status: title, indicating the HTTP Status code, such as fprintf (stdout, "Status: 200/n ");

Note that each title must be followed by a line break and an empty line.

 

MIME types are expressed in the form of types/child types. Below are some common types/child types:

  • Text/plain common Text type
  • Text/html Text type
  • Audio/basic 8-bit Audio file format, Suffix:. au
  • Video/mpeg file format
  • Video/quicktime QuickTime file format
  • Image/gif Image File
  • Image/jpeg Image File
  • Image/x-xbitmap X bitmap graphic file, Suffix:. xbm

 

With the above knowledge, we can write some CGI programs. First, we need to analyze the input data. The method is: every time a character = is found, it indicates the end of a Form variable name; each time the character & is found, it indicates the end of a Form variable value. Note that the value of the last variable of the input data does not end. In this way, we can break down the input data into a group of indicators.

However, it will be found that the CGI Input is not rule-based. For example, sometimes a string similar to the following format will appear: filename = hello & cmd = world + I % 27, this is because the browser encodes some special characters to be uploaded. Therefore, after breaking up the data, the decoding rule is: +: Convert + to a space character; % xx: A special character (%) represented by its hexadecimal ASCII value ). Converts a Value xx to an ASCII character. Perform this conversion for the Form variable name and variable value. The following is a CGI program that analyzes Form data and sends the result back to the Web server.

  #include 
       #include 
       #include 
       int htoi(char *);  main()  {   int i,n;  char c;  printf (″Contenttype: text/plain/n/n″);  n=0;  if (getenv(″CONTENT-LENGTH″))   n=atoi(getenv(″CONTENT-LENGTH″));  for (i=0; i<n;i++){   int is-eq=0;  c=getchar();  switch (c){   case ′&′:    c=′/n′;    break;   case ′+′:    c=′ ′;    break;   case ′%′:{    char s[3];    s[0]=getchar();    s[1]=getchar();    s[2]=0;    c=htoi(s);    i+=2;   }   break;  case ′=′:   c=′:′;   is-eq=1;   break;  };  putchar(c);  if (is-eq) putchar(′ ′);  }  putchar (′/n′);  fflush(stdout);  }  /* convert hex string to int */  int htoi(char *s)  {   char *digits=″0123456789ABCDEF″;  if (islower (s[0])) s[0]=toupper(s[0]);  if (islower (s[1])) s[1]=toupper(s[1]);  return 16 * (strchr(digits, s[0]) -strchr (digits,′0′))  +(strchr(digits,s[1])-strchr(digits,′0′));  }

The above program first outputs a MIME header information to the Web server, checks the number of characters in the input, and cyclically checks each character. When the "&" character is found, it means that a name/value pair ends, and the program outputs a blank line. When the character is found to be +, it is converted to a space; when the character is %, it indicates the start of a two-character hexadecimal value. Call the htoi () function to convert the subsequent two characters into the corresponding ASCII characters; when the character is found to be =, it means that the end of the name part of a name/value pair, and converts it to a character :. Finally, output the converted characters to the Web server.

 

To develop a CGI program, follow these steps:
1. Determine whether the data input method is GET or POST.
2. Read data, separate each received form variable according to the separator and decode the data at the same time.
3. process data.
4. Output CGI title and HTML data.
5. Exit.

Using C language to develop CGI requires you to analyze the input data, but string processing is not the strength of C language, so I would like to recommend you a set of development kits that I think are good, CGIC, (available for free at http://www.boutell.com/boutell ). I made a few changes to the files provided in the Development Kit and compiled them into LIB using VC6. After downloading the SDK, you can see the instructions provided by the SDK. The instructions are detailed not only in the sample code but also in each function.

Return

All rights reserved by Wen Yi Yang http://www.vchelp.net/

1.2 A more friendly CGI Development System WinCGI


CGI development is too complex in some ways, mainly because it is used to obtain environment variables and decompose/decode data. In Windows, you can use WinCGI for development. The advantage of WinCGI is that it reduces the burden on developers to break down/decode data and provides a unified input/output method.

During WinCGI program execution, the first parameter will be a file name, such as yourCGI.exe para.txt, which records all environment variable information and parameter information, the structure of the file is the same as that of the INI file. Therefore, all parameters can be retrieved using the standard function GetPrivateProfileString provided by Windows. In addition, all the data in the file has been decoded and can be directly used.

The parameter file contains the following sections)

  • [CGI]
  • [Accept]
  • [System]
  • [Extra Headers]
  • [Form Literal]
  • [Form External]
  • [Form File]
  • [Form Huge]

The file format is as follows:

[CGI]CGI Version=CGI/1.2 (Win)Query String=XXXXXX[Section]key=valuekey=value...

The following data is particularly useful to us in this parameter file:

 

The keywords in the [CGI] area record the system parameters, the browser of the other party, the IP address of the other party, and other information. Some common keywords are listed below:

  • Request Method: data transmission Method. If the transmission Method is GET, you can also check the value of the Query String keyword to obtain the transmitted data, otherwise, you must read the [Form Literal] area to obtain the input.
  • Request Protocol: the Protocol and version used, such as HTTP/1.0.
  • From: The email address of the browser user.
  • User Agent: browser name, such as Netscape and Internet Explorer.
  • Content Type: the type of the uploaded data. The format is Type/subtype.
  • Content Length: the Length of the uploaded data.
  • Content File: when the data is too long, the data is saved by writing the File specified by this keyword.
  • Server Name: The network address of the WEB Server.
  • Server Software: the Software name and version of the WEB Server.
  • Server Port: the Port that the WEB Server listens.
  • CGI Version: the Version of the CGI system on the server.
  • Remote Address: the IP Address of the client.

 

The keywords in the [CGI] area record the system parameters, the browser of the other party, the IP address of the other party, and other information. If the transfer method is GET, you need to check the value of the Query String keyword.

The keywords in the [ACCEPT] area record the data types acceptable to the client's browser. Therefore, we can see that the information in [CGI] and [ACCEPT] is no different from the value of the environment variable in common CGI.

[SYSTEM] is a very important area. The GMT Offset keyword indicates the time zone of the client. The Output File keyword is the name of the Output File, in WinCGI, you do not need to write data directly to the output stream. Instead, you need to use a temporary file to save the data, after the CGI program exits, the WinCGI system returns the content of the file to the customer and deletes the file (and also deletes all temporary files in the call process ).

The following [Form Literal] area contains decoded data. The original format is: key = value &... the decoded data is stored in this zone, but in some exceptional cases, the [Form External] and [Form Huge] zones are used. In the [Form External] area, the data format is as follows: key = pathname length. when the length of the uploaded string is greater than 254, this area is used, pathname indicates the file containing decoded characters. The length is the string length. When the length of the uploaded data is greater than 64 KB, the data is stored in an independent File. The File name is specified by the Content File keyword in the [System] area. In the [Form Huge] area, the data format is as follows: key = offset length. offset indicates the starting position of the data in the file, and length indicates the Data length.

The following example shows how to set the input value to a_cgi_sample.exe? Name = your_name & e-mail = your@mail.com & memo = length_gt_254
The format of the data contained in the file is as follows:

[Form Literal] name = your_nameemail = your@mail.com [Form External]; assume that the memo field length is 500 memo = a_temp_file 500

 

Finally, the pseudocode outline of a WinCGI program is given:

Void main (int argc, char ** argv) {if (argc = 1) error raise; // the configuration file char szw.file [] = argv [1] cannot be obtained; read [Form Literal] section for input datachar szOutFile [] = Read "Output File" key from [System] section; fopen (szOutFile) {write result to outFileclose outFile} return; // exit}

 

In general, the WinCGI program is slightly different from the general CGI program, but it is slightly different in the input and output methods.

Return

All rights reserved by Wen Yi Yang http://www.vchelp.net/

1.3 Use ISAPI to develop CGI programs


ISAPI (Internet Server API) was initially a CGI application development interface provided by Microsoft for the IIS Server. Its main purpose is to provide a good development interface for CGI development, if ISAPI is not responsible, it can be considered as a development mode similar to WinCGI, except that ISAPI obtains parameters transmitted by user forms through ing macros. This is similar to the Message ing macro of MFC.

Of course, the launch of ISAPI also has many other features:

  • ISAPI is implemented through DLL dynamic connection library. Therefore, it is faster to load normal EXE programs, and the system will not immediately remove the DLL space in the memory after use, therefore, it will get a faster speed when used again.
  • The ISAPI runs in the thread mode inside the caller, so it requires less runtime space than the CGI process.
  • Multiple processing functions can be centralized in the same DLL, and the macro is mapped to indicate the types of requests processed by different functions.
  • Because it is integrated with IIS, you can use ISAPI to develop ISAPI filters. You can use a filter to perform functions such as user permission detection, data encryption, compression, and logs. The functions of the IIS server can also be enhanced using the ISAPI filter.

So far, many non-M $ WEB servers have added support for isapis.

 

Multiple processing functions can be concentrated in the same DLL. Therefore, there is a difference between an ISAPI request and a common CGI request. In the URL, you must enter the following form: http ://... /cgi-bin/test. dll? Function_name & name = xxx & email = yyy, function_name indicates the function name. to be correct, you must map it to a handler in the DLL. A default function is used to process unmapped functions.

VC4.2 and later versions provide a Wizard for creating an ISAPI program. When creating a project, select ISAPI Extension Wizard and select create Server Extension and enter relevant information in the subsequent dialog box.

A simplest ISAPI program contains at least a new class derived from the CHttpServer class, and performs basic ing in the class, reloading BOOL GetExtensionVersion (HSE_VERSION_INFO * pVer) function and a member function in the form of void Default (CHttpServerContext * pCtxt. Fortunately, the Wizard program has done everything for us and created the most basic code.

The Default function is used to process the code in the Default function without parameters. First, we should write the relevant Code as follows:

Void CTestisaExtension: Default (CHttpServerContext * pCtxt) {// Print the <HTML> <BODY> tags. startContent (pCtxt); // Print the title. writeTitle (pCtxt); * pCtxt <_ T ("<p> demo </p> "); * pCtxt <_ T ("<p> currently the Default member function </p>"); // Print </HTML> </BODY> tags. endContent (pCtxt );}

Then, use the following method to call: http: //.../cgi-bin/test. dll? Default or http: //.../cgi-bin/test. dll ?. You will see the output HTML page.

 

 

<FORM ACTION="test.dll?Add" METHOD=POST><INPUT NAME="name"><INPUT NAME="id"><INPUT TYPE=SUBMIT></FORM>

The above form requires the user to enter the user name and ID, so the form of transmitted data should be like: http: //.../test. dll? Add & name = xxx & id = yyy, the decomposed data is stored in the specified variable. Usage:

ON_PARSE_COMMAND(Add, CTestExtension, ITS_PSTR ITS_I4)ON_PARSE_COMMAND_PARAMS("name id")

In the ON_PARSE_COMMAND macro, you must specify the function name, class name, and parameter type list. In the ON_PARSE_COMMAND_PARAMS macro, you must specify the variable name list in the form based on the list of parameters listed in the previous macro. The last step is to define a name and request URL? After the command name is the same as the member function, the parameter settings must be consistent with the parameter list definition in the ON_PARSE_COMMAND macro, in this example:
Void CTestExtension: Add (CHttpServerContext * pCtxt, LPTSTR pszName, int iID ). The following types can be used in the parameter type list for description:

  • ITS_EMPTY no data
  • ITS_PSTR string LPCSTR
  • ITS_I2 short
  • ITS_I4 long
  • ITS_R4 float
  • ITS_R8 double

 

The following shows a more complex form, which is defined as follows:

<FORM ACTION="test.dll?Delete" METHOD=POST><INPUT NAME="name"><INPUT NAME="month"><SELECT NAME="mode"><OPTION VALUE=1>All<OPTION VALUE=2>Before<OPTION VALUE=3>After<INPUT TYPE=HIDDEN NAME=pwd VALUE=xxx><INPUT TYPE=SUBMIT></FORM>

The ing and processing functions are defined as follows:

ON_PARSE_COMMAND(Add, CTestExtension, ITS_PSTR ITS_I4 ITS_I4 ITS_PSTR)ON_PARSE_COMMAND_PARAMS("name month mode pwd")void CTestExtension::Add(CHttpServerContext* pCtxt,LPTSTR pszName,int iMonth,int iMode,LPTSTR pszPwd)。

 

ISAPI program output: In all command processing functions, the first parameter is the CHttpServerContext * pointer, and all our output must be carried out through it. The <operator is defined in the CHttpServerContext class, with this operator, we can easily output strings, numbers, and binary data. The output method is as follows:

*pCtxt<<"this is a string";*pCtxt<<'c';*pCtxt<<10;

It can be seen that the output is very simple. A complete output process should be in the following format:

StartContent (pCtxt); // start to output WriteTitle (pCtxt); // output header information, equivalent to output <TITLE> * pCtxt <"your string"; EndContent (pCtxt ); // end output

 

The ISAPI extension class we use is derived from CHttpServer. You can call CHttpServer: AddHeader to specify the type of returned data. For example, the following code demonstrates the output of plain text:

void CTestisaExtension::Default(CHttpServerContext* pCtxt){AddHeader(pCtxt, "Content-type = text/plain/r/n");(*pCtxt) << "Hello world!/r/n"; }

We can reload some functions to enhance control. The following functions can be reloaded:

  • Virtual LPCTSTR CHttpServer: GetTitle () const; <TITLE> partial information is returned.
  • Virtual BOOL CHttpServer: OnParseError (CHttpServerContext * pCtxt, int nCause); error handling
  • Virtual void CHttpServer: StartContent (CHttpServerContext * pCtxt) const; Output <HTML> <BODY> partial information
  • Virtual void CHttpServer: EndContent (CHttpServerContext * pCtxt) const; Output </BODY> </HTML> partial information
  • Virtual void CHttpServer: WriteTitle (CHttpServerContext * pCtxt) const; Output <TITLE> </TITLE> partial information

 

In addition, we can use the CHttpServerContext pointer in the command processing function to obtain the relevant environment variables in CGI. In CHttpServerContext, a member variable m_pECB is the following structure pointer.

Typedef struct _ EXTENSION_CONTROL_BLOCK {DWORD cbSize; // IN this structure length DWORD dwVersion // IN version HCONN ConnID; // IN connection with the context DWORD dwHttpStatusCode; // OUT status code CHAR lpszLogData [encoding]; // out lpstr lpszMethod; // IN environment variable REQUEST_METHOD LPSTR lpszQueryString; // IN QUERY_STRING LPSTR lpszPathInfo; // IN PATH_INFO LPSTR encoding; // IN PATH_TRANSLATED DWORD cbTotalBytes; // IN CONTENT_LENGTH DWORD cbAvailable; // in lpbyte lpbData; // in lpstr lpszContentType; // IN CONTENT_TYPE... other information is ignored here} EXTENSION_CONTROL_BLOCK, * LPEXTENSION_CONTROL_BLOCK;

 

Return

All rights reserved by Wen Yi Yang http://www.vchelp.net/

1.4 Use WinInet to develop Internet programs


The WinInet Development Kit provided by M $ is part of ActiveX technology. Later, MS packages WinInet APIs and provides corresponding MFC classes. The function of the WinNet development kit is to provide support for the http ftp Gopher protocol, so that developers can avoid writing code related to the underlying protocol when developing Internet programs. In addition, many features of WinInet are related to IE. For example, you can use IE to set and use data in IE cache. This section focuses on the use of HTTP.

CInternetSession in WinInet is a session management class. Generally, if you want to use the WinInet function, you need to create a session and then use the data access function based on the session. The CInternetSession constructor receives four parameters.

CInternetSession (LPCTSTR pstrAgent = NULL, // Application name, you can define DWORD dwContext = 1, // context tag, if this value is sent to the callback function DWORD dwAccessType = INTERNET_OPEN_TYPE_PRECONFIG, // LPCTSTR pstrProxyName = NULL, // CERN proxy server address, which is generally set to NULLLPCTSTR pstrProxyBypass = NULL, // proxy server address DWORD dwFlags = 0); // tag, generally set to 0

 

DwAccessType can be:

  • INTERNET_OPEN_TYPE_PRECONFIG use connection settings in IE
  • INTERNET_OPEN_TYPE_DIRECT connects directly to the server
  • INTERNET_OPEN_TYPE_PROXY connection through Proxy Server

 

Specify the proxy server address when dwAccessType is INTERNET_OPEN_TYPE_PROXY.

DwFlags can be:

  • INTERNET_FLAG_DONT_CACHE does not store the obtained content in the cache.
  • INTERNET_FLAG_OFFLINE offline,
  •  

 

After a session is created, you can use CInternetSession: OpenURL to open a URL and read data. The function prototype is:

CStdioFile * OpenURL (maid, // File url dword dwContext = 1, // context IDDWORD dwFlags = INTERNET_FLAG_TRANSFER_ASCII, // mark maid = NULL, // DWORD dwHeadersLength = 0); // The length of the Data header sent to the server

DwFlags can be:

  • INTERNET_FLAG_RELOAD force re-reading data
  • INTERNET_FLAG_DONT_CACHE is not saved to the cache
  • INTERNET_FLAG_TRANSFER_ASCII uses text data
  • INTERNET_FLAG_TRANSFER_BINARY uses binary data

 

The return value of OpenURL is the CStdioFile pointer. The function will return different file class pointers based on the protocol used, but these classes are all derived classes of CStdioFile.

URL type Returns
File :// CStdioFile *
Http :// CHttpFile *
Gopher :// CGopherFile *
Ftp :// CInternetFile *

Then, you can use CStdioFile: ReadString to read the file content.

 

The example in this article is to use WinInet to read online files through HTTP protocol.

The code to complete this function is very simple. Of course, there are no errors detected in the code.

Void CSp_14Dlg: GetURL (void) {UpdateData (); CInternetSession sess; // create a session CHttpFile * pF = (CHttpFile *) sess. openURL (m_szURL); // open the file CString szData, szAllData; while (pF-> ReadString (szData) {// read the file szAllData + = "/r/n "; szAllData + = szData;} pF-> Close (); sess. close (); m_szHTML = szAllData; UpdateData (FALSE );}

Download DEMO code

 

Here I only talk about the simplest application. If you need stronger control or FORM sending, You need to generate the CHttpConnection object and CHttpFile object.

 

 

 

Return

All rights reserved by Wen Yi Yang http://www.vchelp.net/

 

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.