From bbf34d35935d666108a8b015351da1b8a8c38359 Mon Sep 17 00:00:00 2001 From: chenyong Date: Tue, 31 Dec 2019 12:03:08 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E6=B7=BB=E5=8A=A0=E3=80=91=E6=8E=A5?= =?UTF-8?q?=E6=94=B6=E5=92=8C=E5=8F=91=E9=80=81=E9=9D=9E=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E4=B8=B2=E6=A0=BC=E5=BC=8F=E6=95=B0=E6=8D=AE=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=94=AF=E6=8C=81=EF=BC=8C=E6=9B=B4=E6=96=B0=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=92=8C=E6=96=87=E6=A1=A3=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/api.md | 14 ++++++--- docs/migration-guide.md | 2 +- docs/user-guide.md | 12 ++++--- inc/webclient.h | 12 +++---- samples/webclient_get_sample.c | 17 +++++----- samples/webclient_post_sample.c | 30 +++++++++--------- src/webclient.c | 56 +++++++++++++++++++++++---------- src/webclient_file.c | 2 +- 8 files changed, 89 insertions(+), 56 deletions(-) diff --git a/docs/api.md b/docs/api.md index 5cfcfcc..f722a50 100644 --- a/docs/api.md +++ b/docs/api.md @@ -66,7 +66,7 @@ int webclient_get_position(struct webclient_session *session, const char *URI, i ## 发送 POST 请求 ```c -int webclient_post(struct webclient_session *session, const char *URI, const char *post_data); +int webclient_post(struct webclient_session *session, const char *URI, const void *post_data, size_t data_len); ``` 发送 HTTP POST 请求命令,上传数据到 HTTP 服务器。 @@ -76,6 +76,7 @@ int webclient_post(struct webclient_session *session, const char *URI, const cha |session | 当前连接会话结构体指针 | |URI | 连接的 HTTP 服务器地址 | |post_data | 需要上传的数据地址 | +|data_len | 需要上传数据的长度 | | **返回** | **描述** | |`>0` | HTTP 响应状态码 | |<0 | 发送请求失败 | @@ -83,7 +84,7 @@ int webclient_post(struct webclient_session *session, const char *URI, const cha ## 发送数据 ```c -int webclient_write(struct webclient_session *session, const unsigned char *buffer, size_t size); +int webclient_write(struct webclient_session *session, const void *buffer, size_t size); ``` 发送数据到连接的服务器。 @@ -101,7 +102,7 @@ int webclient_write(struct webclient_session *session, const unsigned char *buff ## 接收数据 ```c -int webclient_read(struct webclient_session *session, unsigned char *buffer, size_t size); +int webclient_read(struct webclient_session *session, void *buffer, size_t size); ``` 从连接的服务器接收数据。 @@ -169,7 +170,7 @@ const char *webclient_header_fields_get(struct webclient_session *session, const ## 接收响应数据到指定地址 ```c -int webclient_response(struct webclient_session *session, unsigned char **response); +int webclient_response(struct webclient_session *session, void **response, size_t *resp_len); ``` 该函数用于发送 GET 或 POST 请求之后, 可以接收响应数据到指定地址。 @@ -178,6 +179,7 @@ int webclient_response(struct webclient_session *session, unsigned char **respon |:------------------|:-----------------------------------| |session | 当前连接会话结构体指针 | |response | 存放接收数据的字符串地址 | +|resp_len | 接收数据的长度的指针 | | **返回** | **描述** | | `>0` | 成功接收数据的长度 | | <=0 | 接收数据失败 | @@ -185,7 +187,7 @@ int webclient_response(struct webclient_session *session, unsigned char **respon ## 发送 GET/POST 请求并接收响应数据 ```c -int webclient_request(const char *URI, const char *header, const char *post_data, unsigned char **response); +int webclient_request(const char *URI, const char *header, const void *post_data, size_t data_len, void **response, size_t *resp_len); ``` | 参数 | 描述 | @@ -197,7 +199,9 @@ int webclient_request(const char *URI, const char *header, const char *post_data |post_data | 发送到服务器的数据 | | | = NULL,该发送请求为 GET 请求 | | | != NULL,该发送请求为 POST 请求 | +| data_len | 发送数据的长度 | |response | 存放接收数据的字符串地址 | +|resp_len | 接收数据长度的指针 | | **返回** | **描述** | | `>0` | 成功接收数据的长度 | | <=0 | 接收数据失败 | diff --git a/docs/migration-guide.md b/docs/migration-guide.md index 31bc31d..1c1f7f8 100644 --- a/docs/migration-guide.md +++ b/docs/migration-guide.md @@ -143,7 +143,7 @@ session = webclient_session_create(1024) webclient_header_fields_add(session, "Content-Length: %s", post_data_sz); -webclient_post(session, URI, post_data); +webclient_post(session, URI, post_data, rt_strlen(post_data)); webclient_close(session); ``` diff --git a/docs/user-guide.md b/docs/user-guide.md index d00980c..e8d90f2 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -256,6 +256,7 @@ webclient_close(session); ```c struct webclient_session *session = NULL; +size_t length = 0; char *result; session = webclient_create(1024); @@ -265,7 +266,7 @@ if(webclient_get(session, URI) != 200) LOG_E("error!"); } -webclient_response(session, &result); +webclient_response(session, &result, &length); web_free(result); webclient_close(session); @@ -276,12 +277,13 @@ webclient_close(session); 多用于接收数据长度较小,且头部信息已经拼接给出的 GET 请求。 ```c +size_t length = 0; char *result, *header = RT_NULL; /* 拼接自定义头部数据 */ webclient_request_header_add(&header, "User-Agent: RT-Thread HTTP Agent\r\n"); -webclient_request(URI, header, NULL, &result); +webclient_request(URI, header, NULL, 0, &result, &length); web_free(result); ``` @@ -302,7 +304,7 @@ webclient_header_fields_add(session, "Content-Length: %d\r\n", post_data_sz); webclient_header_fields_add(session, "Content-Type: application/octet-stream\r\n"); /* 分段数据上传 webclient_post 第三个传输上传数据为 NULL,改为下面循环上传数据*/ -if( webclient_post(session, URI, NULL) != 200) +if( webclient_post(session, URI, NULL, 0) != 200) { LOG_E("error!"); } @@ -334,7 +336,7 @@ session = webclient_create(1024); webclient_header_fields_add(session, "Content-Length: %d\r\n", strlen(post_data)); webclient_header_fields_add(session, "Content-Type: application/octet-stream\r\n"); -if(webclient_post(session, URI, post_data) != 200); +if(webclient_post(session, URI, post_data, rt_strlen(post_data)) != 200); { LOG_E("error!"); } @@ -353,7 +355,7 @@ char *header = RT_NULL; webclient_request_header_add(&header, "Content-Length: %d\r\n", strlen(post_data)); webclient_request_header_add(&header, "Content-Type: application/octet-stream\r\n"); -webclient_request(URI, header, post_data, NULL); +webclient_request(URI, header, post_data, rt_strlen(post_data), NULL, NULL); ``` ## 常见问题 diff --git a/inc/webclient.h b/inc/webclient.h index b4ea163..018bd24 100644 --- a/inc/webclient.h +++ b/inc/webclient.h @@ -25,7 +25,7 @@ #ifdef __cplusplus extern "C" { -#endif +#endif #ifndef web_malloc #define web_malloc rt_malloc @@ -110,7 +110,7 @@ int webclient_get(struct webclient_session *session, const char *URI); int webclient_get_position(struct webclient_session *session, const char *URI, int position); /* send HTTP POST request */ -int webclient_post(struct webclient_session *session, const char *URI, const char *post_data); +int webclient_post(struct webclient_session *session, const char *URI, const void *post_data, size_t data_len); /* close and release wenclient session */ int webclient_close(struct webclient_session *session); @@ -118,16 +118,16 @@ int webclient_close(struct webclient_session *session); int webclient_set_timeout(struct webclient_session *session, int millisecond); /* send or receive data from server */ -int webclient_read(struct webclient_session *session, unsigned char *buffer, size_t size); -int webclient_write(struct webclient_session *session, const unsigned char *buffer, size_t size); +int webclient_read(struct webclient_session *session, void *buffer, size_t size); +int webclient_write(struct webclient_session *session, const void *buffer, size_t size); /* webclient GET/POST header buffer operate by the header fields */ int webclient_header_fields_add(struct webclient_session *session, const char *fmt, ...); const char *webclient_header_fields_get(struct webclient_session *session, const char *fields); /* send HTTP POST/GET request, and get response data */ -int webclient_response(struct webclient_session *session, unsigned char **response); -int webclient_request(const char *URI, const char *header, const char *post_data, unsigned char **response); +int webclient_response(struct webclient_session *session, void **response, size_t *resp_len); +int webclient_request(const char *URI, const char *header, const void *post_data, size_t data_len, void **response, size_t *resp_len); int webclient_request_header_add(char **request_header, const char *fmt, ...); int webclient_resp_status_get(struct webclient_session *session); int webclient_content_length_get(struct webclient_session *session); diff --git a/samples/webclient_get_sample.c b/samples/webclient_get_sample.c index 4697e97..8185229 100644 --- a/samples/webclient_get_sample.c +++ b/samples/webclient_get_sample.c @@ -58,7 +58,7 @@ static int webclient_get_comm(const char *uri) rt_kprintf("webclient GET request type is chunked.\n"); do { - bytes_read = webclient_read(session, buffer, GET_RESP_BUFSZ); + bytes_read = webclient_read(session, (void *)buffer, GET_RESP_BUFSZ); if (bytes_read <= 0) { break; @@ -78,7 +78,7 @@ static int webclient_get_comm(const char *uri) do { - bytes_read = webclient_read(session, buffer, + 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) @@ -114,10 +114,11 @@ __exit: /* send HTTP GET request by simplify request interface, it used to received shorter data */ static int webclient_get_smpl(const char *uri) { - char *request = RT_NULL; + char *response = RT_NULL; + size_t resp_len = 0; int index; - if (webclient_request(uri, RT_NULL, RT_NULL, (unsigned char **)&request) < 0) + if (webclient_request(uri, RT_NULL, RT_NULL, 0, (void **)&response, &resp_len) < 0) { rt_kprintf("webclient send get request failed."); return -RT_ERROR; @@ -125,15 +126,15 @@ static int webclient_get_smpl(const char *uri) rt_kprintf("webclient send get request by simplify request interface.\n"); rt_kprintf("webclient get response data: \n"); - for (index = 0; index < rt_strlen(request); index++) + for (index = 0; index < rt_strlen(response); index++) { - rt_kprintf("%c", request[index]); + rt_kprintf("%c", response[index]); } rt_kprintf("\n"); - if (request) + if (response) { - web_free(request); + web_free(response); } return 0; diff --git a/samples/webclient_post_sample.c b/samples/webclient_post_sample.c index 30b225c..a5e7711 100644 --- a/samples/webclient_post_sample.c +++ b/samples/webclient_post_sample.c @@ -21,7 +21,7 @@ const char *post_data = "RT-Thread is an open source IoT operating system from China!"; /* send HTTP POST request by common request interface, it used to receive longer data */ -static int webclient_post_comm(const char *uri, const char *post_data) +static int webclient_post_comm(const char *uri, const void *post_data, size_t data_len) { struct webclient_session* session = RT_NULL; unsigned char *buffer = RT_NULL; @@ -49,7 +49,7 @@ static int webclient_post_comm(const char *uri, const char *post_data) webclient_header_fields_add(session, "Content-Type: application/octet-stream\r\n"); /* send POST request by default header */ - if ((resp_status = webclient_post(session, uri, post_data)) != 200) + if ((resp_status = webclient_post(session, uri, post_data, data_len)) != 200) { rt_kprintf("webclient POST request failed, response(%d) error.\n", resp_status); ret = -RT_ERROR; @@ -88,15 +88,17 @@ __exit: } /* send HTTP POST request by simplify request interface, it used to received shorter data */ -static int webclient_post_smpl(const char *uri, const char *post_data) +static int webclient_post_smpl(const char *uri, const char *post_data, size_t data_len) { - char *request = RT_NULL, *header = RT_NULL; - int index; + char *response = RT_NULL; + char *header = RT_NULL; + size_t resp_len = 0; + int index = 0; webclient_request_header_add(&header, "Content-Length: %d\r\n", strlen(post_data)); webclient_request_header_add(&header, "Content-Type: application/octet-stream\r\n"); - if (webclient_request(uri, (const char *)header, post_data, (unsigned char **)&request) < 0) + if (webclient_request(uri, header, post_data, data_len, (void **)&response, &resp_len) < 0) { rt_kprintf("webclient send post request failed."); web_free(header); @@ -105,9 +107,9 @@ static int webclient_post_smpl(const char *uri, const char *post_data) rt_kprintf("webclient send post request by simplify request interface.\n"); rt_kprintf("webclient post response data: \n"); - for (index = 0; index < rt_strlen(request); index++) + for (index = 0; index < resp_len; index++) { - rt_kprintf("%c", request[index]); + rt_kprintf("%c", response[index]); } rt_kprintf("\n"); @@ -116,9 +118,9 @@ static int webclient_post_smpl(const char *uri, const char *post_data) web_free(header); } - if (request) + if (response) { - web_free(request); + web_free(response); } return 0; @@ -138,7 +140,7 @@ int webclient_post_test(int argc, char **argv) return -RT_ENOMEM; } - webclient_post_comm(uri, post_data); + webclient_post_comm(uri, (void *)post_data, rt_strlen(post_data)); } else if (argc == 2) { @@ -151,7 +153,7 @@ int webclient_post_test(int argc, char **argv) return -RT_ENOMEM; } - webclient_post_smpl(uri, post_data); + webclient_post_smpl(uri, (void *)post_data, rt_strlen(post_data)); } else { @@ -161,7 +163,7 @@ int webclient_post_test(int argc, char **argv) rt_kprintf("no memory for create post request uri buffer.\n"); return -RT_ENOMEM; } - webclient_post_comm(uri, post_data); + webclient_post_comm(uri, (void *)post_data, rt_strlen(post_data)); } } else if(argc == 3 && rt_strcmp(argv[1], "-s") == 0) @@ -173,7 +175,7 @@ int webclient_post_test(int argc, char **argv) return -RT_ENOMEM; } - webclient_post_smpl(uri, post_data); + webclient_post_smpl(uri, (void *)post_data, rt_strlen(post_data)); } else { diff --git a/src/webclient.c b/src/webclient.c index b136ba8..ada9c35 100644 --- a/src/webclient.c +++ b/src/webclient.c @@ -79,7 +79,7 @@ static const char *webclient_strstri(const char* str, const char* subStr) return RT_NULL; } -static int webclient_send(struct webclient_session* session, const unsigned char *buffer, size_t len, int flag) +static int webclient_send(struct webclient_session* session, const void *buffer, size_t len, int flag) { #ifdef WEBCLIENT_USING_MBED_TLS if (session->tls_session) @@ -91,7 +91,7 @@ static int webclient_send(struct webclient_session* session, const unsigned char return send(session->socket, buffer, len, flag); } -static int webclient_recv(struct webclient_session* session, unsigned char *buffer, size_t len, int flag) +static int webclient_recv(struct webclient_session* session, void *buffer, size_t len, int flag) { #ifdef WEBCLIENT_USING_MBED_TLS if (session->tls_session) @@ -1039,15 +1039,16 @@ int webclient_get_position(struct webclient_session *session, const char *URI, i * @param session webclient session * @param URI input server URI address * @param header POST request header, can't be empty - * @param post_data data sent to the server + * @param post_data data send to the server * = NULL: just connect server and send header * != NULL: send header and body data, resolve response data + * @param data_len the length of send data * * @return <0: send POST request failed * =0: send POST header success * >0: response http status code */ -int webclient_post(struct webclient_session *session, const char *URI, const char *post_data) +int webclient_post(struct webclient_session *session, const char *URI, const void *post_data, size_t data_len) { int rc = WEBCLIENT_OK; int resp_status = 0; @@ -1055,6 +1056,12 @@ int webclient_post(struct webclient_session *session, const char *URI, const cha RT_ASSERT(session); RT_ASSERT(URI); + if ((post_data != RT_NULL) && (data_len == 0)) + { + LOG_E("input post data length failed"); + return -WEBCLIENT_ERROR; + } + rc = webclient_connect(session, URI); if (rc != WEBCLIENT_OK) { @@ -1069,9 +1076,9 @@ int webclient_post(struct webclient_session *session, const char *URI, const cha return rc; } - if (post_data) + if (post_data && (data_len > 0)) { - webclient_write(session, (unsigned char *) post_data, rt_strlen(post_data)); + webclient_write(session, post_data, data_len); /* resolve response data, get http status code */ resp_status = webclient_handle_response(session); @@ -1164,7 +1171,7 @@ static int webclient_next_chunk(struct webclient_session *session) * =0: http server disconnect * >0: successfully read data length */ -int webclient_read(struct webclient_session *session, unsigned char *buffer, size_t length) +int webclient_read(struct webclient_session *session, void *buffer, size_t length) { int bytes_read = 0; int total_read = 0; @@ -1241,7 +1248,7 @@ int webclient_read(struct webclient_session *session, unsigned char *buffer, siz left = length; do { - bytes_read = webclient_recv(session, buffer + total_read, left, 0); + bytes_read = webclient_recv(session, (void *)((char *)buffer + total_read), left, 0); if (bytes_read <= 0) { #if defined(WEBCLIENT_USING_SAL_TLS) || defined(WEBCLIENT_USING_MBED_TLS) @@ -1299,7 +1306,7 @@ int webclient_read(struct webclient_session *session, unsigned char *buffer, siz * =0: http server disconnect * >0: successfully write data length */ -int webclient_write(struct webclient_session *session, const unsigned char *buffer, size_t length) +int webclient_write(struct webclient_session *session, const void *buffer, size_t length) { int bytes_write = 0; int total_write = 0; @@ -1320,7 +1327,7 @@ int webclient_write(struct webclient_session *session, const unsigned char *buff /* send all of data on the buffer. */ do { - bytes_write = webclient_send(session, buffer + total_write, left, 0); + bytes_write = webclient_send(session, (void *)((char *)buffer + total_write), left, 0); if (bytes_write <= 0) { #if defined(WEBCLIENT_USING_SAL_TLS) || defined(WEBCLIENT_USING_MBED_TLS) @@ -1438,10 +1445,11 @@ int webclient_close(struct webclient_session *session) * * @param session wenclient session * @param response response buffer address + * @param resp_len response buffer length * * @return response data size */ -int webclient_response(struct webclient_session *session, unsigned char **response) +int webclient_response(struct webclient_session *session, void **response, size_t *resp_len) { unsigned char *buf_ptr; unsigned char *response_buf = 0; @@ -1513,8 +1521,9 @@ int webclient_response(struct webclient_session *session, unsigned char **respon if (response_buf) { - *response = response_buf; + *response = (void *)response_buf; *(response_buf + total_read) = '\0'; + *resp_len = total_read; } return total_read; @@ -1583,12 +1592,14 @@ int webclient_request_header_add(char **request_header, const char *fmt, ...) * @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_request(const char *URI, const char *header, const char *post_data, unsigned char **response) +int webclient_request(const char *URI, const char *header, const void *post_data, size_t data_len, void **response, size_t *resp_len) { struct webclient_session *session = RT_NULL; int rc = WEBCLIENT_OK; @@ -1602,6 +1613,19 @@ int webclient_request(const char *URI, const char *header, const char *post_data 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 */ @@ -1631,7 +1655,7 @@ int webclient_request(const char *URI, const char *header, const char *post_data goto __exit; } - totle_length = webclient_response(session, response); + totle_length = webclient_response(session, response, resp_len); if (totle_length <= 0) { rc = -WEBCLIENT_ERROR; @@ -1671,13 +1695,13 @@ int webclient_request(const char *URI, const char *header, const char *post_data webclient_header_fields_add(session, "Content-Type: application/octet-stream\r\n"); } - if (webclient_post(session, URI, post_data) != 200) + if (webclient_post(session, URI, post_data, data_len) != 200) { rc = -WEBCLIENT_ERROR; goto __exit; } - totle_length = webclient_response(session, response); + totle_length = webclient_response(session, response, resp_len); if (totle_length <= 0) { rc = -WEBCLIENT_ERROR; diff --git a/src/webclient_file.c b/src/webclient_file.c index 598e90d..f8db2e0 100644 --- a/src/webclient_file.c +++ b/src/webclient_file.c @@ -225,7 +225,7 @@ int webclient_post_file(const char* URI, const char* filename, rt_strncpy(session->header->buffer, header, rt_strlen(header)); session->header->length = rt_strlen(session->header->buffer); - rc = webclient_post(session, URI, NULL); + rc = webclient_post(session, URI, NULL, 0); if(rc < 0) { goto __exit;