Merge pull request #6 from aozima/dev

add ipv6 address support.
master
Bernard Xiong 8 years ago committed by GitHub
commit e0cee1233f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,20 +1,27 @@
/* /*
* File : webclient.c * File : webclient.c
* COPYRIGHT (C) 2012-2013, Shanghai Real-Thread Technology Co., Ltd * COPYRIGHT (C) 2011-2018, Shanghai Real-Thread Technology Co., Ltd
* *
* Change Logs: * Change Logs:
* Date Author Notes * Date Author Notes
* 2013-05-05 Bernard the first version * 2013-05-05 Bernard the first version
* 2013-06-10 Bernard fix the slow speed issue when download file. * 2013-06-10 Bernard fix the slow speed issue when download file.
* 2015-11-14 aozima add content_length_remainder. * 2015-11-14 aozima add content_length_remainder.
* 2017-12-23 aozima update gethostbyname to getaddrinfo.
* 2018-01-04 aozima add ipv6 address support.
*/ */
#include "webclient.h" #include "webclient.h"
#include <string.h> #include <string.h>
#ifdef RT_USING_DFS_NET
#include <netdb.h>
#include <sys/socket.h>
#else
#include <lwip/netdb.h> #include <lwip/netdb.h>
#include <lwip/sockets.h> #include <lwip/sockets.h>
#endif /* RT_USING_DFS_NET */
#include "webclient_internal.h" #include "webclient_internal.h"
@ -41,7 +48,7 @@ char *webclient_strdup(const char *s)
return tmp; return tmp;
} }
static char* webclient_header_skip_prefix(char* line, const char* prefix) static char *webclient_header_skip_prefix(char *line, const char *prefix)
{ {
char *ptr; char *ptr;
size_t len = strlen(prefix); size_t len = strlen(prefix);
@ -71,7 +78,7 @@ static char* webclient_header_skip_prefix(char* line, const char* prefix)
* before the data. We need to read exactly to the end of the headers * before the data. We need to read exactly to the end of the headers
* and no more data. This readline reads a single char at a time. * and no more data. This readline reads a single char at a time.
*/ */
static int webclient_read_line(int socket, char * buffer, int size) static int webclient_read_line(int socket, char *buffer, int size)
{ {
int rc; int rc;
char *ptr = buffer; char *ptr = buffer;
@ -107,91 +114,107 @@ static int webclient_read_line(int socket, char * buffer, int size)
/* /*
* resolve server address * resolve server address
* @param server the server sockaddress * @param server the server sockaddress
* @param url the input URL address, for example, http://www.rt-thread.org/index.html * @param url the input URL address.
* @param host_addr the buffer pointer to save server host address * @param host_addr the buffer pointer to save server host address
* @param request the pointer to point the request url, for example, /index.html * @param request the pointer to point the request url, for example, /index.html
* *
* @return 0 on resolve server address OK, others failed * @return 0 on resolve server address OK, others failed
*
* URL example:
* http://www.rt-thread.org/
* http://192.168.1.1:80/index.htm
* http://[fe80::1]/index.html
* http://[fe80::1]:80/index.html
*/ */
static int webclient_resolve_address(struct webclient_session* session, struct sockaddr_in *server, static int webclient_resolve_address(struct webclient_session *session, struct addrinfo **res,
const char *url, char** request) const char *url, char **request)
{ {
int rc = WEBCLIENT_OK; int rc = WEBCLIENT_OK;
char *ptr; char *ptr;
char port[6] = "80"; /* default port of 80(http) */ char port_str[6] = "80"; /* default port of 80(http) */
int i = 0, is_domain;
struct hostent *hptr;
const char *host_addr = 0; const char *host_addr = 0;
int url_len, host_addr_len = 0; int url_len, host_addr_len = 0;
url_len = strlen(url); url_len = strlen(url);
/* strip protocol(http) */ /* strip protocol(http) */
ptr = strchr(url, ':'); if (strncmp(url, "http://", 7) != 0)
if (ptr != NULL)
{ {
url = ptr + 1; rc = -1;
goto _exit;
} }
host_addr = url + 7;
/* URL must start with double forward slashes. */ /* ipv6 address */
if ((url[0] != '/') || (url[1] != '/')) if (host_addr[0] == '[')
{ {
//rt_kprintf("is ipv6 address!\n");
host_addr += 1;
ptr = strstr(host_addr, "]");
if (!ptr)
{
//rt_kprintf("ipv6 address miss end!\n");
rc = -1; rc = -1;
goto _exit; goto _exit;
} }
host_addr_len = ptr - host_addr;
url += 2; ptr = strstr(host_addr + host_addr_len, "/");
is_domain = 0; if (!ptr)
i = 0;
/* allow specification of port in URL like http://www.server.net:8080/ */
while (*url)
{
if (*url == '/')
{ {
host_addr_len = url - host_addr; rc = -1;
break; goto _exit;
} }
else if (ptr != (host_addr + host_addr_len + 1))
if (*url == ':')
{ {
unsigned char w; int port_len = ptr - host_addr - host_addr_len - 2;
host_addr_len = url - host_addr; strncpy(port_str, host_addr + host_addr_len + 2, port_len);
port_str[port_len] = '\0';
for (w = 0; w < 5 && url[w + 1] != '/' && url[w + 1] != '\0'; w++) //rt_kprintf("ipv6 address port: %s\n", port_str);
port[w] = url[w + 1];
/* get port ok */
port[w] = '\0';
url += w + 1;
break;
} }
if ((*url < '0' || *url > '9') && *url != '.') *request = (char *)ptr;
is_domain = 1; }
else /* ipv4 or domain. */
{
char *port_ptr;
if(host_addr == 0) ptr = strstr(host_addr, "/");
if (!ptr)
{ {
host_addr = url; rc = -1;
//rt_kprintf("webclient_resolve_address host_addr start: %s\n", host_addr); goto _exit;
} }
host_addr_len = ptr - host_addr;
*request = (char *)ptr;
port_ptr = strstr(host_addr, ":");
if (port_ptr)
{
int port_len = ptr - port_ptr - 1;
strncpy(port_str, port_ptr + 1, port_len);
port_str[port_len] = '\0';
url++; host_addr_len = port_ptr - host_addr;
}
} }
*request = (char*) url;
if((host_addr_len < 1) || (host_addr_len > url_len) ) if ((host_addr_len < 1) || (host_addr_len > url_len))
{ {
//rt_kprintf("webclient_resolve_address host_addr_len: %d error!\n", host_addr_len); //rt_kprintf("%s host_addr_len: %d error!\n", __FUNCTION__, host_addr_len);
rc = -1; rc = -1;
goto _exit; goto _exit;
} }
/* get host addr ok. */ /* get host addr ok. */
{ {
char *host_addr_new = web_malloc(host_addr_len+1); char *host_addr_new = web_malloc(host_addr_len + 1);
if(!host_addr_new) if (!host_addr_new)
{ {
rc = -1; rc = -1;
goto _exit; goto _exit;
@ -203,40 +226,41 @@ static int webclient_resolve_address(struct webclient_session* session, struct s
//rt_kprintf("session->host: %s\n", session->host); //rt_kprintf("session->host: %s\n", session->host);
} }
if (is_domain)
{ {
/* resolve the host name. */ /* resolve the host name. */
hptr = gethostbyname(session->host); struct addrinfo hint;
if (hptr == 0) int ret;
memset(&hint, 0, sizeof(hint));
ret = getaddrinfo(session->host, port_str, &hint, res);
if (ret != 0)
{ {
rt_kprintf("WEBCLIENT: failed to resolve domain '%s'\n", session->host); rt_kprintf("getaddrinfo err: %d '%s'\n", ret, session->host);
rc = -1; rc = -1;
goto _exit; goto _exit;
} }
memcpy(&server->sin_addr, *hptr->h_addr_list, sizeof(server->sin_addr));
} }
else
{
inet_aton(session->host, (struct in_addr* )&(server->sin_addr));
}
/* set the port */
server->sin_port = htons((int) strtol(port, NULL, 10));
server->sin_family = AF_INET;
_exit: _exit:
if(rc != WEBCLIENT_OK) if (rc != WEBCLIENT_OK)
{ {
if(session->host) if (session->host)
{ {
web_free(session->host); web_free(session->host);
session->host = 0; session->host = 0;
} }
if (*res)
{
freeaddrinfo(*res);
*res = RT_NULL;
}
} }
return rc; return rc;
} }
int webclient_send_header(struct webclient_session* session, int method, int webclient_send_header(struct webclient_session *session, int method,
const char *header, size_t header_sz) const char *header, size_t header_sz)
{ {
int rc = WEBCLIENT_OK; int rc = WEBCLIENT_OK;
@ -244,7 +268,7 @@ int webclient_send_header(struct webclient_session* session, int method,
if (header == RT_NULL) if (header == RT_NULL)
{ {
header_buffer = web_malloc (WEBCLIENT_HEADER_BUFSZ); header_buffer = web_malloc(WEBCLIENT_HEADER_BUFSZ);
if (header_buffer == RT_NULL) if (header_buffer == RT_NULL)
{ {
rc = -WEBCLIENT_NOMEM; rc = -WEBCLIENT_NOMEM;
@ -252,14 +276,14 @@ int webclient_send_header(struct webclient_session* session, int method,
} }
header_ptr = header_buffer; header_ptr = header_buffer;
header_ptr += rt_snprintf((char*) header_ptr, header_ptr += rt_snprintf((char *) header_ptr,
WEBCLIENT_HEADER_BUFSZ - (header_ptr - header_buffer), WEBCLIENT_HEADER_BUFSZ - (header_ptr - header_buffer),
"GET %s HTTP/1.1\r\n", "GET %s HTTP/1.1\r\n",
session->request ? session->request : "/"); session->request ? session->request : "/");
header_ptr += rt_snprintf((char*) header_ptr, header_ptr += rt_snprintf((char *) header_ptr,
WEBCLIENT_HEADER_BUFSZ - (header_ptr - header_buffer), WEBCLIENT_HEADER_BUFSZ - (header_ptr - header_buffer),
"Host: %s\r\n", session->host); "Host: %s\r\n", session->host);
header_ptr += rt_snprintf((char*) header_ptr, header_ptr += rt_snprintf((char *) header_ptr,
WEBCLIENT_HEADER_BUFSZ - (header_ptr - header_buffer), WEBCLIENT_HEADER_BUFSZ - (header_ptr - header_buffer),
"User-Agent: RT-Thread HTTP Agent\r\n\r\n"); "User-Agent: RT-Thread HTTP Agent\r\n\r\n");
@ -269,7 +293,7 @@ int webclient_send_header(struct webclient_session* session, int method,
{ {
if (method != WEBCLIENT_USER_METHOD) if (method != WEBCLIENT_USER_METHOD)
{ {
header_buffer = web_malloc (WEBCLIENT_HEADER_BUFSZ); header_buffer = web_malloc(WEBCLIENT_HEADER_BUFSZ);
if (header_buffer == RT_NULL) if (header_buffer == RT_NULL)
{ {
rc = -WEBCLIENT_NOMEM; rc = -WEBCLIENT_NOMEM;
@ -281,13 +305,13 @@ int webclient_send_header(struct webclient_session* session, int method,
if (strstr(header, "HTTP/1.") == RT_NULL) if (strstr(header, "HTTP/1.") == RT_NULL)
{ {
if (method == WEBCLIENT_GET) if (method == WEBCLIENT_GET)
header_ptr += rt_snprintf((char*) header_ptr, header_ptr += rt_snprintf((char *) header_ptr,
WEBCLIENT_HEADER_BUFSZ WEBCLIENT_HEADER_BUFSZ
- (header_ptr - header_buffer), - (header_ptr - header_buffer),
"GET %s HTTP/1.1\r\n", "GET %s HTTP/1.1\r\n",
session->request ? session->request : "/"); session->request ? session->request : "/");
else if (method == WEBCLIENT_POST) else if (method == WEBCLIENT_POST)
header_ptr += rt_snprintf((char*) header_ptr, header_ptr += rt_snprintf((char *) header_ptr,
WEBCLIENT_HEADER_BUFSZ WEBCLIENT_HEADER_BUFSZ
- (header_ptr - header_buffer), - (header_ptr - header_buffer),
"POST %s HTTP/1.1\r\n", "POST %s HTTP/1.1\r\n",
@ -296,21 +320,21 @@ int webclient_send_header(struct webclient_session* session, int method,
if (strstr(header, "Host:") == RT_NULL) if (strstr(header, "Host:") == RT_NULL)
{ {
header_ptr += rt_snprintf((char*) header_ptr, header_ptr += rt_snprintf((char *) header_ptr,
WEBCLIENT_HEADER_BUFSZ - (header_ptr - header_buffer), WEBCLIENT_HEADER_BUFSZ - (header_ptr - header_buffer),
"Host: %s\r\n", session->host); "Host: %s\r\n", session->host);
} }
if (strstr(header, "User-Agent:") == RT_NULL) if (strstr(header, "User-Agent:") == RT_NULL)
{ {
header_ptr += rt_snprintf((char*) header_ptr, header_ptr += rt_snprintf((char *) header_ptr,
WEBCLIENT_HEADER_BUFSZ - (header_ptr - header_buffer), WEBCLIENT_HEADER_BUFSZ - (header_ptr - header_buffer),
"User-Agent: RT-Thread HTTP Agent\r\n"); "User-Agent: RT-Thread HTTP Agent\r\n");
} }
if (strstr(header, "Accept: ") == RT_NULL) if (strstr(header, "Accept: ") == RT_NULL)
{ {
header_ptr += rt_snprintf((char*) header_ptr, header_ptr += rt_snprintf((char *) header_ptr,
WEBCLIENT_HEADER_BUFSZ - (header_ptr - header_buffer), WEBCLIENT_HEADER_BUFSZ - (header_ptr - header_buffer),
"Accept: */*\r\n"); "Accept: */*\r\n");
} }
@ -325,7 +349,7 @@ int webclient_send_header(struct webclient_session* session, int method,
/* append user's header */ /* append user's header */
memcpy(header_ptr, header, header_sz); memcpy(header_ptr, header, header_sz);
header_ptr += header_sz; header_ptr += header_sz;
header_ptr += rt_snprintf((char*) header_ptr, header_ptr += rt_snprintf((char *) header_ptr,
WEBCLIENT_HEADER_BUFSZ - (header_ptr - header_buffer), WEBCLIENT_HEADER_BUFSZ - (header_ptr - header_buffer),
"\r\n"); "\r\n");
@ -333,7 +357,7 @@ int webclient_send_header(struct webclient_session* session, int method,
} }
else else
{ {
webclient_write(session, (unsigned char*) header, header_sz); webclient_write(session, (unsigned char *) header, header_sz);
} }
} }
@ -342,7 +366,7 @@ __exit:
return rc; return rc;
} }
int webclient_handle_response(struct webclient_session* session) int webclient_handle_response(struct webclient_session *session)
{ {
int rc; int rc;
int content_length = -1; int content_length = -1;
@ -353,7 +377,7 @@ int webclient_handle_response(struct webclient_session* session)
/* set content length of session */ /* set content length of session */
session->content_length = -1; session->content_length = -1;
mimeBuffer = (char*)web_malloc(WEBCLIENT_RESPONSE_BUFSZ + 1); mimeBuffer = (char *)web_malloc(WEBCLIENT_RESPONSE_BUFSZ + 1);
if (!mimeBuffer) if (!mimeBuffer)
return -1; return -1;
@ -464,12 +488,13 @@ int webclient_handle_response(struct webclient_session* session)
and handles the protocol and reads the return headers. Needs and handles the protocol and reads the return headers. Needs
to leave the stream at the start of the real data. to leave the stream at the start of the real data.
*/ */
int webclient_connect(struct webclient_session* session, const char *URI) int webclient_connect(struct webclient_session *session, const char *URI)
{ {
int rc; int rc = WEBCLIENT_OK;
int socket_handle; int socket_handle;
int timeout = WEBCLIENT_SOCKET_TIMEO; int timeout = WEBCLIENT_SOCKET_TIMEO;
struct sockaddr_in server; struct addrinfo *res = RT_NULL;
//struct sockaddr_in server;
char *request; char *request;
RT_ASSERT(session != RT_NULL); RT_ASSERT(session != RT_NULL);
@ -478,9 +503,17 @@ int webclient_connect(struct webclient_session* session, const char *URI)
session->socket = -1; session->socket = -1;
/* Check valid IP address and URL */ /* Check valid IP address and URL */
rc = webclient_resolve_address(session, &server, URI, &request); rc = webclient_resolve_address(session, &res, URI, &request);
if (rc != WEBCLIENT_OK) if (rc != WEBCLIENT_OK)
return rc; {
goto _exit;
}
if (!res)
{
rc = -1;
goto _exit;
}
/* copy host address */ /* copy host address */
if (*request) if (*request)
@ -488,34 +521,44 @@ int webclient_connect(struct webclient_session* session, const char *URI)
else else
session->request = RT_NULL; session->request = RT_NULL;
socket_handle = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); socket_handle = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP); //
if (socket_handle < 0) if (socket_handle < 0)
return -WEBCLIENT_NOSOCKET; {
rc = -WEBCLIENT_NOSOCKET;
goto _exit;
}
/* set recv timeout option */ /* set recv timeout option */
setsockopt(socket_handle, SOL_SOCKET, SO_RCVTIMEO, (void*) &timeout, setsockopt(socket_handle, SOL_SOCKET, SO_RCVTIMEO, (void *) &timeout,
sizeof(timeout)); sizeof(timeout));
setsockopt(socket_handle, SOL_SOCKET, SO_SNDTIMEO, (void*) &timeout, setsockopt(socket_handle, SOL_SOCKET, SO_SNDTIMEO, (void *) &timeout,
sizeof(timeout)); sizeof(timeout));
if (connect(socket_handle, (struct sockaddr *) &server, if (connect(socket_handle, res->ai_addr, res->ai_addrlen) != 0)
sizeof(struct sockaddr)) != 0)
{ {
/* connect failed, close socket handle */ /* connect failed, close socket handle */
closesocket(socket_handle); closesocket(socket_handle);
return -WEBCLIENT_CONNECT_FAILED; rc = -WEBCLIENT_CONNECT_FAILED;
goto _exit;
} }
session->socket = socket_handle; session->socket = socket_handle;
return WEBCLIENT_OK;
_exit:
if (res)
{
freeaddrinfo(res);
}
return rc;
} }
struct webclient_session* webclient_open(const char* URI) struct webclient_session *webclient_open(const char *URI)
{ {
struct webclient_session* session; struct webclient_session *session;
/* create session */ /* create session */
session = (struct webclient_session*) web_malloc(sizeof(struct webclient_session)); session = (struct webclient_session *) web_malloc(sizeof(struct webclient_session));
if (session == RT_NULL) if (session == RT_NULL)
return RT_NULL; return RT_NULL;
memset(session, 0x0, sizeof(struct webclient_session)); memset(session, 0x0, sizeof(struct webclient_session));
@ -557,13 +600,13 @@ struct webclient_session* webclient_open(const char* URI)
return session; return session;
} }
struct webclient_session* webclient_open_position(const char* URI, int position) struct webclient_session *webclient_open_position(const char *URI, int position)
{ {
struct webclient_session* session; struct webclient_session *session;
char *range_header; char *range_header;
/* create session */ /* create session */
session = (struct webclient_session*) web_malloc(sizeof(struct webclient_session)); session = (struct webclient_session *) web_malloc(sizeof(struct webclient_session));
if (session == RT_NULL) if (session == RT_NULL)
return RT_NULL; return RT_NULL;
memset(session, 0x0, sizeof(struct webclient_session)); memset(session, 0x0, sizeof(struct webclient_session));
@ -575,7 +618,7 @@ struct webclient_session* webclient_open_position(const char* URI, int position)
return RT_NULL; return RT_NULL;
} }
range_header = (char*)web_malloc (WEBCLIENT_HEADER_BUFSZ); range_header = (char *)web_malloc(WEBCLIENT_HEADER_BUFSZ);
rt_snprintf(range_header, WEBCLIENT_HEADER_BUFSZ - 1, rt_snprintf(range_header, WEBCLIENT_HEADER_BUFSZ - 1,
"Range: bytes=%d-\r\n", position); "Range: bytes=%d-\r\n", position);
if (!range_header) if (!range_header)
@ -617,13 +660,13 @@ __exit:
return RT_NULL; return RT_NULL;
} }
struct webclient_session* webclient_open_header(const char* URI, int method, struct webclient_session *webclient_open_header(const char *URI, int method,
const char* header, size_t header_sz) const char *header, size_t header_sz)
{ {
struct webclient_session* session; struct webclient_session *session;
/* create session */ /* create session */
session = (struct webclient_session*) web_malloc(sizeof(struct webclient_session)); session = (struct webclient_session *) web_malloc(sizeof(struct webclient_session));
if (session == RT_NULL) if (session == RT_NULL)
return RT_NULL; return RT_NULL;
memset(session, 0, sizeof(struct webclient_session)); memset(session, 0, sizeof(struct webclient_session));
@ -654,20 +697,20 @@ struct webclient_session* webclient_open_header(const char* URI, int method,
return session; return session;
} }
int webclient_set_timeout(struct webclient_session* session, int millisecond) int webclient_set_timeout(struct webclient_session *session, int millisecond)
{ {
RT_ASSERT(session != RT_NULL); RT_ASSERT(session != RT_NULL);
/* set recv timeout option */ /* set recv timeout option */
setsockopt(session->socket, SOL_SOCKET, SO_RCVTIMEO, setsockopt(session->socket, SOL_SOCKET, SO_RCVTIMEO,
(void*) &millisecond, sizeof(millisecond)); (void *) &millisecond, sizeof(millisecond));
setsockopt(session->socket, SOL_SOCKET, SO_SNDTIMEO, setsockopt(session->socket, SOL_SOCKET, SO_SNDTIMEO,
(void*) &millisecond, sizeof(millisecond)); (void *) &millisecond, sizeof(millisecond));
return 0; return 0;
} }
static int webclient_next_chunk(struct webclient_session* session) static int webclient_next_chunk(struct webclient_session *session)
{ {
char line[64]; char line[64];
int length; int length;
@ -707,7 +750,7 @@ static int webclient_next_chunk(struct webclient_session* session)
return session->chunk_sz; return session->chunk_sz;
} }
int webclient_read(struct webclient_session* session, unsigned char *buffer, int webclient_read(struct webclient_session *session, unsigned char *buffer,
size_t length) size_t length)
{ {
int bytesRead = 0; int bytesRead = 0;
@ -748,14 +791,14 @@ int webclient_read(struct webclient_session* session, unsigned char *buffer,
return bytesRead; return bytesRead;
} }
if(session->content_length > 0) if (session->content_length > 0)
{ {
if(length > session->content_length_remainder) if (length > session->content_length_remainder)
{ {
length = session->content_length_remainder; length = session->content_length_remainder;
} }
if(length == 0) if (length == 0)
{ {
return 0; return 0;
} }
@ -798,9 +841,10 @@ int webclient_read(struct webclient_session* session, unsigned char *buffer,
left -= bytesRead; left -= bytesRead;
totalRead += bytesRead; totalRead += bytesRead;
} while (left); }
while (left);
if(session->content_length > 0) if (session->content_length > 0)
{ {
session->content_length_remainder -= totalRead; session->content_length_remainder -= totalRead;
} }
@ -808,7 +852,7 @@ int webclient_read(struct webclient_session* session, unsigned char *buffer,
return totalRead; return totalRead;
} }
int webclient_write(struct webclient_session* session, int webclient_write(struct webclient_session *session,
const unsigned char *buffer, size_t length) const unsigned char *buffer, size_t length)
{ {
int bytesWrite = 0; int bytesWrite = 0;
@ -849,7 +893,8 @@ int webclient_write(struct webclient_session* session,
left -= bytesWrite; left -= bytesWrite;
totalWrite += bytesWrite; totalWrite += bytesWrite;
} while (left); }
while (left);
return totalWrite; return totalWrite;
} }
@ -857,7 +902,7 @@ int webclient_write(struct webclient_session* session,
/* /*
* close a webclient client session. * close a webclient client session.
*/ */
int webclient_close(struct webclient_session* session) int webclient_close(struct webclient_session *session)
{ {
RT_ASSERT(session != RT_NULL); RT_ASSERT(session != RT_NULL);
@ -873,10 +918,10 @@ int webclient_close(struct webclient_session* session)
return 0; return 0;
} }
int webclient_response(struct webclient_session* session, void **response) int webclient_response(struct webclient_session *session, void **response)
{ {
unsigned char* buf_ptr; unsigned char *buf_ptr;
unsigned char* response_buf = 0; unsigned char *response_buf = 0;
int length, total_read = 0; int length, total_read = 0;
if (!session || !response) return -1; if (!session || !response) return -1;
@ -889,18 +934,18 @@ int webclient_response(struct webclient_session* session, void **response)
total_read = 0; total_read = 0;
while (1) while (1)
{ {
unsigned char* new_resp; unsigned char *new_resp;
result_sz = total_read + WEBCLIENT_RESPONSE_BUFSZ; result_sz = total_read + WEBCLIENT_RESPONSE_BUFSZ;
new_resp = web_realloc(response_buf, result_sz + 1); new_resp = web_realloc(response_buf, result_sz + 1);
if(!new_resp) if (!new_resp)
{ {
rt_kprintf("no memory for realloc new_resp\n"); rt_kprintf("no memory for realloc new_resp\n");
break; break;
} }
response_buf = new_resp; response_buf = new_resp;
buf_ptr = (unsigned char*) response_buf + total_read; buf_ptr = (unsigned char *) response_buf + total_read;
/* read result */ /* read result */
length = webclient_read(session, buf_ptr, result_sz - total_read); length = webclient_read(session, buf_ptr, result_sz - total_read);
@ -916,9 +961,9 @@ int webclient_response(struct webclient_session* session, void **response)
result_sz = session->content_length; result_sz = session->content_length;
response_buf = web_malloc(result_sz + 1); response_buf = web_malloc(result_sz + 1);
if(!response_buf) return 0; if (!response_buf) return 0;
buf_ptr = (unsigned char*) response_buf; buf_ptr = (unsigned char *) response_buf;
for (total_read = 0; total_read < result_sz;) for (total_read = 0; total_read < result_sz;)
{ {
length = webclient_read(session, buf_ptr, result_sz - total_read); length = webclient_read(session, buf_ptr, result_sz - total_read);
@ -949,15 +994,15 @@ int webclient_response(struct webclient_session* session, void **response)
/* /*
* High level APIs for webclient client * High level APIs for webclient client
*/ */
struct webclient_session* webclient_open_custom(const char* URI, int method, struct webclient_session *webclient_open_custom(const char *URI, int method,
const char* header, size_t header_sz, const char* data, size_t data_sz) const char *header, size_t header_sz, const char *data, size_t data_sz)
{ {
int rc = 0; int rc = 0;
size_t length; size_t length;
struct webclient_session* session = RT_NULL; struct webclient_session *session = RT_NULL;
/* create session */ /* create session */
session = (struct webclient_session*) web_malloc(sizeof(struct webclient_session)); session = (struct webclient_session *) web_malloc(sizeof(struct webclient_session));
if (!session) if (!session)
{ {
rc = -WEBCLIENT_NOMEM; rc = -WEBCLIENT_NOMEM;
@ -977,7 +1022,7 @@ struct webclient_session* webclient_open_custom(const char* URI, int method,
/* POST data */ /* POST data */
if (data) if (data)
{ {
length = webclient_write(session, (unsigned char*) data, data_sz); length = webclient_write(session, (unsigned char *) data, data_sz);
if (length != data_sz) if (length != data_sz)
{ {
rt_kprintf("POST data %d:%d\n", length, data_sz); rt_kprintf("POST data %d:%d\n", length, data_sz);
@ -991,7 +1036,7 @@ struct webclient_session* webclient_open_custom(const char* URI, int method,
goto _success; goto _success;
_err_exit: _err_exit:
if(session) if (session)
{ {
webclient_close(session); webclient_close(session);
session = 0; session = 0;
@ -1001,16 +1046,16 @@ _success:
return session; return session;
} }
int webclient_transfer(const char* URI, const char* header, size_t header_sz, int webclient_transfer(const char *URI, const char *header, size_t header_sz,
const char* data, size_t data_sz, char *result, size_t result_sz) const char *data, size_t data_sz, char *result, size_t result_sz)
{ {
int rc = 0; int rc = 0;
int length, total_read = 0; int length, total_read = 0;
unsigned char* buf_ptr; unsigned char *buf_ptr;
struct webclient_session* session = RT_NULL; struct webclient_session *session = RT_NULL;
/* create session */ /* create session */
session = (struct webclient_session*) web_malloc(sizeof(struct webclient_session)); session = (struct webclient_session *) web_malloc(sizeof(struct webclient_session));
if (!session) if (!session)
{ {
rc = -WEBCLIENT_NOMEM; rc = -WEBCLIENT_NOMEM;
@ -1028,7 +1073,7 @@ int webclient_transfer(const char* URI, const char* header, size_t header_sz,
goto __exit; goto __exit;
/* POST data */ /* POST data */
length = webclient_write(session, (unsigned char*) data, data_sz); length = webclient_write(session, (unsigned char *) data, data_sz);
if (length != data_sz) if (length != data_sz)
{ {
rt_kprintf("POST data %d:%d\n", length, data_sz); rt_kprintf("POST data %d:%d\n", length, data_sz);
@ -1050,7 +1095,7 @@ int webclient_transfer(const char* URI, const char* header, size_t header_sz,
if (session->content_length == 0) if (session->content_length == 0)
{ {
total_read = 0; total_read = 0;
buf_ptr = (unsigned char*) result; buf_ptr = (unsigned char *) result;
while (1) while (1)
{ {
/* read result */ /* read result */
@ -1065,7 +1110,7 @@ int webclient_transfer(const char* URI, const char* header, size_t header_sz,
} }
else else
{ {
buf_ptr = (unsigned char*) result; buf_ptr = (unsigned char *) result;
for (total_read = 0; total_read < result_sz;) for (total_read = 0; total_read < result_sz;)
{ {
length = webclient_read(session, buf_ptr, result_sz - total_read); length = webclient_read(session, buf_ptr, result_sz - total_read);

@ -1,11 +1,14 @@
/* /*
* File : webclient.h * File : webclient.h
* COPYRIGHT (C) 2012-2013, Shanghai Real-Thread Technology Co., Ltd * COPYRIGHT (C) 2011-2018, Shanghai Real-Thread Technology Co., Ltd
* *
* Change Logs: * Change Logs:
* Date Author Notes * Date Author Notes
* 2013-05-05 Bernard the first version * 2013-05-05 Bernard the first version
* 2013-06-10 Bernard fix the slow speed issue when download file.
* 2015-11-14 aozima add content_length_remainder. * 2015-11-14 aozima add content_length_remainder.
* 2017-12-23 aozima update gethostbyname to getaddrinfo.
* 2018-01-04 aozima add ipv6 address support.
*/ */
#ifndef __WEBCLIENT_H__ #ifndef __WEBCLIENT_H__
@ -52,20 +55,20 @@ struct webclient_session
int chunk_offset; int chunk_offset;
/* content_type of HTTP response */ /* content_type of HTTP response */
char* content_type; char *content_type;
/* content_length of HTTP response */ /* content_length of HTTP response */
int content_length; int content_length;
/* last modified timestamp of resource */ /* last modified timestamp of resource */
char* last_modified; char *last_modified;
/* location */ /* location */
char* location; char *location;
/* server host */ /* server host */
char* host; char *host;
/* HTTP request */ /* HTTP request */
char* request; char *request;
/* private for webclient session. */ /* private for webclient session. */
@ -76,35 +79,35 @@ struct webclient_session
size_t content_length_remainder; size_t content_length_remainder;
}; };
struct webclient_session* webclient_open(const char* URI); struct webclient_session *webclient_open(const char *URI);
struct webclient_session* webclient_open_position(const char* URI, int position); struct webclient_session *webclient_open_position(const char *URI, int position);
struct webclient_session* webclient_open_header(const char* URI, int method, const char* header, size_t header_sz); struct webclient_session *webclient_open_header(const char *URI, int method, const char *header, size_t header_sz);
int webclient_close(struct webclient_session* session); int webclient_close(struct webclient_session *session);
int webclient_set_timeout(struct webclient_session* session, int millisecond); int webclient_set_timeout(struct webclient_session *session, int millisecond);
int webclient_read (struct webclient_session* session, unsigned char *buffer, size_t size); int webclient_read(struct webclient_session *session, unsigned char *buffer, size_t size);
int webclient_write(struct webclient_session* session, const unsigned char *buffer, size_t size); int webclient_write(struct webclient_session *session, const unsigned char *buffer, size_t size);
int webclient_send_header(struct webclient_session* session, int method, int webclient_send_header(struct webclient_session *session, int method,
const char *header, size_t header_sz); const char *header, size_t header_sz);
int webclient_connect(struct webclient_session* session, const char *URI); int webclient_connect(struct webclient_session *session, const char *URI);
int webclient_handle_response(struct webclient_session* session); int webclient_handle_response(struct webclient_session *session);
/* hight level APIs for HTTP client */ /* hight level APIs for HTTP client */
int webclient_response(struct webclient_session* session, void **response); int webclient_response(struct webclient_session *session, void **response);
struct webclient_session* webclient_open_custom(const char* URI, int method, struct webclient_session *webclient_open_custom(const char *URI, int method,
const char* header, size_t header_sz, const char *header, size_t header_sz,
const char* data, size_t data_sz); const char *data, size_t data_sz);
int webclient_transfer(const char* URI, const char* header, size_t header_sz, int webclient_transfer(const char *URI, const char *header, size_t header_sz,
const char* data, size_t data_sz, const char *data, size_t data_sz,
char *result, size_t result_sz); char *result, size_t result_sz);
#ifdef RT_USING_DFS #ifdef RT_USING_DFS
int webclient_get_file(const char* URI, const char* filename); int webclient_get_file(const char *URI, const char *filename);
int webclient_post_file(const char* URI, const char* filename, const char* form_data); int webclient_post_file(const char *URI, const char *filename, const char *form_data);
#endif #endif
#endif #endif

Loading…
Cancel
Save