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 <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

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

}

发表评论