HTTP协议框架 - 构建最简单的 GET 请求拼装和 Response 解析

头文件:

 
  
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

 

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

 

拼装部分:

 
  
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 }

 

Response解析 -- header 与 Content 切分部分

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
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 }

 

header Parser

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
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 }

 

转载于:https://www.cnblogs.com/boymgl/articles/1664355.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值