mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-15 17:02:53 +08:00
fix never stop, webclient base test need fix
This commit is contained in:
parent
3d773b5709
commit
3b8887b45f
@ -1,10 +1,6 @@
|
||||
import requests
|
||||
requests._append_params_to_url('http://www.rt-thread.com', {
|
||||
'a': 1,
|
||||
'b': 2
|
||||
})
|
||||
|
||||
requests._append_params_to_url('http://www.rt-thread.com', {
|
||||
'a': ' ',
|
||||
'b': '%',
|
||||
})
|
||||
a = requests.request("GET", 'http://www.rt-thread.com')
|
||||
|
||||
print(a.headers)
|
||||
print(a.content)
|
@ -1,116 +1,358 @@
|
||||
#include "_requests.h"
|
||||
#include <ctype.h>
|
||||
#include "_requests_Response.h"
|
||||
#include "webclient.h"
|
||||
#include "_requests_Response.h"
|
||||
|
||||
#define GET_HEADER_BUFSZ 1024
|
||||
#define GET_RESP_BUFSZ 1024
|
||||
/* 标准输出函数 */
|
||||
#define RQ_print(fmt, ...) __platform_printf(fmt, ##__VA_ARGS__)
|
||||
#define RQ_cli(fmt, ...) __platform_printf(fmt, ##__VA_ARGS__)
|
||||
#define RQ_error_pointer(...) \
|
||||
RQ_print("[%s]: Checking NULL pointer of {" #__VA_ARGS__ "}.\n", __fun__)
|
||||
#define RQ_error_value(str, ...) \
|
||||
RQ_print("[%s]: Checking error value of {" #__VA_ARGS__ ":" str "}.\n", __fun__, ##__VA_ARGS__)
|
||||
#define RQ_err(fmt, ...) RQ_print("[%s]:" fmt "\n", __VA_ARGS__)
|
||||
|
||||
PikaObj* _requests_request(PikaObj* self, char* method, char* url) {
|
||||
PikaObj* response = newNormalObj(New__requests_Response);
|
||||
obj_setStr(response, "url", url);
|
||||
/* 补充常见宏定义 */
|
||||
#ifndef unlikely
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
#endif
|
||||
#ifndef likely
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#endif
|
||||
|
||||
struct webclient_session* session = RT_NULL;
|
||||
unsigned char* buffer = RT_NULL;
|
||||
int ret = 0;
|
||||
int bytes_read, resp_status;
|
||||
int content_length = -1;
|
||||
int _requests_Response_request(PikaObj *self, char* method, char* url, pika_float timeout, char* data)
|
||||
{
|
||||
const char *this_url; /* 真实组装之后的url */
|
||||
const char *this_header; /* 填充之后响应头信息 */
|
||||
const void *this_data; /* POST传输的数据 */
|
||||
size_t data_len, resp_len; /* 长度信息 */
|
||||
void *resp_data; /* 返回的负载内容 */
|
||||
int32_t ret; /* 返回值 */
|
||||
struct webclient_session *session;
|
||||
|
||||
buffer = (unsigned char*)web_calloc(1, GET_RESP_BUFSZ);
|
||||
if (buffer == RT_NULL) {
|
||||
rt_kprintf("no memory for receive buffer.\n");
|
||||
ret = -RT_ENOMEM;
|
||||
goto __exit;
|
||||
session = (struct webclient_session *)obj_getInt(self, "session_address");
|
||||
if (session == (void *)-999999999 || session == NULL)
|
||||
{
|
||||
RQ_cli("Sorry, can not operate NULL session object.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create webclient session and set header response size */
|
||||
session = webclient_session_create(GET_HEADER_BUFSZ);
|
||||
if (session == RT_NULL) {
|
||||
ret = -RT_ENOMEM;
|
||||
goto __exit;
|
||||
}
|
||||
timeout = 0; /* 默认超时时间不限 */
|
||||
this_data = NULL; /* 默认无数据 */
|
||||
|
||||
if (strEqu("GET", method)) {
|
||||
resp_status = webclient_get(session, url);
|
||||
obj_setInt(response, "status_code", resp_status);
|
||||
/* send GET request by default header */
|
||||
if (resp_status != 200) {
|
||||
goto __exit;
|
||||
/**
|
||||
* 现在支持可选的额外参数
|
||||
* params: 用于填充url参数,即get方法通过url传递数据
|
||||
* headers: 用于响应头信息填充
|
||||
* data: 负载内容
|
||||
* json: 负载内容
|
||||
* files: 负载内容
|
||||
* timeout: 超时设置
|
||||
* 实际上支持有限
|
||||
*/
|
||||
|
||||
/* 获取超时时间,默认s,最小分辨度ms */
|
||||
timeout = timeout;
|
||||
/* 获取原始字符数据 */
|
||||
this_data = data;
|
||||
|
||||
/* 记录request的url */
|
||||
this_url = url;
|
||||
this_header = obj_getStr(self, "headers");
|
||||
|
||||
/* FIXME */
|
||||
RQ_cli("%s", this_header);
|
||||
|
||||
/* 进行post或者get操作 */
|
||||
if (strEqu(method, "GET"))
|
||||
{
|
||||
/* Get之后,header->buffer缓冲区内容会被清空 */
|
||||
/* FIXME: 保存一下header->buffer内容 */
|
||||
if (webclient_get(session, this_url) != 200)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
content_length = webclient_content_length_get(session);
|
||||
obj_setInt(response, "content_length", content_length);
|
||||
|
||||
if (content_length < 0) {
|
||||
// rt_kprintf("webclient GET request type is chunked.\n");
|
||||
do {
|
||||
bytes_read =
|
||||
webclient_read(session, (void*)buffer, GET_RESP_BUFSZ);
|
||||
if (bytes_read <= 0) {
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
} else {
|
||||
int content_pos = 0;
|
||||
do {
|
||||
bytes_read =
|
||||
webclient_read(session, (void*)buffer,
|
||||
content_length - content_pos > GET_RESP_BUFSZ
|
||||
? GET_RESP_BUFSZ
|
||||
: content_length - content_pos);
|
||||
if (bytes_read <= 0) {
|
||||
break;
|
||||
}
|
||||
content_pos += bytes_read;
|
||||
} while (content_pos < content_length);
|
||||
ret = webclient_response(session, &resp_data, &resp_len);
|
||||
if (ret <= 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
obj_setStr(response, "text", (char*)buffer);
|
||||
goto __exit;
|
||||
/* 正常得到了数据 */
|
||||
obj_setInt(self, "state_code", session->resp_status);
|
||||
obj_setInt(self, "content_length", resp_len);
|
||||
obj_setStr(self, "text", (char *)resp_data);
|
||||
obj_setStr(self, "headers", session->header->buffer);
|
||||
/* FIXME:暂时不保存源url */
|
||||
obj_setStr(self, "url", NULL);
|
||||
}
|
||||
|
||||
__exit:
|
||||
if (session) {
|
||||
webclient_close(session);
|
||||
}
|
||||
|
||||
if (buffer) {
|
||||
web_free(buffer);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
if (response) {
|
||||
obj_deinit(response);
|
||||
else if (strEqu(method, "GET"))
|
||||
{
|
||||
if (this_data == NULL)
|
||||
{
|
||||
data_len = 0;
|
||||
}
|
||||
response = NULL;
|
||||
else
|
||||
{
|
||||
data_len = strlen(this_data);
|
||||
}
|
||||
/* FIXME: 默认二进制数据 */
|
||||
if (strstr(session->header->buffer, "Content-Length") == RT_NULL)
|
||||
{
|
||||
ret = webclient_header_fields_add(session, "Content-Length: %d\r\n", data_len);
|
||||
if (ret < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (strstr(session->header->buffer, "Content-Type") == RT_NULL)
|
||||
{
|
||||
/* 二进制数据流 */
|
||||
ret =
|
||||
webclient_header_fields_add(session, "Content-Type: application/octet-stream\r\n");
|
||||
if (ret < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (webclient_post(session, this_url, this_data, data_len) != 200)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
ret = webclient_response(session, &resp_data, &resp_len);
|
||||
if (ret <= 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
/* 正常得到了数据 */
|
||||
obj_setInt(self, "state_code", session->resp_status);
|
||||
obj_setInt(self, "content_length", resp_len);
|
||||
obj_setStr(self, "text", (char *)resp_data);
|
||||
obj_setStr(self, "headers", session->header->buffer);
|
||||
/* FIXME:暂时不保存源url */
|
||||
obj_setStr(self, "url", NULL);
|
||||
}
|
||||
return response;
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
char to_hex(char code) {
|
||||
int _requests_Response_header_write(PikaObj *self, char *header, char *value)
|
||||
{
|
||||
struct webclient_session *session;
|
||||
|
||||
session = (struct webclient_session *)obj_getInt(self, "session_address");
|
||||
if (session == (void *)-999999999 || session == NULL)
|
||||
{
|
||||
RQ_cli("Sorry, can not operate NULL session object.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 写入请求初始内容 */
|
||||
if (webclient_header_fields_add(session, "%s:%s\r\n", header, value) < 0)
|
||||
{
|
||||
RQ_cli("Sorry, request header too long.\n");
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _requests_Response_proto_write(PikaObj *self, char *proto)
|
||||
{
|
||||
struct webclient_session *session;
|
||||
|
||||
session = (struct webclient_session *)obj_getInt(self, "session_address");
|
||||
if (session == (void *)-999999999 || session == NULL)
|
||||
{
|
||||
RQ_cli("Sorry, can not operate NULL session object.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 写入请求初始内容 */
|
||||
if (proto != NULL && *proto != '\0')
|
||||
{
|
||||
if (webclient_header_fields_add(session, " %s\r\n", proto) < 0)
|
||||
{
|
||||
RQ_cli("Sorry, request header too long.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (webclient_header_fields_add(session, " HTTP/1.1\r\n") < 0)
|
||||
{
|
||||
RQ_cli("Sorry, request header too long.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
char to_hex(char code)
|
||||
{
|
||||
static char hex[] = "0123456789abcdef";
|
||||
return hex[code & 15];
|
||||
}
|
||||
|
||||
char* _requests_urlencode(PikaObj* self, char* s) {
|
||||
obj_setBytes(self, "encodebuff", NULL, strlen(s) * 3 + 1);
|
||||
char* result = (char*)obj_getBytes(self, "encodebuff");
|
||||
char* p = result;
|
||||
while (*s) {
|
||||
if (isalnum(*s) || *s == '-' || *s == '_' || *s == '.' || *s == '~') {
|
||||
int _requests_Response_urlencode_write(PikaObj *self, char* s1, char* s2, char* start, char* connect)
|
||||
{
|
||||
struct webclient_session *session;
|
||||
char *url_address, *p, *s;
|
||||
int32_t length, header_length;
|
||||
|
||||
session = (struct webclient_session *)obj_getInt(self, "session_address");
|
||||
if (session == (void *)-999999999 || session == NULL)
|
||||
{
|
||||
RQ_cli("Sorry, can not operate NULL session object.\n");
|
||||
return -1;
|
||||
}
|
||||
header_length = session->header->length;
|
||||
url_address = session->header->buffer + header_length;
|
||||
p = url_address;
|
||||
|
||||
if (start != NULL)
|
||||
{
|
||||
/* 写入前置符号 */
|
||||
s = (char *)start;
|
||||
while (*s)
|
||||
{
|
||||
*p++ = *s++;
|
||||
}
|
||||
}
|
||||
|
||||
s = s1;
|
||||
while (*s)
|
||||
{
|
||||
if (isalnum(*s) || *s == '-' || *s == '_' || *s == '.' || *s == '~')
|
||||
{
|
||||
*p++ = *s;
|
||||
} else if (*s == ' ') {
|
||||
}
|
||||
else if (*s == ' ')
|
||||
{
|
||||
*p++ = '+';
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
*p++ = '%';
|
||||
*p++ = to_hex(*s >> 4);
|
||||
*p++ = to_hex(*s & 0xf);
|
||||
}
|
||||
s++;
|
||||
}
|
||||
if (connect != NULL)
|
||||
{
|
||||
/* 写入连接符号 */
|
||||
s = (char *)connect;
|
||||
while (*s)
|
||||
{
|
||||
*p++ = *s++;
|
||||
}
|
||||
}
|
||||
s = (char *)s2;
|
||||
if (s != NULL)
|
||||
{
|
||||
while (*s)
|
||||
{
|
||||
if (isalnum(*s) || *s == '-' || *s == '_' || *s == '.' || *s == '~')
|
||||
{
|
||||
*p++ = *s;
|
||||
}
|
||||
else if (*s == ' ')
|
||||
{
|
||||
*p++ = '+';
|
||||
}
|
||||
else
|
||||
{
|
||||
*p++ = '%';
|
||||
*p++ = to_hex(*s >> 4);
|
||||
*p++ = to_hex(*s & 0xf);
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
return result;
|
||||
|
||||
length = p - url_address;
|
||||
length += header_length;
|
||||
if (length > session->header->size)
|
||||
{
|
||||
RQ_cli("Error, header buffer has overflowed: {%d}.\n", length);
|
||||
return -1;
|
||||
}
|
||||
/* 更新长度信息 */
|
||||
session->header->length = length;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void _requests___del__(PikaObj* self) {}
|
||||
int _requests_Response_request_init(PikaObj *self, char *method)
|
||||
{
|
||||
/* 创建会话对象,header长度固定 */
|
||||
struct webclient_session *session;
|
||||
char *temp;
|
||||
|
||||
void _requests___init__(PikaObj* self) {}
|
||||
if (unlikely((strEqu(method, "GET") || strEqu(method, "POST")) == 0))
|
||||
{
|
||||
/* 目前仅支持两种方法 */
|
||||
RQ_cli("Sorry, now only support method: GET and POST.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
session = webclient_session_create(WEBCLIENT_HEADER_BUFSZ);
|
||||
if (session == RT_NULL)
|
||||
{
|
||||
RQ_cli("Sorry, memeory is not enough.\n");
|
||||
obj_setInt(self, "session_address", 0);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 写入请求初始内容 */
|
||||
if (webclient_header_fields_add(session, "%s ", method) < 0)
|
||||
{
|
||||
_requests_Response_request_del(self);
|
||||
RQ_cli("Sorry, request header too long.\n");
|
||||
return -1;
|
||||
}
|
||||
temp = session->header->buffer + session->header->length;
|
||||
obj_setStr(self, "url", temp);
|
||||
obj_setStr(self, "headers", session->header->buffer);
|
||||
obj_setInt(self, "session_address", (int64_t)session);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
PikaObj *_requests_Response_request_del(PikaObj *self)
|
||||
{
|
||||
struct webclient_session *session;
|
||||
session = (struct webclient_session *)obj_getInt(self, "session_address");
|
||||
if (session == (void *)-999999999)
|
||||
{
|
||||
session = NULL;
|
||||
}
|
||||
if (session)
|
||||
{
|
||||
webclient_close(session);
|
||||
}
|
||||
/* 初始化 */
|
||||
obj_setStr(self, "url", NULL);
|
||||
obj_setStr(self, "text", NULL);
|
||||
obj_setStr(self, "headers", NULL);
|
||||
obj_setInt(self, "session_address", 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void _requests_Response___del__(PikaObj *self)
|
||||
{
|
||||
_requests_Response_request_del(self);
|
||||
}
|
||||
|
||||
void _requests_Response___init__(PikaObj *self)
|
||||
{
|
||||
/* 初始化 */
|
||||
obj_setStr(self, "url", NULL);
|
||||
obj_setStr(self, "text", NULL);
|
||||
obj_setStr(self, "headers", NULL);
|
||||
obj_setInt(self, "session_address", 0);
|
||||
}
|
||||
|
@ -2,16 +2,25 @@ class Response:
|
||||
content_length: int
|
||||
text: str
|
||||
state_code: int
|
||||
headers: dict
|
||||
headers: str
|
||||
url: str
|
||||
session_address: int
|
||||
|
||||
def json(self) -> dict: ...
|
||||
|
||||
def request(self,
|
||||
method: str,
|
||||
url: str,
|
||||
timeout: float,
|
||||
data: str) -> int: ...
|
||||
|
||||
def request(method: str, url: str) -> Response: ...
|
||||
def request_init(self, method: str) -> int: ...
|
||||
def request_del(self) -> None: ...
|
||||
def proto_write(self, proto: str) -> int: ...
|
||||
def urlencode_write(self, s1: str, s2: str, start: str,
|
||||
connect: str) -> int: ...
|
||||
|
||||
def urlencode(s: str) -> str: ...
|
||||
def header_write(self, header: str, value: str) -> int: ...
|
||||
|
||||
|
||||
def __init__(): ...
|
||||
def __del__(): ...
|
||||
def __init__(self): ...
|
||||
def __del__(self): ...
|
||||
|
@ -2,35 +2,95 @@ import _requests
|
||||
|
||||
|
||||
class Response(_requests.Response):
|
||||
...
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def __del__(self):
|
||||
super().__del__()
|
||||
|
||||
|
||||
def _append_params_to_url(url: str, params: dict) -> str:
|
||||
def _append_params_to_url(rqst: Response, url: str, params: dict) -> int:
|
||||
if params is None:
|
||||
return url
|
||||
ret = rqst.urlencode_write(url, '\0', '\0', '\0')
|
||||
return 1
|
||||
if '?' in url:
|
||||
url += '&'
|
||||
first_connect = '&'
|
||||
|
||||
else:
|
||||
url += '?'
|
||||
first_connect = '?'
|
||||
# 初始化连接url
|
||||
ret = rqst.urlencode_write(url, '\0', '\0', '\0')
|
||||
if ret != 1:
|
||||
return ret
|
||||
count = 0
|
||||
connect = '='
|
||||
start = '&'
|
||||
for k, v in params.items():
|
||||
k = _requests.urlencode(str(k))
|
||||
v = _requests.urlencode(str(v))
|
||||
url += '%s=%s&' % (k, v)
|
||||
return url[:-1]
|
||||
if count == 0:
|
||||
ret = rqst.urlencode_write(str(k), str(v), first_connect, connect)
|
||||
if ret != 1:
|
||||
return ret
|
||||
count += 1
|
||||
else:
|
||||
ret = rqst.urlencode_write(str(k), str(v), start, connect)
|
||||
if ret != 1:
|
||||
return ret
|
||||
return 1
|
||||
|
||||
|
||||
def request(method: str, url: str, params=None) -> Response:
|
||||
url = _append_params_to_url(url, params)
|
||||
return _requests.request(method, url)
|
||||
def _append_headers(rqst: Response, headers: dict) -> int:
|
||||
if headers is None:
|
||||
return 1
|
||||
for k, v in headers.items():
|
||||
ret = rqst.header_write(str(k), str(v))
|
||||
if ret != 1:
|
||||
return ret
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
def request(
|
||||
method: str,
|
||||
url: str,
|
||||
params=None,
|
||||
headers=None,
|
||||
timeout=0.0,
|
||||
files=None,
|
||||
json=None,
|
||||
data=None) -> Response:
|
||||
if files != None:
|
||||
print("files is not supported")
|
||||
return None
|
||||
if json != None:
|
||||
print("json is not supported")
|
||||
return None
|
||||
"""
|
||||
初始化请求对象,分配内存和固定请求头
|
||||
"""
|
||||
rqst = Response()
|
||||
# 初始化,分配内存, 写入方法POST/GET
|
||||
ret = rqst.request_init(method)
|
||||
if ret != 1:
|
||||
return None
|
||||
# 写入URL
|
||||
ret = _append_params_to_url(rqst, url, params)
|
||||
if ret != 1:
|
||||
# 出现错误,需要释放对象
|
||||
return None
|
||||
# 写入默认HTTP版本号
|
||||
ret = rqst.proto_write('\0')
|
||||
if ret != 1:
|
||||
return None
|
||||
# 写入响应头数据
|
||||
ret = _append_headers(rqst, headers)
|
||||
if ret != 1:
|
||||
return None
|
||||
# 进行实际request过程
|
||||
ret = rqst.request(method, url, timeout, data)
|
||||
if ret != 1:
|
||||
return None
|
||||
return rqst
|
||||
|
||||
|
||||
def get(url: str, params=None) -> Response:
|
||||
return request('GET', url, params)
|
||||
|
||||
|
||||
def __init__():
|
||||
_requests.__init__()
|
||||
|
||||
|
||||
def __del__():
|
||||
_requests.__del__()
|
||||
|
@ -468,6 +468,7 @@ __exit:
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME: userful func
|
||||
* add fields data to request header data.
|
||||
*
|
||||
* @param session webclient session
|
||||
@ -577,7 +578,7 @@ int webclient_content_length_get(struct webclient_session* session) {
|
||||
return session->content_length;
|
||||
}
|
||||
|
||||
static int webclient_send_header(struct webclient_session* session,
|
||||
static int webclient_send_header2(struct webclient_session* session,
|
||||
int method) {
|
||||
int rc = WEBCLIENT_OK;
|
||||
char* header = RT_NULL;
|
||||
@ -701,6 +702,54 @@ __exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* FIXME: 定制版发送响应头 */
|
||||
static int webclient_send_header(struct webclient_session* session,
|
||||
int method) {
|
||||
int rc = WEBCLIENT_OK;
|
||||
char* header = RT_NULL;
|
||||
|
||||
RT_ASSERT(session);
|
||||
|
||||
header = session->header->buffer;
|
||||
|
||||
if (strstr(header, "Host:") == RT_NULL) {
|
||||
if (webclient_header_fields_add(session, "Host: %s\r\n",
|
||||
session->host) < 0)
|
||||
return -WEBCLIENT_NOMEM;
|
||||
}
|
||||
|
||||
if (strstr(header, "User-Agent:") == RT_NULL) {
|
||||
if (webclient_header_fields_add(
|
||||
session, "User-Agent: PikaScript HTTP Agent\r\n") < 0)
|
||||
return -WEBCLIENT_NOMEM;
|
||||
}
|
||||
|
||||
if (strstr(header, "Accept:") == RT_NULL) {
|
||||
if (webclient_header_fields_add(session, "Accept: */*\r\n") < 0)
|
||||
return -WEBCLIENT_NOMEM;
|
||||
}
|
||||
|
||||
/* header data end */
|
||||
web_snprintf(session->header->buffer + session->header->length,
|
||||
session->header->size - session->header->length,
|
||||
"\r\n");
|
||||
session->header->length += 2;
|
||||
|
||||
/* check header size */
|
||||
if (session->header->length > session->header->size) {
|
||||
LOG_E("send header failed, not enough header buffer size(%d)!",
|
||||
session->header->size);
|
||||
rc = -WEBCLIENT_NOBUFFER;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
webclient_write(session, (unsigned char*)session->header->buffer,
|
||||
session->header->length);
|
||||
|
||||
__exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* resolve server response data.
|
||||
*
|
||||
@ -811,6 +860,7 @@ int webclient_handle_response(struct webclient_session* session) {
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME: userful func
|
||||
* create webclient session, set maximum header and response size
|
||||
*
|
||||
* @param header_sz maximum send header size
|
||||
@ -1726,3 +1776,136 @@ __exit:
|
||||
|
||||
return totle_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Better interface.
|
||||
* send request(GET/POST) to server and get response data.
|
||||
*
|
||||
* @param URI input server address
|
||||
* @param header send header data
|
||||
* = NULL: use default header data, must be GET request
|
||||
* != NULL: user custom header data, GET or POST request
|
||||
* @param post_data data sent to the server
|
||||
* = NULL: it is GET request
|
||||
* != NULL: it is POST request
|
||||
* @param data_len send data length
|
||||
* @param response response buffer address
|
||||
* @param resp_len response buffer length
|
||||
*
|
||||
* @return <0: request failed
|
||||
* >=0: response buffer size
|
||||
*/
|
||||
int webclient_request2(
|
||||
struct webclient_session* session,
|
||||
const char* URI,
|
||||
const char* header,
|
||||
const void* post_data,
|
||||
size_t data_len,
|
||||
double timeout,
|
||||
void** response,
|
||||
size_t* resp_len) {
|
||||
int rc = WEBCLIENT_OK;
|
||||
int totle_length = 0;
|
||||
|
||||
if (post_data == RT_NULL && response == RT_NULL) {
|
||||
LOG_E("request get failed, get response data cannot be empty.");
|
||||
return -WEBCLIENT_ERROR;
|
||||
}
|
||||
|
||||
if ((post_data != RT_NULL) && (data_len == 0)) {
|
||||
LOG_E("input post data length failed");
|
||||
return -WEBCLIENT_ERROR;
|
||||
}
|
||||
|
||||
if ((response != RT_NULL && resp_len == RT_NULL) ||
|
||||
(response == RT_NULL && resp_len != RT_NULL)) {
|
||||
LOG_E("input response data or length failed");
|
||||
return -WEBCLIENT_ERROR;
|
||||
}
|
||||
|
||||
if (post_data == RT_NULL) {
|
||||
/* send get request */
|
||||
session = webclient_session_create(WEBCLIENT_HEADER_BUFSZ);
|
||||
if (session == RT_NULL) {
|
||||
rc = -WEBCLIENT_NOMEM;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (header != RT_NULL) {
|
||||
char *header_str, *header_ptr;
|
||||
int header_line_length;
|
||||
|
||||
for (header_str = (char*)header;
|
||||
(header_ptr = strstr(header_str, "\r\n")) != RT_NULL;) {
|
||||
header_line_length = header_ptr + strlen("\r\n") - header_str;
|
||||
webclient_header_fields_add(session, "%.*s", header_line_length,
|
||||
header_str);
|
||||
header_str += header_line_length;
|
||||
}
|
||||
}
|
||||
|
||||
if (webclient_get(session, URI) != 200) {
|
||||
rc = -WEBCLIENT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
totle_length = webclient_response(session, response, resp_len);
|
||||
if (totle_length <= 0) {
|
||||
rc = -WEBCLIENT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
} else {
|
||||
/* send post request */
|
||||
session = webclient_session_create(WEBCLIENT_HEADER_BUFSZ);
|
||||
if (session == RT_NULL) {
|
||||
rc = -WEBCLIENT_NOMEM;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (header != RT_NULL) {
|
||||
char *header_str, *header_ptr;
|
||||
int header_line_length;
|
||||
|
||||
for (header_str = (char*)header;
|
||||
(header_ptr = strstr(header_str, "\r\n")) != RT_NULL;) {
|
||||
header_line_length = header_ptr + strlen("\r\n") - header_str;
|
||||
webclient_header_fields_add(session, "%.*s", header_line_length,
|
||||
header_str);
|
||||
header_str += header_line_length;
|
||||
}
|
||||
}
|
||||
|
||||
if (strstr(session->header->buffer, "Content-Length") == RT_NULL) {
|
||||
webclient_header_fields_add(session, "Content-Length: %d\r\n",
|
||||
strlen(post_data));
|
||||
}
|
||||
|
||||
if (strstr(session->header->buffer, "Content-Type") == RT_NULL) {
|
||||
webclient_header_fields_add(
|
||||
session, "Content-Type: application/octet-stream\r\n");
|
||||
}
|
||||
|
||||
if (webclient_post(session, URI, post_data, data_len) != 200) {
|
||||
rc = -WEBCLIENT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
totle_length = webclient_response(session, response, resp_len);
|
||||
if (totle_length <= 0) {
|
||||
rc = -WEBCLIENT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
}
|
||||
|
||||
__exit:
|
||||
if (session) {
|
||||
webclient_close(session);
|
||||
session = RT_NULL;
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return totle_length;
|
||||
}
|
||||
|
@ -106,7 +106,6 @@ enum WEBCLIENT_METHOD {
|
||||
struct webclient_header {
|
||||
char* buffer;
|
||||
size_t length; /* content header buffer size */
|
||||
|
||||
size_t size; /* maximum support header size */
|
||||
};
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
cd build && rm ./test/pikascript_test -f && ninja -j3
|
||||
cd build && rm ./test/pikascript_test -f && ninja -j0
|
||||
cd .. && cp ./build/boot/demo06-pikamain/pikascript_demo06-pikamain package/pikascript/pika
|
||||
|
@ -8,11 +8,18 @@ class Response:
|
||||
|
||||
def json(self) -> dict: ...
|
||||
|
||||
def request(self, method: str, **kwargs) -> int: ...
|
||||
def request(self,
|
||||
method: str,
|
||||
url: str,
|
||||
timeout: float,
|
||||
data: str) -> int: ...
|
||||
|
||||
def request_init(self, method: str) -> int: ...
|
||||
def request_del(self) -> None: ...
|
||||
def proto_write(self, proto: str) -> int: ...
|
||||
def urlencode_write(self, s1: str, s2: str, start: str , connect: str) -> int: ...
|
||||
def urlencode_write(self, s1: str, s2: str, start: str,
|
||||
connect: str) -> int: ...
|
||||
|
||||
def header_write(self, header: str, value: str) -> int: ...
|
||||
|
||||
def __init__(self): ...
|
||||
|
@ -20,7 +20,7 @@
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#endif
|
||||
|
||||
int _requests_Response_request(PikaObj *self, char *method, PikaDict *kwargs)
|
||||
int _requests_Response_request(PikaObj *self, char* method, char* url, pika_float timeout, char* data)
|
||||
{
|
||||
const char *this_url; /* 真实组装之后的url */
|
||||
const char *this_header; /* 填充之后响应头信息 */
|
||||
@ -28,7 +28,6 @@ int _requests_Response_request(PikaObj *self, char *method, PikaDict *kwargs)
|
||||
size_t data_len, resp_len; /* 长度信息 */
|
||||
void *resp_data; /* 返回的负载内容 */
|
||||
int32_t ret; /* 返回值 */
|
||||
double timeout; /* 超时时间 */
|
||||
struct webclient_session *session;
|
||||
|
||||
session = (struct webclient_session *)obj_getInt(self, "session_address");
|
||||
@ -41,44 +40,26 @@ int _requests_Response_request(PikaObj *self, char *method, PikaDict *kwargs)
|
||||
timeout = 0; /* 默认超时时间不限 */
|
||||
this_data = NULL; /* 默认无数据 */
|
||||
|
||||
if (kwargs != NULL)
|
||||
{
|
||||
/**
|
||||
* 现在支持可选的额外参数
|
||||
* params: 用于填充url参数,即get方法通过url传递数据
|
||||
* headers: 用于响应头信息填充
|
||||
* data: 负载内容
|
||||
* json: 负载内容
|
||||
* files: 负载内容
|
||||
* timeout: 超时设置
|
||||
* 实际上支持有限
|
||||
*/
|
||||
if (args_isArgExist((Args *)kwargs, "timeout"))
|
||||
{
|
||||
/* 获取超时时间,默认s,最小分辨度ms */
|
||||
timeout = pikaDict_getFloat(kwargs, "timeout");
|
||||
}
|
||||
if (args_isArgExist((Args *)kwargs, "files"))
|
||||
{
|
||||
/* 获取文件 */
|
||||
RQ_cli("Sorry, now don't support transport files.\n");
|
||||
return -1;
|
||||
}
|
||||
if (args_isArgExist((Args *)kwargs, "json"))
|
||||
{
|
||||
/* 获取JSON字符 */
|
||||
RQ_cli("Sorry, now don't support JSON.\n");
|
||||
return -1;
|
||||
}
|
||||
if (args_isArgExist((Args *)kwargs, "data"))
|
||||
{
|
||||
/* 获取原始字符数据 */
|
||||
this_data = pikaDict_getStr(kwargs, "data");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 现在支持可选的额外参数
|
||||
* params: 用于填充url参数,即get方法通过url传递数据
|
||||
* headers: 用于响应头信息填充
|
||||
* data: 负载内容
|
||||
* json: 负载内容
|
||||
* files: 负载内容
|
||||
* timeout: 超时设置
|
||||
* 实际上支持有限
|
||||
*/
|
||||
|
||||
/* 获取超时时间,默认s,最小分辨度ms */
|
||||
timeout = timeout;
|
||||
/* 获取原始字符数据 */
|
||||
this_data = data;
|
||||
|
||||
/* 记录request的url */
|
||||
this_url = obj_getStr(self, "url");
|
||||
this_url = url;
|
||||
this_header = obj_getStr(self, "headers");
|
||||
|
||||
/* FIXME */
|
||||
RQ_cli("%s", this_header);
|
||||
|
||||
|
@ -30,24 +30,40 @@ def _append_params_to_url(rqst: Response, url: str, params: dict) -> int:
|
||||
ret = rqst.urlencode_write(str(k), str(v), first_connect, connect)
|
||||
if ret != 1:
|
||||
return ret
|
||||
count+=1
|
||||
count += 1
|
||||
else:
|
||||
ret = rqst.urlencode_write(str(k), str(v), start, connect)
|
||||
if ret != 1:
|
||||
return ret
|
||||
return 1
|
||||
|
||||
|
||||
def _append_headers(rqst: Response, headers: dict) -> int:
|
||||
if headers is None:
|
||||
return
|
||||
return 1
|
||||
for k, v in headers.items():
|
||||
ret = rqst.header_write(str(k), str(v))
|
||||
if ret != 1:
|
||||
return ret
|
||||
|
||||
|
||||
return 1
|
||||
|
||||
def request(method: str, url: str, params=None, headers=None, **kwargs) -> Response:
|
||||
|
||||
def request(
|
||||
method: str,
|
||||
url: str,
|
||||
params=None,
|
||||
headers=None,
|
||||
timeout=0.0,
|
||||
files=None,
|
||||
json=None,
|
||||
data=None) -> Response:
|
||||
if files != None:
|
||||
print("files is not supported")
|
||||
return None
|
||||
if json != None:
|
||||
print("json is not supported")
|
||||
return None
|
||||
"""
|
||||
初始化请求对象,分配内存和固定请求头
|
||||
"""
|
||||
@ -55,30 +71,26 @@ def request(method: str, url: str, params=None, headers=None, **kwargs) -> Respo
|
||||
# 初始化,分配内存, 写入方法POST/GET
|
||||
ret = rqst.request_init(method)
|
||||
if ret != 1:
|
||||
del rqst
|
||||
return None
|
||||
# 写入URL
|
||||
ret = _append_params_to_url(rqst, url, params)
|
||||
if ret != 1:
|
||||
if ret != 1:
|
||||
# 出现错误,需要释放对象
|
||||
del rqst
|
||||
return None
|
||||
# 写入默认HTTP版本号
|
||||
ret = rqst.proto_write('\0')
|
||||
if ret != 1:
|
||||
del rqst
|
||||
return None
|
||||
# 写入响应头数据
|
||||
ret = _append_headers(rqst, headers)
|
||||
if ret != 1:
|
||||
del rqst
|
||||
return None
|
||||
# 进行实际request过程
|
||||
ret = rqst.request(kwargs)
|
||||
ret = rqst.request(method, url, timeout, data)
|
||||
if ret != 1:
|
||||
del rqst
|
||||
return None
|
||||
return rqst
|
||||
|
||||
|
||||
def get(url: str, params=None) -> Response:
|
||||
return request('GET', url, params)
|
||||
|
Loading…
x
Reference in New Issue
Block a user