HttpTunnel原理及源程序分析
作者: 来源: 发表时间:2007-05-28
浏览次数:
字号:大 中 小
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.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;
}
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;
还有一些其他相关函数可以参考源程序。