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

框架头文件:

/************************
 * HTTP Parser framework
 * 2010-01-11
 ************************/

#ifndef __SIMPLE_HTTP_H__
#define __SIMPLE_HTTP_H__

#define GET_REQUEST_SIZE 1024

#define HEADER_SIZE 1024
#define CONTENT_SIZE 1024000

// response header
typedef struct {
        char content_type[32];
        char content_length[32];
} http_response;

// build a GET request
int httpGET(char * sndbuf,
            int buflen,
            const char * http_version,
            const char * http_useragent,
            const char * http_host,
            const char * http_uri);

// read a response from a socket
// (no reconnection, so your socket must be healthy)
int httpResponse(int fd,
                 char * content,
                 int len,
                 http_response * response);

#endif

GET请求拼装

const char * HTTP_GET_FORMAT =
"GET %s %s/r/n" /
"User-Agent: %s/r/n" /
"Host: %s/r/n" /
"/r/n";

nt httpGET(char * sndbuf,
            int buflen,
            const char * http_version,
            const char * http_useragent,
            const char * http_host,
            const char * http_uri)
{
        if (sndbuf == NULL || buflen <= 0)
        {
                return -1;
        }

        return snprintf(sndbuf, buflen, HTTP_GET_FORMAT, http_uri, http_version, http_useragent, http_host);
}

Response解析 -- header 与 Content 切分部分
int httpResponse(int fd, char * content, int len, http_response * response)
{
	char header[HEADER_SIZE] = { 0 };

	char c;
	char line[1024];
	int cindex = 0;

	// analyze status
	int status = 0;
	
	char * contentptr = content;
	char * headerptr = header;
	char * content_head = NULL;

	int readnum = 0;
	int content_length = 0;
	int content_rest_length = 0;

	if (fd < 0 || content == NULL || len <= 0)
	{
		return -1;
	}

	if ((readnum = read(fd, header, HEADER_SIZE)) > 0)
	{
		while ((c = *headerptr) && content_head == NULL)
		{
			switch (status)
			{
			case 0: // nothing happend
				if (c == '/r') 
				{
					status = 1;

					httpParseLine(line, cindex, response); // a whole line

					cindex = 0;
					memset(line, 0, sizeof(line));
				}
				else 
				{
					line[cindex++] = c;
				}
				headerptr ++;
				break;
			case 1: // a /r appeared
				if (c == '/n') 
				{
					status = 2;
					headerptr ++;
				}
				else 
				{
					status = 0;
				}
				break;
			case 2: // a /n followed a /r
				if (c == '/r') 
				{
					status = 3;
					headerptr ++;
				}
				else
				{
					status = 0;
				}
				break;
			case 3: // a /r followed a /r/n pair
				if (c == '/n') 
				{
					status = 4;
					headerptr ++;
				}
				else
				{
					status = 0;
				}
				break;
			case 4: // head tail
				content_head = headerptr;
				content_length = atoi(response->content_length);
				content_rest_length = content_length - (readnum - (headerptr - header));
				contentptr = content;
				strncpy(content, content_head, readnum - (headerptr - header));
				contentptr += readnum - (headerptr - header);
				while (content_rest_length > 0)
				{
					readnum = read(fd, contentptr, content_rest_length);
					contentptr += readnum;
					content_rest_length -= readnum;
				}
				break;
			}
		}
	}

	return 0;
}

header Parser


// parser item in head
static int httpParseLine(const char * line, int len, http_response * response)
{
        char c;
        int index = 0;
        int status = 0;

        if (line == NULL || len == 0 || response == NULL)
        {
                return -1;
        }

        while (status != 1)
        {
                switch (status)
                {
                case 0: // nothing happened
                        if (strncmp(line, "Content-Type:", 13) == 0)
                        {
                                status = 2;
                        }
                        else if (strncmp(line, "Content-Length:", 15) == 0)
                        {
                                status = 3;
                        }
                        else
                        { 
                                return -1;
                        }
                        break;
                case 1: // finished
                        break;
                case 2:
                        strcpy(response->content_type, line + 13);
                        status = 1;
                        break;
                case 3:
                        strcpy(response->content_length, line + 15);
                        status = 1;
                        break;
                }
        }

        return 0;
}




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值