头文件:
1
/*
***********************
2 * HTTP Parser framework
3 * 2010-01-11
4 *********************** */
5
6 #ifndef __SIMPLE_HTTP_H__
7 #define __SIMPLE_HTTP_H__
8
9 #define GET_REQUEST_SIZE 1024
10
11 #define HEADER_SIZE 1024
12 #define CONTENT_SIZE 1024000
13
14 // response header
15 typedef struct {
16 char content_type[ 32 ];
17 char content_length[ 32 ];
18 } http_response;
19
20 // build a GET request
21 int httpGET( char * sndbuf,
22 int buflen,
23 const char * http_version,
24 const char * http_useragent,
25 const char * http_host,
26 const char * http_uri);
27
28 // read a response from a socket
29 // (no reconnection, so your socket must be healthy)
30 int httpResponse( int fd,
31 char * content,
32 int len,
33 http_response * response);
34
35 #endif
2 * HTTP Parser framework
3 * 2010-01-11
4 *********************** */
5
6 #ifndef __SIMPLE_HTTP_H__
7 #define __SIMPLE_HTTP_H__
8
9 #define GET_REQUEST_SIZE 1024
10
11 #define HEADER_SIZE 1024
12 #define CONTENT_SIZE 1024000
13
14 // response header
15 typedef struct {
16 char content_type[ 32 ];
17 char content_length[ 32 ];
18 } http_response;
19
20 // build a GET request
21 int httpGET( char * sndbuf,
22 int buflen,
23 const char * http_version,
24 const char * http_useragent,
25 const char * http_host,
26 const char * http_uri);
27
28 // read a response from a socket
29 // (no reconnection, so your socket must be healthy)
30 int httpResponse( int fd,
31 char * content,
32 int len,
33 http_response * response);
34
35 #endif
GET请求拼装格式:
1
const
char
*
HTTP_GET_FORMAT
=
2 " GET %s %s\r\n " \
3 " User-Agent: %s\r\n " \
4 " Host: %s\r\n " \
5 " \r\n " ;
2 " GET %s %s\r\n " \
3 " User-Agent: %s\r\n " \
4 " Host: %s\r\n " \
5 " \r\n " ;
拼装部分:
1
int
httpGET(
char
*
sndbuf,
2 int buflen,
3 const char * http_version,
4 const char * http_useragent,
5 const char * http_host,
6 const char * http_uri)
7 {
8 if (sndbuf == NULL || buflen <= 0 )
9 {
10 return - 1 ;
11 }
12
13 return snprintf(sndbuf, buflen, HTTP_GET_FORMAT, http_uri, http_version, http_useragent, http_host);
14 }
2 int buflen,
3 const char * http_version,
4 const char * http_useragent,
5 const char * http_host,
6 const char * http_uri)
7 {
8 if (sndbuf == NULL || buflen <= 0 )
9 {
10 return - 1 ;
11 }
12
13 return snprintf(sndbuf, buflen, HTTP_GET_FORMAT, http_uri, http_version, http_useragent, http_host);
14 }
Response解析 -- header 与 Content 切分部分
代码
1
int
httpResponse(
int
fd,
char
*
content,
int
len, http_response
*
response)
2 {
3 char header[HEADER_SIZE] = { 0 };
4
5 char c;
6 char line[ 1024 ];
7 int cindex = 0 ;
8
9 // analyze status
10 int status = 0 ;
11
12 char * contentptr = content;
13 char * headerptr = header;
14 char * content_head = NULL;
15
16 int readnum = 0 ;
17 int content_length = 0 ;
18 int content_rest_length = 0 ;
19
20 if (fd < 0 || content == NULL || len <= 0 )
21 {
22 return - 1 ;
23 }
24
25 if ((readnum = read(fd, header, HEADER_SIZE)) > 0 )
26 {
27 while ((c = * headerptr) && content_head == NULL)
28 {
29 switch (status)
30 {
31 case 0 : // nothing happend
32 if (c == ' \r ' )
33 {
34 status = 1 ;
35
36 httpParseLine(line, cindex, response); // a whole line
37
38 cindex = 0 ;
39 memset(line, 0 , sizeof (line));
40 }
41 else
42 {
43 line[cindex ++ ] = c;
44 }
45 headerptr ++ ;
46 break ;
47 case 1 : // a \r appeared
48 if (c == ' \n ' )
49 {
50 status = 2 ;
51 headerptr ++ ;
52 }
53 else
54 {
55 status = 0 ;
56 }
57 break ;
58 case 2 : // a \n followed a \r
59 if (c == ' \r ' )
60 {
61 status = 3 ;
62 headerptr ++ ;
63 }
64 else
65 {
66 status = 0 ;
67 }
68 break ;
69 case 3 : // a \r followed a \r\n pair
70 if (c == ' \n ' )
71 {
72 status = 4 ;
73 headerptr ++ ;
74 }
75 else
76 {
77 status = 0 ;
78 }
79 break ;
80 case 4 : // head tail
81 content_head = headerptr;
82 content_length = atoi(response -> content_length);
83 content_rest_length = content_length - (readnum - (headerptr - header));
84 contentptr = content;
85 strncpy(content, content_head, readnum - (headerptr - header));
86 contentptr += readnum - (headerptr - header);
87 while (content_rest_length > 0 )
88 {
89 readnum = read(fd, contentptr, content_rest_length);
90 contentptr += readnum;
91 content_rest_length -= readnum;
92 }
93 break ;
94 }
95 }
96 }
97
98 return 0 ;
99 }
2 {
3 char header[HEADER_SIZE] = { 0 };
4
5 char c;
6 char line[ 1024 ];
7 int cindex = 0 ;
8
9 // analyze status
10 int status = 0 ;
11
12 char * contentptr = content;
13 char * headerptr = header;
14 char * content_head = NULL;
15
16 int readnum = 0 ;
17 int content_length = 0 ;
18 int content_rest_length = 0 ;
19
20 if (fd < 0 || content == NULL || len <= 0 )
21 {
22 return - 1 ;
23 }
24
25 if ((readnum = read(fd, header, HEADER_SIZE)) > 0 )
26 {
27 while ((c = * headerptr) && content_head == NULL)
28 {
29 switch (status)
30 {
31 case 0 : // nothing happend
32 if (c == ' \r ' )
33 {
34 status = 1 ;
35
36 httpParseLine(line, cindex, response); // a whole line
37
38 cindex = 0 ;
39 memset(line, 0 , sizeof (line));
40 }
41 else
42 {
43 line[cindex ++ ] = c;
44 }
45 headerptr ++ ;
46 break ;
47 case 1 : // a \r appeared
48 if (c == ' \n ' )
49 {
50 status = 2 ;
51 headerptr ++ ;
52 }
53 else
54 {
55 status = 0 ;
56 }
57 break ;
58 case 2 : // a \n followed a \r
59 if (c == ' \r ' )
60 {
61 status = 3 ;
62 headerptr ++ ;
63 }
64 else
65 {
66 status = 0 ;
67 }
68 break ;
69 case 3 : // a \r followed a \r\n pair
70 if (c == ' \n ' )
71 {
72 status = 4 ;
73 headerptr ++ ;
74 }
75 else
76 {
77 status = 0 ;
78 }
79 break ;
80 case 4 : // head tail
81 content_head = headerptr;
82 content_length = atoi(response -> content_length);
83 content_rest_length = content_length - (readnum - (headerptr - header));
84 contentptr = content;
85 strncpy(content, content_head, readnum - (headerptr - header));
86 contentptr += readnum - (headerptr - header);
87 while (content_rest_length > 0 )
88 {
89 readnum = read(fd, contentptr, content_rest_length);
90 contentptr += readnum;
91 content_rest_length -= readnum;
92 }
93 break ;
94 }
95 }
96 }
97
98 return 0 ;
99 }
header Parser
代码
1
//
parser item in head
2 static int httpParseLine( const char * line, int len, http_response * response)
3 {
4 char c;
5 int index = 0 ;
6 int status = 0 ;
7
8 if (line == NULL || len == 0 || response == NULL)
9 {
10 return - 1 ;
11 }
12
13 while (status != 1 )
14 {
15 switch (status)
16 {
17 case 0 : // nothing happened
18 if (strncmp(line, " Content-Type: " , 13 ) == 0 )
19 {
20 status = 2 ;
21 }
22 else if (strncmp(line, " Content-Length: " , 15 ) == 0 )
23 {
24 status = 3 ;
25 }
26 else
27 {
28 return - 1 ;
29 }
30 break ;
31 case 1 : // finished
32 break ;
33 case 2 :
34 strcpy(response -> content_type, line + 13 );
35 status = 1 ;
36 break ;
37 case 3 :
38 strcpy(response -> content_length, line + 15 );
39 status = 1 ;
40 break ;
41 }
42 }
43
44 return 0 ;
45 }
2 static int httpParseLine( const char * line, int len, http_response * response)
3 {
4 char c;
5 int index = 0 ;
6 int status = 0 ;
7
8 if (line == NULL || len == 0 || response == NULL)
9 {
10 return - 1 ;
11 }
12
13 while (status != 1 )
14 {
15 switch (status)
16 {
17 case 0 : // nothing happened
18 if (strncmp(line, " Content-Type: " , 13 ) == 0 )
19 {
20 status = 2 ;
21 }
22 else if (strncmp(line, " Content-Length: " , 15 ) == 0 )
23 {
24 status = 3 ;
25 }
26 else
27 {
28 return - 1 ;
29 }
30 break ;
31 case 1 : // finished
32 break ;
33 case 2 :
34 strcpy(response -> content_type, line + 13 );
35 status = 1 ;
36 break ;
37 case 3 :
38 strcpy(response -> content_length, line + 15 );
39 status = 1 ;
40 break ;
41 }
42 }
43
44 return 0 ;
45 }