improve api response
This commit is contained in:
parent
790262ac1c
commit
55c465fab9
@ -3,17 +3,18 @@
|
|||||||
|
|
||||||
#include "llhttp.h"
|
#include "llhttp.h"
|
||||||
|
|
||||||
|
#define HTTP_RESPONSE_HEADER_TEMPLATE "HTTP/1.1 %d %s\nContent-Length: %d\nContent-Type: %s; charset=utf-8\nConnection: close\n\n"
|
||||||
|
|
||||||
typedef struct HTTP_REQUEST_DATA_T_ {
|
typedef struct HTTP_REQUEST_DATA_T_ {
|
||||||
char protocol[8];
|
llhttp_method_t method;
|
||||||
char method[8];
|
|
||||||
char url[128];
|
char url[128];
|
||||||
char body[128];
|
char body[128];
|
||||||
} HTTP_REQUEST_DATA_T;
|
} HTTP_REQUEST_DATA_T;
|
||||||
|
|
||||||
typedef struct HTTP_REQUEST_PARSER_WRAPPER_T_ {
|
typedef struct HTTP_REQUEST_PARSER_T_ {
|
||||||
llhttp_t parser;
|
llhttp_t parser;
|
||||||
llhttp_settings_t settings;
|
llhttp_settings_t settings;
|
||||||
} HTTP_REQUEST_PARSER_WRAPPER_T;
|
} HTTP_REQUEST_PARSER_T;
|
||||||
|
|
||||||
int request_parser_on_url(llhttp_t * parser, const char * start, size_t length) {
|
int request_parser_on_url(llhttp_t * parser, const char * start, size_t length) {
|
||||||
HTTP_REQUEST_DATA_T * http_request = parser->data;
|
HTTP_REQUEST_DATA_T * http_request = parser->data;
|
||||||
@ -27,45 +28,36 @@ int request_parser_on_body(llhttp_t * parser, const char * start, size_t length)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_http_request (HTTP_REQUEST_PARSER_WRAPPER_T * wrapper, char * content, size_t len) {
|
int parse_http_request (HTTP_REQUEST_PARSER_T * wrapper, char * content, size_t len) {
|
||||||
llhttp_t parser = wrapper->parser;
|
llhttp_t parser = wrapper->parser;
|
||||||
|
|
||||||
llhttp_errno_t err = llhttp_execute(&parser, content, len);
|
llhttp_errno_t err = llhttp_execute(&parser, content, len);
|
||||||
HTTP_REQUEST_DATA_T * http_request = parser.data;
|
HTTP_REQUEST_DATA_T * http_request = parser.data;
|
||||||
|
|
||||||
uint8_t protocol_major = llhttp_get_http_major(&parser);
|
llhttp_method_t method = llhttp_get_method(&parser);
|
||||||
uint8_t protocol_minor = llhttp_get_http_minor(&parser);
|
http_request->method = method;
|
||||||
sprintf(http_request->protocol, "%d.%d", protocol_major, protocol_minor);
|
|
||||||
|
|
||||||
uint8_t method = llhttp_get_method(&parser);
|
|
||||||
const char * method_name = llhttp_method_name(method);
|
|
||||||
strcpy(http_request->method, method_name);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * get_protocol (HTTP_REQUEST_PARSER_WRAPPER_T * wrapper) {
|
llhttp_method_t get_method (HTTP_REQUEST_PARSER_T * wrapper) {
|
||||||
HTTP_REQUEST_DATA_T * http_request = wrapper->parser.data;
|
|
||||||
return http_request->protocol;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * get_method (HTTP_REQUEST_PARSER_WRAPPER_T * wrapper) {
|
|
||||||
HTTP_REQUEST_DATA_T * http_request = wrapper->parser.data;
|
HTTP_REQUEST_DATA_T * http_request = wrapper->parser.data;
|
||||||
return http_request->method;
|
return http_request->method;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * get_url (HTTP_REQUEST_PARSER_WRAPPER_T * wrapper) {
|
char * get_url (HTTP_REQUEST_PARSER_T * wrapper) {
|
||||||
HTTP_REQUEST_DATA_T * http_request = wrapper->parser.data;
|
HTTP_REQUEST_DATA_T * http_request = wrapper->parser.data;
|
||||||
return http_request->url;
|
return http_request->url;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * get_body (HTTP_REQUEST_PARSER_WRAPPER_T * wrapper) {
|
char * get_body (HTTP_REQUEST_PARSER_T * wrapper) {
|
||||||
HTTP_REQUEST_DATA_T * http_request = wrapper->parser.data;
|
HTTP_REQUEST_DATA_T * http_request = wrapper->parser.data;
|
||||||
return http_request->body;
|
return http_request->body;
|
||||||
}
|
}
|
||||||
|
|
||||||
HTTP_REQUEST_PARSER_WRAPPER_T * new_request_parser () {
|
HTTP_REQUEST_PARSER_T * new_request_parser () {
|
||||||
HTTP_REQUEST_PARSER_WRAPPER_T * wrapper = calloc(1, sizeof(HTTP_REQUEST_PARSER_WRAPPER_T));
|
// create new response parser wrapper
|
||||||
|
HTTP_REQUEST_PARSER_T * wrapper = calloc(1, sizeof(HTTP_REQUEST_PARSER_T));
|
||||||
|
|
||||||
// create a new request data struct
|
// create a new request data struct
|
||||||
HTTP_REQUEST_DATA_T * http_request = calloc(1, sizeof(HTTP_REQUEST_DATA_T));
|
HTTP_REQUEST_DATA_T * http_request = calloc(1, sizeof(HTTP_REQUEST_DATA_T));
|
||||||
@ -82,11 +74,67 @@ HTTP_REQUEST_PARSER_WRAPPER_T * new_request_parser () {
|
|||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
void delete_request_parser (HTTP_REQUEST_PARSER_WRAPPER_T * wrapper) {
|
void delete_request_parser (HTTP_REQUEST_PARSER_T * wrapper) {
|
||||||
free(wrapper->parser.data);
|
free(wrapper->parser.data);
|
||||||
free(wrapper);
|
free(wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct HTTP_RESPONSE_DATA_T_ {
|
||||||
|
llhttp_status_t status;
|
||||||
|
char type[32];
|
||||||
|
char body[128];
|
||||||
|
} HTTP_RESPONSE_DATA_T;
|
||||||
|
|
||||||
|
typedef struct HTTP_RESPONSE_COMPOSER_T_ {
|
||||||
|
HTTP_RESPONSE_DATA_T * response_data;
|
||||||
|
char header[1024];
|
||||||
|
char body[128];
|
||||||
|
uint32_t header_length;
|
||||||
|
uint32_t content_length;
|
||||||
|
} HTTP_RESPONSE_COMPOSER_T;
|
||||||
|
|
||||||
|
void set_status (HTTP_RESPONSE_COMPOSER_T * composer, llhttp_status_t status) {
|
||||||
|
HTTP_RESPONSE_DATA_T * response_data = composer->response_data;
|
||||||
|
response_data->status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_type (HTTP_RESPONSE_COMPOSER_T * composer, char * type) {
|
||||||
|
HTTP_RESPONSE_DATA_T * response_data = composer->response_data;
|
||||||
|
strncpy(response_data->type, type, 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_body (HTTP_RESPONSE_COMPOSER_T * composer, char * body) {
|
||||||
|
HTTP_RESPONSE_DATA_T * response_data = composer->response_data;
|
||||||
|
strncpy(response_data->body, body, 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
void compose_http_response (HTTP_RESPONSE_COMPOSER_T * composer) {
|
||||||
|
HTTP_RESPONSE_DATA_T * response_data = composer->response_data;
|
||||||
|
|
||||||
|
composer->content_length = snprintf(composer->body, sizeof(composer->body), "%s", response_data->body);
|
||||||
|
|
||||||
|
const char * status_name = llhttp_status_name(response_data->status);
|
||||||
|
|
||||||
|
composer->header_length = snprintf(composer->header, sizeof(composer->header), HTTP_RESPONSE_HEADER_TEMPLATE, response_data->status, status_name, composer->content_length, response_data->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
HTTP_RESPONSE_COMPOSER_T * new_response_composer () {
|
||||||
|
// create new response composer wrapper
|
||||||
|
HTTP_RESPONSE_COMPOSER_T * wrapper = calloc(1, sizeof(HTTP_RESPONSE_COMPOSER_T));
|
||||||
|
|
||||||
|
// create a new response data struct
|
||||||
|
HTTP_RESPONSE_DATA_T * http_response = calloc(1, sizeof(HTTP_RESPONSE_DATA_T));
|
||||||
|
|
||||||
|
wrapper->response_data = http_response;
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete_response_composer (HTTP_RESPONSE_COMPOSER_T * composer) {
|
||||||
|
free(composer->response_data);
|
||||||
|
free(composer);
|
||||||
|
}
|
||||||
|
|
||||||
int http_parser_init () {
|
int http_parser_init () {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
90
http_serv.h
90
http_serv.h
@ -7,9 +7,6 @@
|
|||||||
|
|
||||||
#define HTTP_PORT 80
|
#define HTTP_PORT 80
|
||||||
#define POLL_TIME_S 5
|
#define POLL_TIME_S 5
|
||||||
#define HTTP_GET "GET"
|
|
||||||
#define HTTP_POST "POST"
|
|
||||||
#define HTTP_RESPONSE_HEADER "HTTP/1.1 %d OK\nContent-Length: %d\nContent-Type: application/json; charset=utf-8\nConnection: close\n\n"
|
|
||||||
|
|
||||||
extern CURRENT_STATE_T current_state;
|
extern CURRENT_STATE_T current_state;
|
||||||
|
|
||||||
@ -22,11 +19,8 @@ typedef struct TCP_SERVER_T_ {
|
|||||||
typedef struct TCP_CONNECT_STATE_T_ {
|
typedef struct TCP_CONNECT_STATE_T_ {
|
||||||
struct tcp_pcb * pcb;
|
struct tcp_pcb * pcb;
|
||||||
int sent_len;
|
int sent_len;
|
||||||
char headers[1024];
|
HTTP_REQUEST_PARSER_T * request_parser;
|
||||||
char result[128];
|
HTTP_RESPONSE_COMPOSER_T * response_composer;
|
||||||
HTTP_REQUEST_PARSER_WRAPPER_T * request_parser;
|
|
||||||
int header_len;
|
|
||||||
int result_len;
|
|
||||||
ip_addr_t * gw;
|
ip_addr_t * gw;
|
||||||
} TCP_CONNECT_STATE_T;
|
} TCP_CONNECT_STATE_T;
|
||||||
|
|
||||||
@ -48,6 +42,7 @@ static err_t tcp_close_client_connection(TCP_CONNECT_STATE_T * con_state, struct
|
|||||||
}
|
}
|
||||||
if (con_state) {
|
if (con_state) {
|
||||||
delete_request_parser(con_state->request_parser);
|
delete_request_parser(con_state->request_parser);
|
||||||
|
delete_response_composer(con_state->response_composer);
|
||||||
free(con_state);
|
free(con_state);
|
||||||
}
|
}
|
||||||
DEBUG_printf("[HTTP] [OK ] Finished and closed connection to client\n");
|
DEBUG_printf("[HTTP] [OK ] Finished and closed connection to client\n");
|
||||||
@ -67,8 +62,8 @@ static err_t tcp_server_sent(void * arg, struct tcp_pcb * pcb, u16_t len) {
|
|||||||
TCP_CONNECT_STATE_T * con_state = (TCP_CONNECT_STATE_T *)arg;
|
TCP_CONNECT_STATE_T * con_state = (TCP_CONNECT_STATE_T *)arg;
|
||||||
DEBUG_printf("[HTTP] [OK ] Sent %u\n", len);
|
DEBUG_printf("[HTTP] [OK ] Sent %u\n", len);
|
||||||
con_state->sent_len += len;
|
con_state->sent_len += len;
|
||||||
if (con_state->sent_len >= con_state->header_len + con_state->result_len) {
|
if (con_state->sent_len >= con_state->response_composer->header_length + con_state->response_composer->content_length) {
|
||||||
DEBUG_printf("[HTTP] [OK ] Send done\n");
|
DEBUG_printf("[HTTP] [OK ] Sent done\n");
|
||||||
return tcp_close_client_connection(con_state, pcb, ERR_OK);
|
return tcp_close_client_connection(con_state, pcb, ERR_OK);
|
||||||
}
|
}
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
@ -76,26 +71,26 @@ static err_t tcp_server_sent(void * arg, struct tcp_pcb * pcb, u16_t len) {
|
|||||||
|
|
||||||
int send_response (TCP_CONNECT_STATE_T * con_state, struct tcp_pcb * pcb) {
|
int send_response (TCP_CONNECT_STATE_T * con_state, struct tcp_pcb * pcb) {
|
||||||
// Check result buffer size
|
// Check result buffer size
|
||||||
if (con_state->result_len > sizeof(con_state->result) - 1) {
|
if (con_state->response_composer->content_length > sizeof(con_state->response_composer->body) - 1) {
|
||||||
DEBUG_printf("[HTTP] [ERR] Too much result data %d\n", con_state->result_len);
|
DEBUG_printf("[HTTP] [ERR] Too much result data %d\n", con_state->response_composer->content_length);
|
||||||
return tcp_close_client_connection(con_state, pcb, ERR_CLSD);
|
return tcp_close_client_connection(con_state, pcb, ERR_CLSD);
|
||||||
}
|
}
|
||||||
// Check header buffer size
|
// Check header buffer size
|
||||||
if (con_state->header_len > sizeof(con_state->headers) - 1) {
|
if (con_state->response_composer->header_length > sizeof(con_state->response_composer->header) - 1) {
|
||||||
DEBUG_printf("[HTTP] [ERR] Too much header data %d\n", con_state->header_len);
|
DEBUG_printf("[HTTP] [ERR] Too much header data %d\n", con_state->response_composer->header_length);
|
||||||
return tcp_close_client_connection(con_state, pcb, ERR_CLSD);
|
return tcp_close_client_connection(con_state, pcb, ERR_CLSD);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the headers to the client
|
// Send the headers to the client
|
||||||
con_state->sent_len = 0;
|
con_state->sent_len = 0;
|
||||||
err_t err = tcp_write(pcb, con_state->headers, con_state->header_len, 0);
|
err_t err = tcp_write(pcb, con_state->response_composer->header, con_state->response_composer->header_length, 0);
|
||||||
if (err != ERR_OK) {
|
if (err != ERR_OK) {
|
||||||
DEBUG_printf("[HTTP] [ERR] Failed to write header data %d\n", err);
|
DEBUG_printf("[HTTP] [ERR] Failed to write header data %d\n", err);
|
||||||
return tcp_close_client_connection(con_state, pcb, err);
|
return tcp_close_client_connection(con_state, pcb, err);
|
||||||
}
|
}
|
||||||
// Send the body to the client
|
// Send the body to the client
|
||||||
if (con_state->result_len) {
|
if (con_state->response_composer->content_length) {
|
||||||
err = tcp_write(pcb, con_state->result, con_state->result_len, 0);
|
err = tcp_write(pcb, con_state->response_composer->body, con_state->response_composer->content_length, 0);
|
||||||
if (err != ERR_OK) {
|
if (err != ERR_OK) {
|
||||||
DEBUG_printf("[HTTP] [ERR] Failed to write result data %d\n", err);
|
DEBUG_printf("[HTTP] [ERR] Failed to write result data %d\n", err);
|
||||||
return tcp_close_client_connection(con_state, pcb, err);
|
return tcp_close_client_connection(con_state, pcb, err);
|
||||||
@ -104,32 +99,47 @@ int send_response (TCP_CONNECT_STATE_T * con_state, struct tcp_pcb * pcb) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_status_get (const char * request, const char * params, const char * body, char * result, size_t max_result_len) {
|
void handle_status_get (const char * request, const char * params, char * body, HTTP_RESPONSE_COMPOSER_T * response) {
|
||||||
return snprintf(result, max_result_len, "{volt: %f, temp: %f, power: %d}", current_state.voltage, current_state.tempC, current_state.power_state);
|
set_status(response, 200);
|
||||||
|
set_type(response, "application/json");
|
||||||
|
char response_body[128];
|
||||||
|
snprintf(response_body, 128, "{volt: %f, temp: %f, power: %d}", current_state.voltage, current_state.tempC, current_state.power_state);
|
||||||
|
set_body(response, response_body);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_power_post (const char * request, const char * params, const char * body, char * result, size_t max_result_len) {
|
void handle_power_post (const char * request, const char * params, char * body, HTTP_RESPONSE_COMPOSER_T * response) {
|
||||||
|
set_type(response, "application/json");
|
||||||
if (strstr(body, "requested_state")) {
|
if (strstr(body, "requested_state")) {
|
||||||
int requested_power_state_int;
|
int requested_power_state_int;
|
||||||
int led_param = sscanf(body, "requested_state=%d", &requested_power_state_int);
|
int led_param = sscanf(body, "requested_state=%d", &requested_power_state_int);
|
||||||
if (led_param) {
|
if (led_param) {
|
||||||
if (requested_power_state_int == 0 || requested_power_state_int == 1) {
|
if (requested_power_state_int == 0 || requested_power_state_int == 1) {
|
||||||
|
set_status(response, 200);
|
||||||
bmc_power_handler((bool) requested_power_state_int);
|
bmc_power_handler((bool) requested_power_state_int);
|
||||||
return snprintf(result, max_result_len, "{}");
|
set_body(response, "{}");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return snprintf(result, max_result_len, "{error: true, description: \"invalid requested state, must be 0 or 1\"}");
|
set_status(response, 400);
|
||||||
|
set_body(response, "{error: true, description: \"invalid requested state, must be 0 or 1\"}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return snprintf(result, max_result_len, "{error: true, description: \"invalid requested state, must be 0 or 1\"}");
|
set_status(response, 400);
|
||||||
|
set_body(response, "{error: true, description: \"invalid requested state, must be 0 or 1\"}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return snprintf(result, max_result_len, "{error: true, description: \"missing required parameter requested_state\"}");
|
set_status(response, 400);
|
||||||
|
set_body(response, "{error: true, description: \"missing required parameter requested_state\"}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_404_not_found (const char * request, const char * params, char * body, HTTP_RESPONSE_COMPOSER_T * response) {
|
||||||
|
set_status(response, 404);
|
||||||
|
set_type(response, "application/json");
|
||||||
|
set_body(response, "");
|
||||||
|
}
|
||||||
|
|
||||||
err_t tcp_server_recv(void * arg, struct tcp_pcb * pcb, struct pbuf * p, err_t err) {
|
err_t tcp_server_recv(void * arg, struct tcp_pcb * pcb, struct pbuf * p, err_t err) {
|
||||||
TCP_CONNECT_STATE_T * con_state = (TCP_CONNECT_STATE_T *)arg;
|
TCP_CONNECT_STATE_T * con_state = (TCP_CONNECT_STATE_T *)arg;
|
||||||
if (!p) {
|
if (!p) {
|
||||||
@ -138,42 +148,38 @@ err_t tcp_server_recv(void * arg, struct tcp_pcb * pcb, struct pbuf * p, err_t e
|
|||||||
}
|
}
|
||||||
assert(con_state && con_state->pcb == pcb);
|
assert(con_state && con_state->pcb == pcb);
|
||||||
if (p->tot_len > 0) {
|
if (p->tot_len > 0) {
|
||||||
DEBUG_printf("[HTTP] [OK ] Server recieved %d err %d\n", p->tot_len, err);
|
DEBUG_printf("[HTTP] [OK ] Recieved %d err: %d\n", p->tot_len, err);
|
||||||
|
|
||||||
char content[2048] = {0};
|
char content[2048] = {0};
|
||||||
pbuf_copy_partial(p, &content, 2048 - 1, 0);
|
pbuf_copy_partial(p, &content, 2048 - 1, 0);
|
||||||
con_state->request_parser = new_request_parser();
|
con_state->request_parser = new_request_parser();
|
||||||
parse_http_request(con_state->request_parser, content, strlen(content));
|
parse_http_request(con_state->request_parser, content, strlen(content));
|
||||||
|
|
||||||
char * protocol = get_protocol(con_state->request_parser);
|
llhttp_method_t method = get_method(con_state->request_parser);
|
||||||
char * method = get_method(con_state->request_parser);
|
|
||||||
char * url = get_url(con_state->request_parser);
|
char * url = get_url(con_state->request_parser);
|
||||||
char * body = get_body(con_state->request_parser);
|
char * body = get_body(con_state->request_parser);
|
||||||
|
|
||||||
// print request
|
// debug print request
|
||||||
DEBUG_printf("[HTTP] [OK ] Request: %s %s %s\n", method, url, body);
|
const char * method_name = llhttp_method_name(method);
|
||||||
|
DEBUG_printf("[HTTP] [OK ] Request: %s %s %s\n", method_name, url, body);
|
||||||
|
|
||||||
int response_code;
|
con_state->response_composer = new_response_composer();
|
||||||
|
|
||||||
// parse request depending on method and request
|
// parse request depending on method and request
|
||||||
if (strncmp(method, HTTP_GET, sizeof(HTTP_GET) - 1) == 0 && strncmp(url, "/status", sizeof("/status") - 1) == 0) {
|
if (method == HTTP_GET && strncmp(url, "/status", sizeof("/status") - 1) == 0) {
|
||||||
con_state->result_len = handle_status_get(url, NULL, body, con_state->result, sizeof(con_state->result));
|
handle_status_get(url, NULL, body, con_state->response_composer);
|
||||||
response_code = 200;
|
|
||||||
con_state->header_len = snprintf(con_state->headers, sizeof(con_state->headers), HTTP_RESPONSE_HEADER, response_code, con_state->result_len);
|
|
||||||
}
|
}
|
||||||
else if (strncmp(method, HTTP_POST, sizeof(HTTP_POST) - 1) == 0 && strncmp(url, "/power", sizeof("/power") - 1) == 0) {
|
else if (method == HTTP_POST && strncmp(url, "/power", sizeof("/power") - 1) == 0) {
|
||||||
con_state->result_len = handle_power_post(url, NULL, body, con_state->result, sizeof(con_state->result));
|
handle_power_post(url, NULL, body, con_state->response_composer);
|
||||||
response_code = 200;
|
|
||||||
con_state->header_len = snprintf(con_state->headers, sizeof(con_state->headers), HTTP_RESPONSE_HEADER, response_code, con_state->result_len);
|
|
||||||
}
|
}
|
||||||
else { // if not a registered path, return HTTP 404
|
else { // if not a registered path, return HTTP 404
|
||||||
con_state->result_len = 0;
|
handle_404_not_found(url, NULL, body, con_state->response_composer);
|
||||||
response_code = 404;
|
|
||||||
con_state->header_len = snprintf(con_state->headers, sizeof(con_state->headers), HTTP_RESPONSE_HEADER, response_code, con_state->result_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compose_http_response(con_state->response_composer);
|
||||||
|
|
||||||
// print result
|
// print result
|
||||||
DEBUG_printf("[HTTP] [OK ] Result: %d %s\n", response_code, con_state->result);
|
DEBUG_printf("[HTTP] [OK ] Result: %s %s\n", con_state->response_composer->header, con_state->response_composer->body);
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
if (err = send_response(con_state, pcb)) {
|
if (err = send_response(con_state, pcb)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user