当前位置: 首页 >> 程序设计 >> HttpTunnel原理及源程序分析
 

HttpTunnel原理及源程序分析

作者:      来源:     发表时间:2007-05-28     浏览次数:      字号:    

 
3.3 HTTP请求的封装与实现
3.3.1 HTTP请求结构
typedef struct
{
 Http_method method;
 const char *uri;
 int major_version;
 int minor_version;
 Http_header *header;
} Http_request;       
3.3.2 为HTTP请求分配内存空间
static inline Http_request *
http_allocate_request (const char *uri)
{
     Http_request *request;
 
     request = malloc (sizeof (Http_request));
     if (request == NULL)
              return NULL;
 
     request->uri = strdup (uri);
     if (request->uri == NULL)
     {
              free (request);
              return NULL;
     }
 
     return request;
}
3.3.3 创建HTTP请求
Http_request *
http_create_request (Http_method method,
                                           const char *uri,
                                           int major_version,
                                           int minor_version)
{
     Http_request *request;
 
     request = http_allocate_request (uri);
     if (request == NULL)
              return NULL;
 
     request->method = method;
     request->major_version = major_version;
     request->minor_version = minor_version;
     request->header = NULL;
 
     return request;
}
3.3.4 解析HTTP请求
ssize_t
http_parse_request (int fd, Http_request **request_)
{
     Http_request *request;
     unsigned char *data;
     size_t len;
     ssize_t n;
 
     *request_ = NULL;
 
     request = malloc (sizeof (Http_request));
     if (request == NULL)
     {
              log_error ("http_parse_request: out of memory");
              return -1;
     }
 
     request->method = -1;
     request->uri = NULL;
     request->major_version = -1;
     request->minor_version = -1;
     request->header = NULL;
 
     n = read_until (fd, ' ', &data);
     if (n <= 0)
     {
              free (request);
              return n;
     }
     request->method = http_string_to_method (data, n - 1);
     if (request->method == -1)
     {
              log_error ("http_parse_request: expected an HTTP method");
              free (data);
              free (request);
              return -1;
     }
     data[n - 1] = 0;
     log_verbose ("http_parse_request: method = \"%s\"", data);
     free (data);
     len = n;
 
     n = read_until (fd, ' ', &data);
     if (n <= 0)
     {
              free (request);
              return n;
     }
     data[n - 1] = 0;
     request->uri = data;
     len += n;
     log_verbose ("http_parse_request: uri = \"%s\"", request->uri);
 
     n = read_until (fd, '/', &data);
     if (n <= 0)
     {
              http_destroy_request (request);
              return n;
     }
     else if (n != 5 || memcmp (data, "HTTP", 4) != 0)
     {
              log_error ("http_parse_request: expected \"HTTP\"");
              free (data);
              http_destroy_request (request);
              return -1;
     }
     free (data);
     len = n;
 
     n = read_until (fd, '.', &data);
     if (n <= 0)
     {
              http_destroy_request (request);
              return n;
     }
     data[n - 1] = 0;
     request->major_version = atoi (data);
     log_verbose ("http_parse_request: major version = %d",
              request->major_version);
     free (data);
     len += n;
 
     n = read_until (fd, '\r', &data);
     if (n <= 0)
     {
              http_destroy_request (request);
              return n;
     }
     data[n - 1] = 0;
     request->minor_version = atoi (data);
     log_verbose ("http_parse_request: minor version = %d",
              request->minor_version);
     free (data);
     len += n;
 
     n = read_until (fd, '\n', &data);
     if (n <= 0)
     {
              http_destroy_request (request);
              return n;
     }
     free (data);
     if (n != 1)
     {
              log_error ("http_parse_request: invalid line ending");
              http_destroy_request (request);
              return -1;
     }
     len += n;
     n = parse_header (fd, &request->header);
     if (n <= 0)
     {
              http_destroy_request (request);
              return n;
     }
     len += n;
     *request_ = request;
     return len;
}
3.3.5 销毁HTTP请求
void
http_destroy_request (Http_request *request)
{
     if (request->uri)
              free ((char *)request->uri);
     http_destroy_header (request->header);
     free (request);
}
3.4 HTTP响应的封装与实现
3.4.1 HTTP响应结构
typedef struct
{
   int major_version;
   int minor_version;
   int status_code;
   const char *status_message;
   Http_header *header;
} Http_response;
3.4.2 为HTTP响应分配内存空间
static inline Http_response *
http_allocate_response (const char *status_message)
{
     Http_response *response;
 
     response = malloc (sizeof (Http_response));
     if (response == NULL)
              return NULL;
 
     response->status_message = strdup (status_message);
     if (response->status_message == NULL)
     {
              free (response);
              return NULL;
     }
 
     return response;
}
3.4.3 创建HTTP响应
Http_response *
http_create_response (int major_version,
                                           int minor_version,
                                           int status_code,
                                           const char *status_message)
{
     Http_response *response;
 
     response = http_allocate_response (status_message);
     if (response == NULL)
              return NULL;
 
     response->major_version = major_version;
     response->minor_version = minor_version;
     response->status_code = status_code;
     response->header = NULL;
 
     return response;
}
3.4.4 解析HTTP响应
ssize_t
http_parse_response (int fd, Http_response **response_)
{
     Http_response *response;
     unsigned char *data;
     size_t len;
     ssize_t n;
 
     *response_ = NULL;
 
     response = malloc (sizeof (Http_response));
     if (response == NULL)
     {
              log_error ("http_parse_response: out of memory");
              return -1;
     }
 
     response->major_version = -1;
     response->minor_version = -1;
     response->status_code = -1;
     response->status_message = NULL;
     response->header = NULL;
 
     n = read_until (fd, '/', &data);
     if (n <= 0)
     {
              free (response);
              return n;
     }
     else if (n != 5 || memcmp (data, "HTTP", 4) != 0)
     {
              log_error ("http_parse_response: expected \"HTTP\"");
              free (data);
              free (response);
              return -1;
     }
     free (data);
     len = n;
 
     n = read_until (fd, '.', &data);
     if (n <= 0)
     {
              free (response);
              return n;
     }
     data[n - 1] = 0;
     response->major_version = atoi (data);
     log_verbose ("http_parse_response: major version = %d",
              response->major_version);
     free (data);
     len += n;
 
     n = read_until (fd, ' ', &data);
     if (n <= 0)
     {
              free (response);
              return n;
     }
     data[n - 1] = 0;
     response->minor_version = atoi (data);
     log_verbose ("http_parse_response: minor version = %d",
              response->minor_version);
     free (data);
     len += n;
 
     n = read_until (fd, ' ', &data);
     if (n <= 0)
     {
              free (response);
              return n;
     }
     data[n - 1] = 0;
     response->status_code = atoi (data);
     log_verbose ("http_parse_response: status code = %d",
              response->status_code);
     free (data);
     len += n;
 
     n = read_until (fd, '\r', &data);
     if (n <= 0)
     {
              free (response);
              return n;
     }
     data[n - 1] = 0;
     response->status_message = data;
     log_verbose ("http_parse_response: status message = \"%s\"",
              response->status_message);
     len += n;
 
     n = read_until (fd, '\n', &data);
     if (n <= 0)
     {
              http_destroy_response (response);
              return n;
     }
     free (data);
     if (n != 1)
     {
              log_error ("http_parse_request: invalid line ending");
              http_destroy_response (response);
              return -1;
     }
     len += n;
 
     n = parse_header (fd, &response->header);
     if (n <= 0)
     {
              http_destroy_response (response);
              return n;
     }
     len += n;
 
     *response_ = response;
     return len;
}
3.5 HTTP目标的封装
typedef struct
{
 const char *host_name;
 int host_port;
 const char *proxy_name;
 int proxy_port;
 const char *proxy_authorization;
 const char *user_agent;
} Http_destination;
还有一些其他相关函数可以参考源程序。

[1] [2]

责任编辑 webmaster

 
发表评论  打印本文  推荐本文  加入收藏  返回顶部  关闭窗口
 
 
 
 
评论更多>>
 
 
 
发表
 
姓名: QQ:
性别: MSN:
E-mail: 主页:
评分: 1 2 3 4 5
评论内容:
验证码:
  
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  •