C Language http Request Parsing Form Content

Source: Internet
Author: User

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 );
}

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.