add data_reader_http

This commit is contained in:
lixianjing 2023-12-22 17:55:22 +08:00
parent 267cb72d95
commit 901dd67269
8 changed files with 321 additions and 6 deletions

View File

@ -1,5 +1,8 @@
# 最新动态
2023/12/22
* 增加data\_reader\_http。
2023/12/21
* 增加控件继承的函数指针查找父集的逻辑(感谢智明提供补丁)

View File

@ -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;
}

View File

@ -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*/

View File

@ -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

View File

@ -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
View 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;
}

View 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*/

View 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);
}
}