add get_url_content_ex to support buffer passed by caller
parent
b0494666ad
commit
b620f77391
5
HISTORY
5
HISTORY
|
|
@ -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
|
||||
|
|
|
|||
184
src/http_func.c
184
src/http_func.c
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue