332 lines
10 KiB
C
Raw Normal View History

#include "_requests.h"
2022-12-11 19:08:52 +08:00
#include "PikaObj.h"
#include <ctype.h>
#include "_requests_Response.h"
2022-11-24 01:21:42 +08:00
#include "webclient.h"
2022-12-11 19:08:52 +08:00
#include "random.h"
#if !PIKASCRIPT_VERSION_REQUIRE_MINIMUN(1, 11, 9)
#error "This library requires PikaScript version 1.11.9 or higher"
#endif
/* 标准输出函数 */
#define RQ_print(fmt, ...) __platform_printf(fmt, ##__VA_ARGS__)
#define RQ_cli(fmt, ...) __platform_printf(fmt, ##__VA_ARGS__)
2022-12-11 19:08:52 +08:00
#define RQ_debug(fmt, ...) {}
/* #define RQ_debug(fmt, ...) __platform_printf("[RQ]:**|"fmt"|**\n", ##__VA_ARGS__) */
#define RQ_error_pointer(...) \
RQ_print("[%s]: Checking NULL pointer of {" #__VA_ARGS__ "}.\n", __fun__)
2022-11-24 01:21:42 +08:00
#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
2022-12-11 19:08:52 +08:00
/**
*
* params: url参数get方法通过url传递数据
* headers:
* data:
* json:
* files:
* timeout:
*
*/
2022-11-24 01:21:42 +08:00
int _requests_Response_request(PikaObj* self,
char* method,
char* url,
pika_float timeout,
char* data) {
size_t data_len, resp_len; /* 长度信息 */
2022-11-24 01:21:42 +08:00
void* resp_data; /* 返回的负载内容 */
int32_t ret; /* 返回值 */
2022-11-24 01:21:42 +08:00
struct webclient_session* session;
2022-12-11 19:08:52 +08:00
session = (struct webclient_session*)obj_getPtr(self, "session_address");
if (unlikely(session == NULL)) {
RQ_cli("Sorry, can not operate NULL session object.\n");
return -1;
}
2022-12-11 19:08:52 +08:00
if (unlikely(url == NULL)) {
RQ_cli("Sorry, please give a specified url.\n");
return -1;
}
2022-12-11 19:08:52 +08:00
RQ_debug("header length:%d", session->header->length);
RQ_debug("header buffer:%.4096s", session->header->buffer);
RQ_debug("header url:%.1024s", url);
/* 进行post或者get操作 */
2022-11-24 01:21:42 +08:00
if (strEqu(method, "GET")) {
/* Get之后header->buffer缓冲区内容会被清空 */
/* FIXME: 保存一下header->buffer内容 */
2022-12-11 19:08:52 +08:00
if (webclient_get2(session, url) != 200) {
return -1;
}
ret = webclient_response(session, &resp_data, &resp_len);
2022-12-11 19:08:52 +08:00
if (ret < 0) {
return -1;
}
/* 正常得到了数据 */
2022-12-11 19:08:52 +08:00
obj_setInt(self, "status_code", session->resp_status);
obj_setInt(self, "content_length", resp_len);
obj_setStr(self, "headers", session->header->buffer);
2022-12-11 19:08:52 +08:00
/* 释放申请的缓冲区内存 */
if (resp_data != NULL) {
obj_setStr(self, "text", (char*)resp_data);
web_free(resp_data);
} else {
obj_setStr(self, "text", "");
}
} else if (strEqu(method, "POST")) {
if (data == NULL) {
data_len = 0;
2022-11-24 01:21:42 +08:00
} else {
2022-12-11 19:08:52 +08:00
data_len = strlen(data);
}
/* FIXME: 默认二进制数据 */
2022-11-24 01:21:42 +08:00
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;
}
}
2022-11-24 01:21:42 +08:00
if (strstr(session->header->buffer, "Content-Type") == RT_NULL) {
/* 二进制数据流 */
2022-11-24 01:21:42 +08:00
ret = webclient_header_fields_add(
session, "Content-Type: application/octet-stream\r\n");
if (ret < 0) {
return -1;
}
}
2022-12-11 19:08:52 +08:00
RQ_debug("header buffer:%.4096s", session->header->buffer);
if (webclient_post(session, url, data, data_len) != 200) {
return -1;
}
ret = webclient_response(session, &resp_data, &resp_len);
2022-12-11 19:08:52 +08:00
if (ret < 0) {
return -1;
}
/* 正常得到了数据 */
2022-12-11 19:08:52 +08:00
obj_setInt(self, "status_code", session->resp_status);
obj_setInt(self, "content_length", resp_len);
obj_setStr(self, "headers", session->header->buffer);
2022-12-11 19:08:52 +08:00
/* 释放申请的缓冲区内存 */
if (resp_data != NULL) {
obj_setStr(self, "text", (char*)resp_data);
web_free(resp_data);
} else {
obj_setStr(self, "text", "");
}
2022-11-24 01:21:42 +08:00
} else {
return -1;
}
return 1;
}
2022-11-24 01:21:42 +08:00
int _requests_Response_header_write(PikaObj* self, char* header, char* value) {
struct webclient_session* session;
2022-12-11 19:08:52 +08:00
session = (struct webclient_session*)obj_getPtr(self, "session_address");
if (unlikely(session == NULL)) {
RQ_cli("Sorry, can not operate NULL session object.\n");
return -1;
}
2022-12-11 19:08:52 +08:00
RQ_debug("Add HTTP fileds:");
/* 写入请求初始内容 */
2022-11-24 01:21:42 +08:00
if (webclient_header_fields_add(session, "%s:%s\r\n", header, value) < 0) {
RQ_cli("Sorry, request header too long.\n");
return -1;
}
2022-12-11 19:08:52 +08:00
RQ_debug("buffer:%p.", session->header->buffer);
return 1;
}
2022-11-24 01:21:42 +08:00
int _requests_Response_proto_write(PikaObj* self, char* proto) {
struct webclient_session* session;
2022-12-11 19:08:52 +08:00
session = (struct webclient_session*)obj_getPtr(self, "session_address");
if (unlikely(session == NULL)) {
RQ_cli("Sorry, can not operate NULL session object.\n");
return -1;
}
2022-12-11 19:08:52 +08:00
/* TODO: 写入协议头之前可以保存 */
RQ_debug("Add proto content:");
/* 写入请求初始内容 */
2022-12-11 19:08:52 +08:00
if (proto != NULL && *proto != 0) {
2022-11-24 01:21:42 +08:00
if (webclient_header_fields_add(session, " %s\r\n", proto) < 0) {
RQ_cli("Sorry, request header too long.\n");
return -1;
}
2022-11-24 01:21:42 +08:00
} else {
if (webclient_header_fields_add(session, " HTTP/1.1\r\n") < 0) {
RQ_cli("Sorry, request header too long.\n");
return -1;
}
}
2022-12-11 19:08:52 +08:00
RQ_debug("buffer:%p.", session->header->buffer);
return 1;
}
2022-11-24 01:21:42 +08:00
char to_hex(char code) {
static char hex[] = "0123456789abcdef";
return hex[code & 15];
}
2022-11-24 01:21:42 +08:00
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;
2022-12-11 19:08:52 +08:00
session = (struct webclient_session*)obj_getPtr(self, "session_address");
if (unlikely(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;
2022-12-11 19:08:52 +08:00
RQ_debug("Add url content:");
RQ_debug("buffer:%p,len:%d.", session->header->buffer, header_length);
RQ_debug("%s%s%s%s", start, s1, connect, s2);
if (*start == 0) {
while(*s1)
{
*p++ = *s1++;
}
goto end;
}
2022-11-24 01:21:42 +08:00
if (start != NULL) {
/* 写入前置符号 */
2022-11-24 01:21:42 +08:00
s = (char*)start;
while (*s) {
*p++ = *s++;
}
}
s = s1;
2022-11-24 01:21:42 +08:00
while (*s) {
if (isalnum(*s) || *s == '-' || *s == '_' || *s == '.' || *s == '~') {
*p++ = *s;
2022-11-24 01:21:42 +08:00
} else if (*s == ' ') {
*p++ = '+';
2022-11-24 01:21:42 +08:00
} else {
*p++ = '%';
*p++ = to_hex(*s >> 4);
*p++ = to_hex(*s & 0xf);
}
s++;
}
2022-11-24 01:21:42 +08:00
if (connect != NULL) {
/* 写入连接符号 */
2022-11-24 01:21:42 +08:00
s = (char*)connect;
while (*s) {
*p++ = *s++;
}
}
2022-11-24 01:21:42 +08:00
s = (char*)s2;
if (s != NULL) {
while (*s) {
if (isalnum(*s) || *s == '-' || *s == '_' || *s == '.' ||
*s == '~') {
*p++ = *s;
2022-11-24 01:21:42 +08:00
} else if (*s == ' ') {
*p++ = '+';
2022-11-24 01:21:42 +08:00
} else {
*p++ = '%';
*p++ = to_hex(*s >> 4);
*p++ = to_hex(*s & 0xf);
}
s++;
}
}
2022-12-11 19:08:52 +08:00
end:
*p = '\0';
length = p - url_address;
length += header_length;
2022-11-24 01:21:42 +08:00
if (length > session->header->size) {
RQ_cli("Error, header buffer has overflowed: {%d}.\n", length);
return -1;
}
/* 更新长度信息 */
session->header->length = length;
2022-12-11 19:08:52 +08:00
RQ_debug("context:%.1024s.", session->header->buffer);
RQ_debug("url length add:%d.", length);
return 1;
}
2022-11-24 01:21:42 +08:00
int _requests_Response_request_init(PikaObj* self, char* method) {
/* 创建会话对象header长度固定 */
2022-11-24 01:21:42 +08:00
struct webclient_session* session;
char* temp;
2022-11-24 01:21:42 +08:00
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);
2022-11-24 01:21:42 +08:00
if (session == RT_NULL) {
RQ_cli("Sorry, memeory is not enough.\n");
2022-12-11 19:08:52 +08:00
obj_setPtr(self, "session_address", NULL);
return -1;
2022-11-24 01:21:42 +08:00
} else {
/* 写入请求初始内容 */
2022-11-24 01:21:42 +08:00
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;
2022-12-11 19:08:52 +08:00
RQ_debug("buffer address:%p.", session->header->buffer);
RQ_debug("url address:%p.", temp);
RQ_debug("headers start:%.10s.", session->header->buffer);
obj_setPtr(self, "url_address", temp);
obj_setPtr(self, "session_address", session);
}
2022-12-11 19:08:52 +08:00
RQ_debug("Response deal session memory.");
return 1;
}
2022-11-24 01:21:42 +08:00
PikaObj* _requests_Response_request_del(PikaObj* self) {
struct webclient_session* session;
2022-12-11 19:08:52 +08:00
session = (struct webclient_session*)obj_getPtr(self, "session_address");
2022-11-24 01:21:42 +08:00
if (session) {
webclient_close(session);
2022-12-11 19:08:52 +08:00
RQ_debug("Response free session memory.");
}
2022-12-11 19:08:52 +08:00
RQ_debug("Response set variables None.");
return NULL;
}
2022-11-24 01:21:42 +08:00
void _requests_Response___del__(PikaObj* self) {
_requests_Response_request_del(self);
2022-12-11 19:08:52 +08:00
RQ_debug("Response class deleted.");
}
2022-11-24 01:21:42 +08:00
void _requests_Response___init__(PikaObj* self) {
/* 初始化 */
2022-11-24 01:21:42 +08:00
obj_setNone(self, "url");
obj_setNone(self, "text");
obj_setNone(self, "headers");
2022-12-11 19:08:52 +08:00
obj_setPtr(self, "session_address", NULL);
RQ_debug("Response class initialized.");
}