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