From 9f232770da41ec6e02a3cdc9f173244cd0a92091 Mon Sep 17 00:00:00 2001 From: YuQing <384681@qq.com> Date: Fri, 19 Mar 2021 18:53:59 +0800 Subject: [PATCH] add sf_recv_vary_response and sf_send_and_recv_vary_response --- src/sf_proto.c | 117 ++++++++++++++++++++++++++++++++++++++++--------- src/sf_proto.h | 29 ++++++++++++ 2 files changed, 125 insertions(+), 21 deletions(-) diff --git a/src/sf_proto.c b/src/sf_proto.c index 9c02c9b..75e867c 100644 --- a/src/sf_proto.c +++ b/src/sf_proto.c @@ -92,20 +92,12 @@ int sf_check_response(ConnectionInfo *conn, SFResponseInfo *response, return response->header.status; } -int sf_send_and_recv_response_header(ConnectionInfo *conn, char *data, - const int len, SFResponseInfo *response, const int network_timeout) +static inline int sf_recv_response_header(ConnectionInfo *conn, + SFResponseInfo *response, const int network_timeout) { int result; SFCommonProtoHeader header_proto; - if ((result=tcpsenddata_nb(conn->sock, data, len, network_timeout)) != 0) { - response->error.length = snprintf(response->error.message, - sizeof(response->error.message), - "send data fail, errno: %d, error info: %s", - result, STRERROR(result)); - return result; - } - if ((result=tcprecvdata_nb(conn->sock, &header_proto, sizeof(SFCommonProtoHeader), network_timeout)) != 0) { @@ -120,6 +112,22 @@ int sf_send_and_recv_response_header(ConnectionInfo *conn, char *data, return 0; } +int sf_send_and_recv_response_header(ConnectionInfo *conn, char *data, + const int len, SFResponseInfo *response, const int network_timeout) +{ + int result; + + if ((result=tcpsenddata_nb(conn->sock, data, len, network_timeout)) != 0) { + response->error.length = snprintf(response->error.message, + sizeof(response->error.message), + "send data fail, errno: %d, error info: %s", + result, STRERROR(result)); + return result; + } + + return sf_recv_response_header(conn, response, network_timeout); +} + int sf_send_and_recv_response_ex(ConnectionInfo *conn, char *send_data, const int send_len, SFResponseInfo *response, const int network_timeout, const unsigned char expect_cmd, @@ -234,19 +242,12 @@ int sf_recv_response(ConnectionInfo *conn, SFResponseInfo *response, { int result; int recv_bytes; - SFCommonProtoHeader header_proto; - if ((result=tcprecvdata_nb(conn->sock, &header_proto, - sizeof(SFCommonProtoHeader), network_timeout)) != 0) + if ((result=sf_recv_response_header(conn, response, + network_timeout)) != 0) { - response->error.length = snprintf(response->error.message, - sizeof(response->error.message), - "recv data fail, errno: %d, error info: %s", - result, STRERROR(result)); return result; } - sf_proto_extract_header(&header_proto, &response->header); - if ((result=sf_check_response(conn, response, network_timeout, expect_cmd)) != 0) { @@ -264,8 +265,8 @@ int sf_recv_response(ConnectionInfo *conn, SFResponseInfo *response, return 0; } - if ((result=tcprecvdata_nb_ex(conn->sock, recv_data, - expect_body_len, network_timeout, &recv_bytes)) != 0) + if ((result=tcprecvdata_nb_ex(conn->sock, recv_data, expect_body_len, + network_timeout, &recv_bytes)) != 0) { response->error.length = snprintf(response->error.message, sizeof(response->error.message), @@ -278,6 +279,80 @@ int sf_recv_response(ConnectionInfo *conn, SFResponseInfo *response, return result; } +int sf_recv_vary_response(ConnectionInfo *conn, SFResponseInfo *response, + const int network_timeout, const unsigned char expect_cmd, + SFProtoRecvBuffer *buffer, const int min_body_len) +{ + int result; + int recv_bytes; + + if ((result=sf_recv_response_header(conn, response, + network_timeout)) != 0) + { + return result; + } + if ((result=sf_check_response(conn, response, network_timeout, + expect_cmd)) != 0) + { + return result; + } + + if (response->header.body_len < min_body_len) { + response->error.length = sprintf(response->error.message, + "response body length: %d < %d", + response->header.body_len, min_body_len); + return EINVAL; + } + + if (response->header.body_len <= sizeof(buffer->fixed)) { + if (response->header.body_len == 0) { + return 0; + } + } else { + if (buffer->buff != buffer->fixed && buffer->buff != NULL) { + free(buffer->buff); + } + buffer->buff = (char *)fc_malloc(response->header.body_len); + if (buffer->buff == NULL) { + return ENOMEM; + } + } + + if ((result=tcprecvdata_nb_ex(conn->sock, buffer->buff, response-> + header.body_len, network_timeout, &recv_bytes)) != 0) + { + response->error.length = snprintf(response->error.message, + sizeof(response->error.message), + "recv body fail, recv bytes: %d, expect body length: %d, " + "errno: %d, error info: %s", recv_bytes, + response->header.body_len, + result, STRERROR(result)); + } + + return result; +} + +int sf_send_and_recv_vary_response(ConnectionInfo *conn, + char *send_data, const int send_len, SFResponseInfo *response, + const int network_timeout, const unsigned char expect_cmd, + SFProtoRecvBuffer *buffer, const int min_body_len) +{ + int result; + + if ((result=tcpsenddata_nb(conn->sock, send_data, + send_len, network_timeout)) != 0) + { + response->error.length = snprintf(response->error.message, + sizeof(response->error.message), + "send data fail, errno: %d, error info: %s", + result, STRERROR(result)); + return result; + } + + return sf_recv_vary_response(conn, response, network_timeout, + expect_cmd, buffer, min_body_len); +} + const char *sf_get_cmd_caption(const int cmd) { switch (cmd) { diff --git a/src/sf_proto.h b/src/sf_proto.h index ab7a78f..d9588b2 100644 --- a/src/sf_proto.h +++ b/src/sf_proto.h @@ -171,6 +171,11 @@ typedef struct sf_client_server_entry { typedef const char *(*sf_get_cmd_caption_func)(const int cmd); typedef int (*sf_get_cmd_log_level_func)(const int cmd); +typedef struct { + char fixed[64 * 1024]; + char *buff; +} SFProtoRecvBuffer; + typedef struct { sf_get_cmd_caption_func get_cmd_caption; sf_get_cmd_log_level_func get_cmd_log_level; @@ -333,6 +338,25 @@ int sf_recv_response(ConnectionInfo *conn, SFResponseInfo *response, const int network_timeout, const unsigned char expect_cmd, char *recv_data, const int expect_body_len); +int sf_recv_vary_response(ConnectionInfo *conn, SFResponseInfo *response, + const int network_timeout, const unsigned char expect_cmd, + SFProtoRecvBuffer *buffer, const int min_body_len); + +static inline void sf_init_recv_buffer(SFProtoRecvBuffer *buffer) +{ + buffer->buff = buffer->fixed; +} + +static inline void sf_free_recv_buffer(SFProtoRecvBuffer *buffer) +{ + if (buffer->buff != buffer->fixed) { + if (buffer->buff != NULL) { + free(buffer->buff); + } + buffer->buff = buffer->fixed; + } +} + int sf_send_and_recv_response_header(ConnectionInfo *conn, char *data, const int len, SFResponseInfo *response, const int network_timeout); @@ -388,6 +412,11 @@ static inline int sf_send_and_recv_none_body_response(ConnectionInfo *conn, network_timeout, expect_cmd, recv_data, expect_body_len); } +int sf_send_and_recv_vary_response(ConnectionInfo *conn, + char *send_data, const int send_len, SFResponseInfo *response, + const int network_timeout, const unsigned char expect_cmd, + SFProtoRecvBuffer *buffer, const int min_body_len); + static inline void sf_proto_extract_header(SFCommonProtoHeader *header_proto, SFHeaderInfo *header_info) {