Cgi. h
Copy codeThe Code is as follows:
# Ifndef CGI_H
# Define CGI_H
# Include <stdio. h>
# Include <string. h>
# Include <stdlib. h>
Typedef struct Node {
Char * name;
Char * value;
Struct Node * next;
} Node;
Typedef struct Index {
Node * head;
Char * buffer;
} Index;
Index * get_input ();
Void free_input (Index *);
Node * analyze (char *);
Node * analy_a (char *);
Node * analy_m (char *, char *);
Char * get_value (Node *, char *);
Char fun1 (char );
# Endif
Get_input.c
Copy codeThe Code is as follows:
# Include "cgi. h"
Index * get_input (){
// Obtain the form sending Method
Char * get_method = getenv ("REQUEST_METHOD ");
Index * input = (Index *) malloc (sizeof (Index ));
Node * head;
Char * buffer;
If (strcmp (get_method, "GET") = 0 ){
Char * get_str = getenv ("QUERY_STRING ");
If (get_str = NULL | * get_str = 0 ){
Return NULL;
}
// Get the content through the Environment Variable
Buffer = (char *) malloc (strlen (get_str) + 1 );
Strcpy (buffer, get_str );
// Parse the content to exist in the form of a linked list
Head = analy_a (buffer );
} Else if (strcmp (get_method, "POST") = 0 ){
Int get_len = atoi (getenv ("CONTENT_LENGTH "));
If (get_len = 0 ){
Return NULL;
}
// Post method, reads content through standard input
Buffer = (char *) malloc (get_len + 1 );
Memset (buffer, 0, get_len + 1 );
Int n = fread (buffer, 1, get_len, stdin );
If (n! = Get_len ){
Fprintf (stderr, "Read error! ");
}
Head = analyze (buffer );
}
// Linked list Header
Input-> head = head;
// Received string
Input-> buffer = buffer;
Return input;
}
Analyze. c
Copy codeThe Code is as follows:
# Include "cgi. h"
// Parse the content obtained by the post Method
Node * analyze (char * buffer)
{
// Obtain the content format
Char * c_type = getenv ("CONTENT_TYPE ");
Char * bound;
Fprintf (stderr, "debug: c_type is % s \ n", c_type );
If (strcmp ("application/x-www-form-urlencoded", c_type) = 0 ){
// This format indicates that the retrieved content is in the "name = value" Format
Return analy_a (buffer );
} Else if (strcmp ("text/plain", c_type) = 0 ){
// This encoding format is not discussed for the moment
} Else {
// The encoding format is multipart/form-data. It is applicable to large-volume data transmission.
// Obtain the separator after the equal sign
Bound = index (c_type, '=') + 1;
Fprintf (stderr, "debug: bound is % s \ n", bound );
Return analy_m (buffer, bound );
}
}
Analy_a.c
Copy codeThe Code is as follows:
# Include "cgi. h"
// The encoding format is 'application/x-www-form-urlencoded '.
Node * analy_a (char * buffer)
{
// Create the first node
Node * head = (Node *) malloc (sizeof (Node ));
Node * temp = head;
Temp-> name = buffer;
Char * B _temp = buffer;
// Separate strings by moving or changing some characters
While (* buffer! = 0 ){
If (* buffer = '){
// '=', Indicating that the name has ended and the value will start
* B _temp = 0;
Temp-> value = B _temp + 1;
} Else if (* buffer = '+ '){
// '+' Indicates space
* B _temp = '';
} Else if (* buffer = '% '){
// '%' Is followed by two special characters in hexadecimal notation
* B _temp = fun1 (* (buffer + 1) * 16 + fun1 (* (buffer + 2 ));
Buffer + = 2;
}
Else if (* buffer = '&'){
// '&' Indicates that the value has ended and the name is about to begin.
* B _temp = 0;
// Re-apply for memory and store the new content address
Temp-> next = (Node *) malloc (sizeof (Node ));
Temp = temp-> next;
Temp-> name = B _temp + 1;
} Else {
* B _temp = * buffer;
}
Buffer ++;
B _temp ++;
}
// Last Terminator
* B _temp = 0;
Return head;
}
Analy_m.c
Copy codeThe Code is as follows:
# Include "cgi. h"
// The encoding format is 'multipart/form-data '.
Node * analy_m (char * buffer, char * bound)
{
Char * start;
Char * end;
// The first node
Node * head = (Node *) malloc (sizeof (Node ));
Node * temp = head;
Fprintf (stderr, "debug: buffer is % s \ n", buffer );
// Start parsing the content. The name is between two double quotation marks (For details, refer to the encoding format)
Temp-> name = index (buffer, '"') + 1;
End = index (temp-> name ,'"');
* End = 0;
Fprintf (stderr, "debug: temp-> name is % s \ n", temp-> name );
// Two "\ r \ n" are separated between them"
Temp-> value = end + 5;
Buffer = strstr (temp-> value, bound );
// To the next delimiter, which is separated by two "\ r \ n"
* (Buffer-4) = 0;
Fprintf (stderr, "debug: temp-> valu is % s \ n", temp-> value );
While (start = strstr (buffer, "name = "))! = NULL ){
// Obtain the name and value addresses cyclically until no name exists.
Temp-> next = (Node *) malloc (sizeof (Node ));
Temp = temp-> next;
Temp-> name = index (start, '"') + 1;
End = index (temp-> name ,'"');
* End = 0;
Fprintf (stderr, "debug: temp-> name is % s \ n", temp-> name );
Temp-> value = end + 5;
Buffer = strstr (temp-> value, bound );
* (Buffer-4) = 0;
Fprintf (stderr, "debug: temp-> valu is % s \ n", temp-> value );
}
Return head;
}
Fun1.c
Copy codeThe Code is as follows:
// Convert the hexadecimal character to the decimal number
Char fun1 (char ch)
{
Char buffer;
If (ch <'A '){
Buffer = ch-48;
} Else if (ch <'A '){
Buffer = ch-55;
} Else {
Buffer = ch-87;
}
Return buffer;
}
Get_value.c
Copy codeThe Code is as follows:
# Include "cgi. h"
// Obtain the corresponding value based on the name
Char * get_value (Node * head, char * name)
{
Node * p;
While (head! = NULL ){
If (strcmp (head-> name, name) = 0 ){
Return head-> value;
}
P = head-> next;
Head = p;
}
Return NULL;
}
Free_input.c
Copy codeThe Code is as follows:
# Include "cgi. h"
// Release the dynamically obtained memory
Void free_input (Index * index)
{
Node * temp = index-> head;
Node * p;
While (temp! = NULL ){
P = temp-> next;
Free (temp );
Temp = p;
}
Free (index-> buffer );
Free (index );
}