Просмотр исходного кода

fix never stop, webclient base test need fix

lyon 3 лет назад
Родитель
Сommit
3b8887b45f

+ 4 - 8
examples/requests/requests_encode.py

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

+ 330 - 88
package/requests/_requests.c

@@ -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
-
-PikaObj* _requests_request(PikaObj* self, char* method, char* url) {
-    PikaObj* response = newNormalObj(New__requests_Response);
-    obj_setStr(response, "url", url);
-
-    struct webclient_session* session = RT_NULL;
-    unsigned char* buffer = RT_NULL;
-    int ret = 0;
-    int bytes_read, resp_status;
-    int content_length = -1;
-
-    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;
-    }
-
-    /* create webclient session and set header response size */
-    session = webclient_session_create(GET_HEADER_BUFSZ);
-    if (session == RT_NULL) {
-        ret = -RT_ENOMEM;
-        goto __exit;
-    }
-
-    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;
-        }
-
-        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);
-        }
-        obj_setStr(response, "text", (char*)buffer);
-        goto __exit;
-    }
-
-__exit:
-    if (session) {
-        webclient_close(session);
+/* 标准输出函数 */
+#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__)
+
+/* 补充常见宏定义 */
+#ifndef unlikely
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#endif
+#ifndef likely
+#define likely(x) __builtin_expect(!!(x), 1)
+#endif
+
+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;
+
+    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;
+    }
+
+    timeout = 0;      /* 默认超时时间不限 */
+    this_data = NULL; /* 默认无数据 */
+
+    /**
+     *  现在支持可选的额外参数
+     *      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;
+        }
+        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);
+    }
+    else if (strEqu(method, "GET"))
+    {
+        if (this_data == NULL)
+        {
+            data_len = 0;
+        }
+        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);
+    }
+    else
+    {
+        return -1;
+    }
+
+    return 1;
+}
+
+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 (buffer) {
-        web_free(buffer);
+    /* 写入请求初始内容 */
+    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 (ret != 0) {
-        if (response) {
-            obj_deinit(response);
+    /* 写入请求初始内容 */
+    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;
         }
-        response = NULL;
     }
-    return response;
+    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) {
+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);
+}

+ 15 - 6
package/requests/_requests.pyi

@@ -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): ...

+ 79 - 19
package/requests/requests.py

@@ -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 get(url: str, params=None) -> Response:
-    return request('GET', url, params)
 
+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 __init__():
-    _requests.__init__()
 
-
-def __del__():
-    _requests.__del__()
+def get(url: str, params=None) -> Response:
+    return request('GET', url, params)

+ 184 - 1
package/requests/webclient.c

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

+ 0 - 1
package/requests/webclient.h

@@ -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 - 1
port/linux/only_make.sh

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

+ 9 - 2
port/linux/package/pikascript/_requests.pyi

@@ -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): ...

+ 19 - 38
port/linux/package/pikascript/pikascript-lib/requests/_requests.c

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

+ 23 - 11
port/linux/package/pikascript/requests.py

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