add get_url_content_ex to support buffer passed by caller

pull/1/head
yuqing 2014-06-13 14:13:06 +08:00
parent b0494666ad
commit b620f77391
4 changed files with 131 additions and 83 deletions

View File

@ -1,9 +1,12 @@
Version 1.06 2014-06-06
Version 1.06 2014-06-13
* update source code from FastDFS V5.02
* add function short2buff and buff2short
* add object memory pool (fast_mblock.h and fast_mblock.c)
* add member thread_loop_callback in nio_thread_data
* bug fixed: ini_file_reader.c can't include relative path sub config,
such as #include ../../conf/common.conf
* add get_url_content_ex to support buffer passed by caller
Version 1.05 2012-07-08
* update source code from FastDFS V3.09

View File

@ -22,21 +22,21 @@
#include "logger.h"
#include "shared_func.h"
int get_url_content(const char *url, const int connect_timeout, \
const int network_timeout, int *http_status, \
char **content, int *content_len, char *error_info)
int get_url_content_ex(const char *url, const int url_len,
const int connect_timeout, const int network_timeout,
int *http_status, char **content, int *content_len, char *error_info)
{
char domain_name[256];
char ip_addr[IP_ADDRESS_SIZE];
char out_buff[4096];
int domain_len;
int url_len;
int out_len;
int alloc_size;
int recv_bytes;
int result;
int sock;
int port;
bool bNeedAlloc;
const char *pDomain;
const char *pContent;
const char *pURI;
@ -44,10 +44,18 @@ int get_url_content(const char *url, const int connect_timeout, \
char *pSpace;
*http_status = 0;
if (*content == NULL)
{
bNeedAlloc = true;
alloc_size = 64 * 1024;
}
else
{
bNeedAlloc = false;
alloc_size = *content_len;
}
*content_len = 0;
*content = NULL;
url_len = strlen(url);
if (url_len <= 7 || strncasecmp(url, "http://", 7) != 0)
{
sprintf(error_info, "file: "__FILE__", line: %d, " \
@ -137,43 +145,56 @@ int get_url_content(const char *url, const int connect_timeout, \
return result;
}
alloc_size = 64 * 1024;
*content = (char *)malloc(alloc_size + 1);
if (*content == NULL)
{
close(sock);
result = errno != 0 ? errno : ENOMEM;
if (bNeedAlloc)
{
*content = (char *)malloc(alloc_size + 1);
if (*content == NULL)
{
close(sock);
result = errno != 0 ? errno : ENOMEM;
sprintf(error_info, "file: "__FILE__", line: %d, " \
"malloc %d bytes fail, errno: %d, " \
"error info: %s", __LINE__, alloc_size + 1, \
result, STRERROR(result));
sprintf(error_info, "file: "__FILE__", line: %d, " \
"malloc %d bytes fail, errno: %d, " \
"error info: %s", __LINE__, alloc_size + 1, \
result, STRERROR(result));
return result;
}
return result;
}
}
do
{
recv_bytes = alloc_size - *content_len;
if (recv_bytes <= 0)
{
alloc_size *= 2;
*content = (char *)realloc(*content, alloc_size + 1);
if (*content == NULL)
{
close(sock);
result = errno != 0 ? errno : ENOMEM;
if (bNeedAlloc)
{
alloc_size *= 2;
*content = (char *)realloc(*content, alloc_size + 1);
if (*content == NULL)
{
*content_len = 0;
close(sock);
result = errno != 0 ? errno : ENOMEM;
sprintf(error_info, "file: "__FILE__", line: %d, " \
"realloc %d bytes fail, errno: %d, " \
"error info: %s", __LINE__, \
alloc_size + 1, \
result, STRERROR(result));
sprintf(error_info, "file: "__FILE__", line: %d, " \
"realloc %d bytes fail, errno: %d, " \
"error info: %s", __LINE__, \
alloc_size + 1, \
result, STRERROR(result));
return result;
}
return result;
}
recv_bytes = alloc_size - *content_len;
recv_bytes = alloc_size - *content_len;
}
else
{
sprintf(error_info, "file: "__FILE__", line: %d, " \
"buffer size: %d is too small", \
__LINE__, alloc_size);
return ENOSPC;
}
}
result = tcprecvdata_ex(sock, *content + *content_len, \
@ -182,62 +203,67 @@ int get_url_content(const char *url, const int connect_timeout, \
*content_len += recv_bytes;
} while (result == 0);
if (result != ENOTCONN)
{
close(sock);
free(*content);
*content = NULL;
*content_len = 0;
do
{
if (result != ENOTCONN)
{
sprintf(error_info, "file: "__FILE__", line: %d, " \
"recv data from %s:%d fail, errno: %d, " \
"error info: %s", __LINE__, domain_name, \
port, result, STRERROR(result));
sprintf(error_info, "file: "__FILE__", line: %d, " \
"recv data from %s:%d fail, errno: %d, " \
"error info: %s", __LINE__, domain_name, \
port, result, STRERROR(result));
break;
}
return result;
}
*(*content + *content_len) = '\0';
pContent = strstr(*content, "\r\n\r\n");
if (pContent == NULL)
{
sprintf(error_info, "file: "__FILE__", line: %d, " \
"response data from %s:%d is invalid", \
__LINE__, domain_name, port);
*(*content + *content_len) = '\0';
pContent = strstr(*content, "\r\n\r\n");
if (pContent == NULL)
{
close(sock);
free(*content);
*content = NULL;
*content_len = 0;
result = EINVAL;
break;
}
sprintf(error_info, "file: "__FILE__", line: %d, " \
"response data from %s:%d is invalid", \
__LINE__, domain_name, port);
pContent += 4;
pSpace = strchr(*content, ' ');
if (pSpace == NULL || pSpace >= pContent)
{
sprintf(error_info, "file: "__FILE__", line: %d, " \
"response data from %s:%d is invalid", \
__LINE__, domain_name, port);
return EINVAL;
}
result = EINVAL;
break;
}
pContent += 4;
pSpace = strchr(*content, ' ');
if (pSpace == NULL || pSpace >= pContent)
{
close(sock);
free(*content);
*content = NULL;
*content_len = 0;
sprintf(error_info, "file: "__FILE__", line: %d, " \
"response data from %s:%d is invalid", \
__LINE__, domain_name, port);
return EINVAL;
}
*http_status = atoi(pSpace + 1);
*content_len -= pContent - *content;
memcpy(*content, pContent, *content_len);
*(*content + *content_len) = '\0';
*http_status = atoi(pSpace + 1);
*content_len -= pContent - *content;
memcpy(*content, pContent, *content_len);
*(*content + *content_len) = '\0';
*error_info = '\0';
} while (0);
close(sock);
if (result != 0 && bNeedAlloc)
{
free(*content);
*content = NULL;
*content_len = 0;
}
*error_info = '\0';
return 0;
return result;
}
int get_url_content(const char *url, const int connect_timeout, \
const int network_timeout, int *http_status, \
char **content, int *content_len, char *error_info)
{
*content = NULL;
return get_url_content_ex(url, strlen(url), connect_timeout, network_timeout,
http_status, content, content_len, error_info);
}
int http_parse_query(char *url, KeyValuePair *params, const int max_count)

View File

@ -24,8 +24,26 @@ extern "C" {
get content from url
params:
url: the url to fetch, must start as: "http://"
connect_timeout: connect timeout (seconds)
network_timeout: network timeout (seconds)
connect_timeout: connect timeout in seconds
network_timeout: network timeout in seconds
http_status: return http status code, 200 for Ok
content: return the content (HTTP body only, not including HTTP header),
*content should be freed by caller when input *content is NULL for auto malloc
content_len: input for *content buffer size when *content is NOT NULL,
output for content length (bytes)
return: 0 for success, != 0 for error
**/
int get_url_content_ex(const char *url, const int url_len,
const int connect_timeout, const int network_timeout,
int *http_status, char **content, int *content_len, char *error_info);
/**
get content from url
params:
url: the url to fetch, must start as: "http://"
connect_timeout: connect timeout in seconds
network_timeout: network timeout in seconds
http_status: return http status code, 200 for Ok
content: return the content (HTTP body only, not including HTTP header),
*content should be freed by caller

View File

@ -139,7 +139,7 @@ int iniLoadFromFile(const char *szFilename, IniContext *pContext)
int tail_len;
tail_len = pLast - szFilename;
if (len + tail_len >= sizeof( \
if (len + 1 + tail_len >= sizeof( \
pContext->config_path))
{
logError("file: "__FILE__", line: %d, "\
@ -149,6 +149,7 @@ int iniLoadFromFile(const char *szFilename, IniContext *pContext)
return ENOSPC;
}
*(pContext->config_path + len++) = '/';
memcpy(pContext->config_path + len, \
szFilename, tail_len);
len += tail_len;