mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-11-29 18:48:09 +08:00
add data_reader_http
This commit is contained in:
parent
267cb72d95
commit
901dd67269
@ -1,5 +1,8 @@
|
||||
# 最新动态
|
||||
|
||||
2023/12/22
|
||||
* 增加data\_reader\_http。
|
||||
|
||||
2023/12/21
|
||||
* 增加控件继承的函数指针查找父集的逻辑(感谢智明提供补丁)
|
||||
|
||||
|
@ -45,6 +45,10 @@
|
||||
#include "base/vgcanvas_asset_manager.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_SOCKET
|
||||
#include "tkc/socket_helper.h"
|
||||
#endif/*WITH_SOCKET*/
|
||||
|
||||
#ifdef WITH_FSCRIPT_EXT
|
||||
#ifndef WITH_DATA_READER_WRITER
|
||||
#define WITH_DATA_READER_WRITER
|
||||
@ -59,6 +63,9 @@
|
||||
#include "tkc/data_reader_file.h"
|
||||
#include "tkc/data_reader_mem.h"
|
||||
#include "base/data_reader_asset.h"
|
||||
#ifdef WITH_SOCKET
|
||||
#include "tkc/data_reader_http.h"
|
||||
#endif/*WITH_SOCKET*/
|
||||
#endif /*WITH_DATA_READER_WRITER*/
|
||||
|
||||
#include "base/widget_animator_manager.h"
|
||||
@ -300,6 +307,12 @@ ret_t tk_pre_init(void) {
|
||||
data_reader_factory_register(data_reader_factory(), "asset", data_reader_asset_create);
|
||||
data_reader_factory_register(data_reader_factory(), "mem", data_reader_mem_create);
|
||||
data_writer_factory_register(data_writer_factory(), "wbuffer", data_writer_wbuffer_create);
|
||||
#ifdef WITH_SOCKET
|
||||
data_reader_factory_register(data_reader_factory(), "http", data_reader_http_create);
|
||||
#ifdef WITH_MBEDTLS
|
||||
data_reader_factory_register(data_reader_factory(), "https", data_reader_http_create);
|
||||
#endif/*WITH_MBEDTLS*/
|
||||
#endif/*WITH_SOCKET*/
|
||||
#endif /*WITH_DATA_READER_WRITER*/
|
||||
inited = TRUE;
|
||||
}
|
||||
@ -327,6 +340,9 @@ ret_t tk_init(wh_t w, wh_t h, app_type_t app_type, const char* app_name, const c
|
||||
loop = main_loop_init(w, h);
|
||||
}
|
||||
return_value_if_fail(loop != NULL, RET_FAIL);
|
||||
#ifdef WITH_SOCKET
|
||||
tk_socket_init();
|
||||
#endif/*WITH_SOCKET*/
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
@ -416,6 +432,10 @@ ret_t tk_deinit_internal(void) {
|
||||
#endif
|
||||
tk_semaphore_destroy(s_clear_cache_semaphore);
|
||||
|
||||
#ifdef WITH_SOCKET
|
||||
tk_socket_deinit();
|
||||
#endif/*WITH_SOCKET*/
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
@ -99,4 +99,24 @@ tk_iostream_t* tk_iostream_mbedtls_create(mbedtls_conn_t* conn) {
|
||||
|
||||
return TK_IOSTREAM(obj);
|
||||
}
|
||||
|
||||
#include "streams/inet/mbedtls_client.h"
|
||||
|
||||
tk_iostream_t* tk_iostream_mbedtls_create_client(const char* host, uint16_t port) {
|
||||
mbedtls_conn_t* conn = NULL;
|
||||
tk_iostream_t* io = NULL;
|
||||
char sport[16] = {0};
|
||||
return_value_if_fail(host != NULL, NULL);
|
||||
|
||||
tk_snprintf(sport, sizeof(sport), "%d", (int)port);
|
||||
conn = mbedtls_conn_client_create(host, sport, NULL, 0);
|
||||
return_value_if_fail(conn != NULL, NULL);
|
||||
|
||||
io = tk_iostream_mbedtls_create(conn);
|
||||
if (io == NULL) {
|
||||
mbedtls_conn_destroy(conn);
|
||||
}
|
||||
|
||||
return io;
|
||||
}
|
||||
#endif /*WITH_MBEDTLS*/
|
||||
|
@ -58,6 +58,19 @@ struct _tk_iostream_mbedtls_t {
|
||||
*/
|
||||
tk_iostream_t* tk_iostream_mbedtls_create(mbedtls_conn_t* conn);
|
||||
|
||||
/**
|
||||
* @method tk_iostream_mbedtls_create_client
|
||||
*
|
||||
* 创建iostream对象。
|
||||
*
|
||||
* @param {const char*} host 主机地址。
|
||||
* @param {uint16_t} port 端口号。
|
||||
*
|
||||
* @return {tk_iostream_t*} 返回iostream对象。
|
||||
*
|
||||
*/
|
||||
tk_iostream_t* tk_iostream_mbedtls_create_client(const char* host, uint16_t port);
|
||||
|
||||
#define TK_IOSTREAM_MBEDTLS(obj) ((tk_iostream_mbedtls_t*)(obj))
|
||||
|
||||
END_C_DECLS
|
||||
|
@ -23,10 +23,13 @@
|
||||
#include "tkc/path.h"
|
||||
#include "tkc/utils.h"
|
||||
#include "tkc/serial_helper.h"
|
||||
#ifdef WITH_SOCKET
|
||||
#ifdef WITH_SOCKET
|
||||
#include "streams/inet/iostream_tcp.h"
|
||||
#include "streams/inet/iostream_udp.h"
|
||||
#endif/*WITH_SOCKET*/
|
||||
#endif /*WITH_SOCKET*/
|
||||
#ifdef WITH_MBEDTLS
|
||||
#include "streams/inet/iostream_mbedtls.h"
|
||||
#endif /*WITH_MBEDTLS*/
|
||||
#include "streams/serial/iostream_serial.h"
|
||||
|
||||
#include "streams/stream_factory.h"
|
||||
@ -39,13 +42,21 @@ tk_iostream_t* tk_stream_factory_create_iostream(const char* url) {
|
||||
return_value_if_fail(aurl != NULL, NULL);
|
||||
|
||||
if (tk_str_start_with(url, STR_SCHEMA_TCP)) {
|
||||
#ifdef WITH_SOCKET
|
||||
#ifdef WITH_SOCKET
|
||||
io = tk_iostream_tcp_create_client(aurl->host, aurl->port);
|
||||
#endif/*WITH_SOCKET*/
|
||||
#endif /*WITH_SOCKET*/
|
||||
} else if (tk_str_start_with(url, STR_SCHEMA_UDP)) {
|
||||
#ifdef WITH_SOCKET
|
||||
#ifdef WITH_SOCKET
|
||||
io = tk_iostream_udp_create_client(aurl->host, aurl->port);
|
||||
#endif/*WITH_SOCKET*/
|
||||
#endif /*WITH_SOCKET*/
|
||||
} else if (tk_str_start_with(url, STR_SCHEMA_HTTP)) {
|
||||
#ifdef WITH_SOCKET
|
||||
io = tk_iostream_tcp_create_client(aurl->host, aurl->port);
|
||||
#endif /*WITH_SOCKET*/
|
||||
} else if (tk_str_start_with(url, STR_SCHEMA_HTTPS)) {
|
||||
#ifdef WITH_MBEDTLS
|
||||
io = tk_iostream_mbedtls_create_client(aurl->host, aurl->port);
|
||||
#endif /*WITH_MBEDTLS*/
|
||||
} else if (tk_str_eq(aurl->schema, "serial")) {
|
||||
char filename[MAX_PATH + 1] = {0};
|
||||
|
||||
|
160
src/tkc/data_reader_http.c
Normal file
160
src/tkc/data_reader_http.c
Normal file
@ -0,0 +1,160 @@
|
||||
/**
|
||||
* File: data_reader.c
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: data_reader
|
||||
*
|
||||
* Copyright (c) 2019 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License http for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2023-12-22 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tkc/mem.h"
|
||||
#include "tkc/url.h"
|
||||
#include "tkc/utils.h"
|
||||
#include "tkc/buffer.h"
|
||||
#include "tkc/data_reader_http.h"
|
||||
#include "streams/stream_factory.h"
|
||||
|
||||
typedef struct _data_reader_http_t {
|
||||
data_reader_t data_reader;
|
||||
|
||||
uint64_t size;
|
||||
uint8_t* data;
|
||||
} data_reader_http_t;
|
||||
|
||||
static const char* url_get_path(const char* url) {
|
||||
const char* p = NULL;
|
||||
return_value_if_fail(url != NULL, NULL);
|
||||
|
||||
p = strstr(url, "://");
|
||||
if (p != NULL) {
|
||||
p += 3;
|
||||
p = strchr(p, '/');
|
||||
if (p == NULL) {
|
||||
p = "/";
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static ret_t data_reader_http_get(data_reader_http_t* http, const char* url) {
|
||||
char buff[1024];
|
||||
int32_t nr = 0;
|
||||
url_t* aurl = NULL;
|
||||
const char* p = NULL;
|
||||
tk_iostream_t* io = NULL;
|
||||
return_value_if_fail(url != NULL && http != NULL, RET_BAD_PARAMS);
|
||||
|
||||
aurl = url_create(url);
|
||||
return_value_if_fail(aurl != NULL, RET_BAD_PARAMS);
|
||||
|
||||
io = tk_stream_factory_create_iostream(url);
|
||||
return_value_if_fail(io != NULL, RET_BAD_PARAMS);
|
||||
|
||||
tk_snprintf(buff, sizeof(buff) - 1, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", url_get_path(url),
|
||||
aurl->host);
|
||||
nr = tk_iostream_write(io, buff, strlen(buff));
|
||||
url_destroy(aurl);
|
||||
goto_error_if_fail(nr > 0);
|
||||
|
||||
nr = tk_iostream_read(io, buff, sizeof(buff) - 1);
|
||||
if (nr > 0) {
|
||||
buff[nr] = '\0';
|
||||
p = strstr(buff, "Content-Length:");
|
||||
goto_error_if_fail(p != NULL);
|
||||
p += strlen("Content-Length:");
|
||||
while (*p == ' ') {
|
||||
p++;
|
||||
}
|
||||
http->size = tk_atoi(p);
|
||||
goto_error_if_fail(http->size > 0);
|
||||
|
||||
http->data = TKMEM_ALLOC(http->size + 1);
|
||||
goto_error_if_fail(http->data != NULL);
|
||||
|
||||
p = strstr(buff, "\r\n\r\n");
|
||||
goto_error_if_fail(p != NULL);
|
||||
|
||||
p += 4;
|
||||
nr = nr - (p - buff);
|
||||
memcpy(http->data, p, nr);
|
||||
|
||||
if (http->size > nr) {
|
||||
nr = tk_iostream_read_len(io, http->data + nr, http->size - nr, TK_ISTREAM_DEFAULT_TIMEOUT);
|
||||
goto_error_if_fail(nr > 0);
|
||||
}
|
||||
|
||||
http->data[http->size] = '\0';
|
||||
}
|
||||
|
||||
TK_OBJECT_UNREF(io);
|
||||
|
||||
return RET_OK;
|
||||
error:
|
||||
TK_OBJECT_UNREF(io);
|
||||
|
||||
return RET_FAIL;
|
||||
}
|
||||
|
||||
static int32_t data_reader_http_read(data_reader_t* reader, uint64_t offset, void* data,
|
||||
uint32_t size) {
|
||||
data_reader_http_t* http = (data_reader_http_t*)reader;
|
||||
return_value_if_fail(http != NULL && data != NULL, 0);
|
||||
return_value_if_fail(offset <= http->size, 0);
|
||||
size = tk_min(size, http->size - offset);
|
||||
|
||||
memcpy(data, http->data + offset, size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static uint64_t data_reader_http_get_size(data_reader_t* reader) {
|
||||
data_reader_http_t* http = (data_reader_http_t*)reader;
|
||||
return_value_if_fail(http != NULL, 0);
|
||||
|
||||
return http->size;
|
||||
}
|
||||
|
||||
static ret_t data_reader_http_destroy(data_reader_t* reader) {
|
||||
data_reader_http_t* http = (data_reader_http_t*)reader;
|
||||
|
||||
TKMEM_FREE(http->data);
|
||||
TKMEM_FREE(http);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static const data_reader_vtable_t s_data_reader_http_vtable = {
|
||||
.read = data_reader_http_read,
|
||||
.get_size = data_reader_http_get_size,
|
||||
.destroy = data_reader_http_destroy,
|
||||
};
|
||||
|
||||
data_reader_t* data_reader_http_create(const char* url) {
|
||||
data_reader_http_t* http = NULL;
|
||||
return_value_if_fail(url != NULL, NULL);
|
||||
http = TKMEM_ZALLOC(data_reader_http_t);
|
||||
return_value_if_fail(http != NULL, NULL);
|
||||
|
||||
if (data_reader_http_get(http, url) != RET_OK) {
|
||||
TKMEM_FREE(http->data);
|
||||
TKMEM_FREE(http);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
http->data_reader.vt = &s_data_reader_http_vtable;
|
||||
|
||||
return (data_reader_t*)http;
|
||||
}
|
55
src/tkc/data_reader_http.h
Normal file
55
src/tkc/data_reader_http.h
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* File: data_reader_http.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: data_reader http
|
||||
*
|
||||
* Copyright (c) 2019 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License http for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2023-12-22 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TK_DATA_READER_HTTP_H
|
||||
#define TK_DATA_READER_HTTP_H
|
||||
|
||||
#include "tkc/data_reader.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class data_reader_http_t
|
||||
* @parent data_reader_t
|
||||
* @annotation ["fake"]
|
||||
* 基于HTTP/HTTPS实现的 data_reader。通过 data_reader_factory 创建 reader 时,URL的格式如下(请用函数data_reader_http_build_url生成):
|
||||
*
|
||||
* ```
|
||||
* http://t.weather.sojson.com/api/weather/city/101030100
|
||||
* https://restapi.amap.com/v3/weather/weatherInfo?city=110101&key=%3C%E7%94%A8%E6%88%B7key%3E
|
||||
* ```
|
||||
*/
|
||||
|
||||
/**
|
||||
* @method data_reader_http_create
|
||||
* 创建基于文件的data reader。
|
||||
* > 不要直接调用,而是注册到 data\_reader\_factory后,通过data\_reader\_factory调用。
|
||||
* @annotation ["constructor"]
|
||||
*
|
||||
* @param {const char*} url URL。
|
||||
*
|
||||
* @return {data_reader_t*} 返回data reader对象。
|
||||
*/
|
||||
data_reader_t* data_reader_http_create(const char* url);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /*TK_DATA_READER_HTTP_H*/
|
33
tests/data_reader_http_test.cc
Normal file
33
tests/data_reader_http_test.cc
Normal file
@ -0,0 +1,33 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "tkc/data_reader_factory.h"
|
||||
#include "tkc/data_reader_http.h"
|
||||
|
||||
TEST(DataReaderHTTP, http) {
|
||||
data_reader_t* reader = data_reader_http_create("http://www.baidu.com");
|
||||
|
||||
if(reader != NULL) {
|
||||
char buffer[1024];
|
||||
uint32_t size = data_reader_get_size(reader);
|
||||
int32_t ret = data_reader_read(reader, 0, buffer, sizeof(buffer));
|
||||
ASSERT_EQ(size > 0, true);
|
||||
ASSERT_EQ(ret, sizeof(buffer));
|
||||
ret = data_reader_read(reader, 0, buffer, sizeof(buffer));
|
||||
data_reader_destroy(reader);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DataReaderHTTP, https) {
|
||||
data_reader_t* reader = data_reader_http_create("https://www.baidu.com");
|
||||
|
||||
if(reader != NULL) {
|
||||
char buffer[1024];
|
||||
uint32_t size = data_reader_get_size(reader);
|
||||
int32_t ret = data_reader_read(reader, 0, buffer, sizeof(buffer));
|
||||
ASSERT_EQ(size > 0, true);
|
||||
ASSERT_EQ(ret, sizeof(buffer));
|
||||
|
||||
ret = data_reader_read(reader, 0, buffer, sizeof(buffer));
|
||||
data_reader_destroy(reader);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user