C语言解析http请求表单内容

[1].[文件] cgi.h ~ 405B    下载(105) 跳至 [1] [2] [3] [4] [5] [6] [7] [8]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef CGI_H
#define CGI_H
 
#include
#include
#include
 
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

[2].[文件] get_input.c ~ 965B    下载(85) 跳至 [1] [2] [3] [4] [5] [6] [7] [8]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include "cgi.h"
 
Index *get_input() {
     //获得表单发送方法
     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方法,通过环境变量得到内容
         buffer = ( char *) malloc ( strlen (get_str) + 1);
         strcpy (buffer, get_str);
         //对内容进行解析,以链表的形式存在
         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方法,通过标准输入读取内容
         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);
     }
     //链表头
     input -> head = head;
     //接受到的字符串
     input -> buffer = buffer;
     return input;
}

[3].[文件] analyze.c ~ 610B    下载(81) 跳至 [1] [2] [3] [4] [5] [6] [7] [8]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "cgi.h"
//post方法获取的内容进行解析
Node *analyze( char *buffer)
{
     //获取内容格式
     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) {
         //该格式表明获取内容为"name=value"形式
         return analy_a(buffer);    
     } else if ( strcmp ( "text/plain" , c_type) == 0) {
         //此种编码格式暂不讨论
     } else {
         //编码格式为multipart/form-data,适用大流量数据传送
         //获取等号后面的分隔符
         bound = index(c_type, '=' ) + 1;
         fprintf (stderr, "debug:bound is %s\n" ,bound);
         return analy_m(buffer, bound);
     }
}

[4].[文件] analy_a.c ~ 961B    下载(78) 跳至 [1] [2] [3] [4] [5] [6] [7] [8]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include "cgi.h"
//编码格式为'application/x-www-form-urlencoded'的内容
Node *analy_a( char *buffer)
{
     //创建第一个节点
     Node *head = (Node *) malloc ( sizeof (Node));
     Node *temp = head;
     temp -> name = buffer;
     char *b_temp = buffer;
     //通过移动、改变部分字符来分离字符串
     while (*buffer != 0) {
         if (*buffer == '=' ) {
             //'=',则表示name已经结束,value将开始
             *b_temp = 0;
             temp -> value = b_temp + 1; 
         } else if (*buffer == '+' ) {
             //'+'代表空格
             *b_temp = ' ' ;
         } else if (*buffer == '%' ) {
             //'%'则紧跟两位十六进制表示的特殊字符
             *b_temp = fun1(*(buffer + 1)) * 16 + fun1(*(buffer + 2));
             buffer += 2;
         }
         else if (*buffer == '&' ) {
             //'&'表示value已经结束,name即将开始
             *b_temp = 0;
             //重新申请内存,存储新内容地址
             temp -> next = (Node *) malloc ( sizeof (Node));
             temp = temp -> next;
             temp -> name = b_temp + 1;  
         } else {
             *b_temp = *buffer;
         }
         buffer++;
         b_temp++;          
     }
     //最后一个结束符
     *b_temp = 0;
     return head;
}

[5].[文件] analy_m.c ~ 1KB    下载(80) 跳至 [1] [2] [3] [4] [5] [6] [7] [8]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include "cgi.h"
//编码格式为'multipart/form-data'的内容
Node *analy_m( char *buffer, char *bound)
{
     char *start;
     char *end;
     //第一个节点
     Node *head = (Node*) malloc ( sizeof (Node));
     Node *temp = head;
     fprintf (stderr, "debug:buffer is %s\n" , buffer);
     //开始解析内容,name在两个双引号之间(详见编码格式)
     temp -> name = index(buffer, '"' ) + 1;
     end = index(temp -> name, '"' );
     *end = 0;
     fprintf (stderr, "debug:temp->name is %s\n" , temp -> name);
     //中间间隔了两个"\r\n"
     temp -> value = end + 5;
     buffer = strstr (temp -> value, bound);
     //到下一个间隔符,上面间隔两个"\r\n"
     *(buffer - 4) = 0;
     fprintf (stderr, "debug:temp->valu is %s\n" , temp -> value);
     while ((start = strstr (buffer, "name=" )) != NULL) {
         //循环获取name与value地址,直到没有name为止
         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;
}

[6].[文件] fun1.c ~ 203B    下载(76) 跳至 [1] [2] [3] [4] [5] [6] [7] [8]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
//将十六进制字符转化为十进制数
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; 
}

[7].[文件] get_value.c ~ 241B    下载(77) 跳至 [1] [2] [3] [4] [5] [6] [7] [8]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "cgi.h"
//根据name获取相应的value
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;
}

[8].[文件] free_input.c ~ 222B    下载(79) 跳至 [1] [2] [3] [4] [5] [6] [7] [8]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "cgi.h"
//释放动态获取的内存
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);
}

你可能感兴趣的:(C++)