diff --git a/docs/c-api/mg_http.h/struct_http_message.md b/docs/c-api/mg_http.h/struct_http_message.md index 0f53a7a6..9380496d 100644 --- a/docs/c-api/mg_http.h/struct_http_message.md +++ b/docs/c-api/mg_http.h/struct_http_message.md @@ -29,12 +29,6 @@ signature: | /* Headers */ struct mg_str header_names[MG_MAX_HTTP_HEADERS]; struct mg_str header_values[MG_MAX_HTTP_HEADERS]; - - /* - * Value of the Content-Length header if present, - * otherwise MG_HTTP_CONTENT_LENGTH_UNKNOWN. - */ - size_t content_length; }; --- diff --git a/mongoose.c b/mongoose.c index 6a409a33..fde66dec 100644 --- a/mongoose.c +++ b/mongoose.c @@ -2913,13 +2913,13 @@ static int mg_recv_udp(struct mg_connection *nc, char *buf, size_t len) { } else { mbuf_append(&nc->recv_mbuf, buf, n); } + mbuf_trim(&lc->recv_mbuf); lc->last_io_time = nc->last_io_time = (time_t) mg_time(); #if !defined(NO_LIBC) && MG_ENABLE_HEXDUMP if (nc->mgr && nc->mgr->hexdump_file != NULL) { mg_hexdump_connection(nc, nc->mgr->hexdump_file, buf, n, MG_EV_RECV); } #endif - mbuf_trim(&lc->recv_mbuf); if (n != 0) { mg_call(nc, NULL, nc->user_data, MG_EV_RECV, &n); } @@ -4537,10 +4537,9 @@ enum mg_ssl_if_result mg_ssl_if_conn_init( SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2); SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv3); SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1); - SSL_CTX_set_session_id_context( - ctx->ssl_ctx, - (const unsigned char *) mg_default_session_id_context, - strlen(mg_default_session_id_context)); + SSL_CTX_set_session_id_context(ctx->ssl_ctx, + (void *) mg_default_session_id_context, + strlen(mg_default_session_id_context)); #ifdef MG_SSL_OPENSSL_NO_COMPRESSION SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_COMPRESSION); #endif @@ -5821,10 +5820,7 @@ struct mg_http_proto_data { struct mg_http_endpoint *endpoints; mg_event_handler_t endpoint_handler; struct mg_reverse_proxy_data reverse_proxy_data; - size_t rcvd; /* How many bytes we have received. */ - size_t body_rcvd; /* How many bytes of body we have received. */ - size_t body_processed; /* How many bytes of body we have processed. */ - int finished; + size_t rcvd; /* How many bytes we have received. */ }; static void mg_http_proto_data_destructor(void *proto_data); @@ -6055,7 +6051,6 @@ static int mg_http_get_request_len(const char *s, int buf_len) { static const char *mg_http_parse_headers(const char *s, const char *end, int len, struct http_message *req) { int i = 0; - req->content_length = MG_HTTP_CONTENT_LENGTH_UNKNOWN; while (i < (int) ARRAY_SIZE(req->header_names) - 1) { struct mg_str *k = &req->header_names[i], *v = &req->header_values[i]; @@ -6081,10 +6076,9 @@ static const char *mg_http_parse_headers(const char *s, const char *end, break; } - if (mg_ncasecmp(k->p, "Content-Length", 14) == 0) { + if (!mg_ncasecmp(k->p, "Content-Length", 14)) { req->body.len = (size_t) to64(v->p); req->message.len = len + req->body.len; - req->content_length = req->body.len; } i++; @@ -6200,7 +6194,6 @@ static void mg_http_transfer_file_data(struct mg_connection *nc) { pd->file.keepalive)); if (!pd->file.keepalive) nc->flags |= MG_F_SEND_AND_CLOSE; mg_http_free_proto_data_file(&pd->file); - pd->finished = 1; } } else if (pd->file.type == DATA_PUT) { struct mbuf *io = &nc->recv_mbuf; @@ -6213,7 +6206,6 @@ static void mg_http_transfer_file_data(struct mg_connection *nc) { if (n == 0 || pd->file.sent >= pd->file.cl) { if (!pd->file.keepalive) nc->flags |= MG_F_SEND_AND_CLOSE; mg_http_free_proto_data_file(&pd->file); - pd->finished = 1; } } #if MG_ENABLE_HTTP_CGI @@ -6369,26 +6361,13 @@ static void mg_http_call_endpoint_handler(struct mg_connection *nc, int ev, struct http_message *hm); static void deliver_chunk(struct mg_connection *c, struct http_message *hm, - struct mg_http_proto_data *pd, int req_len) { + int req_len) { /* Incomplete message received. Send MG_EV_HTTP_CHUNK event */ hm->body.len = c->recv_mbuf.len - req_len; - if (hm->content_length != MG_HTTP_CONTENT_LENGTH_UNKNOWN) { - size_t body_remain = hm->content_length - pd->body_processed; - if (hm->body.len > body_remain) { - hm->body.len = body_remain; - } - } - if (pd != NULL) { - pd->body_rcvd = pd->body_processed + hm->body.len; - } c->flags &= ~MG_F_DELETE_CHUNK; mg_call(c, c->handler, c->user_data, MG_EV_HTTP_CHUNK, hm); /* Delete processed data if user set MG_F_DELETE_CHUNK flag */ - if (c->flags & MG_F_DELETE_CHUNK) { - pd->body_processed += hm->body.len; - c->recv_mbuf.len = req_len; - hm->body.len = 0; - } + if (c->flags & MG_F_DELETE_CHUNK) c->recv_mbuf.len = req_len; } /* @@ -6459,7 +6438,7 @@ void mg_http_handler(struct mg_connection *nc, int ev, int ev2 = is_req ? MG_EV_HTTP_REQUEST : MG_EV_HTTP_REPLY; hm->message.len = io->len; hm->body.len = io->buf + io->len - hm->body.p; - deliver_chunk(nc, hm, pd, req_len); + deliver_chunk(nc, hm, req_len); mg_http_call_endpoint_handler(nc, ev2, hm); } if (pd != NULL && pd->endpoint_handler != NULL && @@ -6471,8 +6450,6 @@ void mg_http_handler(struct mg_connection *nc, int ev, #if MG_ENABLE_FILESYSTEM if (pd != NULL && pd->file.fp != NULL) { mg_http_transfer_file_data(nc); - if (pd->finished) { - } } #endif @@ -6497,7 +6474,8 @@ void mg_http_handler(struct mg_connection *nc, int ev, again: req_len = mg_parse_http(io->buf, io->len, hm, is_req); - if (req_len > 0 && (pd == NULL || pd->finished)) { + + if (req_len > 0) { /* New request - new proto data */ pd = mg_http_create_proto_data(nc); pd->rcvd = io->len; @@ -6579,50 +6557,42 @@ void mg_http_handler(struct mg_connection *nc, int ev, } } #endif /* MG_ENABLE_HTTP_WEBSOCKET */ - else { - deliver_chunk(nc, hm, pd, req_len); - if (hm->message.len > pd->rcvd && - (hm->content_length == MG_HTTP_CONTENT_LENGTH_UNKNOWN || - pd->body_rcvd < hm->content_length)) { - /* Not yet received all HTTP body, deliver MG_EV_HTTP_CHUNK */ - if (nc->recv_mbuf_limit > 0 && - nc->recv_mbuf.len >= nc->recv_mbuf_limit) { - LOG(LL_ERROR, ("%p recv buffer (%lu bytes) exceeds the limit " - "%lu bytes, and not drained, closing", - nc, (unsigned long) nc->recv_mbuf.len, - (unsigned long) nc->recv_mbuf_limit)); - nc->flags |= MG_F_CLOSE_IMMEDIATELY; - } - } else { - /* We did receive all HTTP body. */ - int request_done = 1; - int trigger_ev = nc->listener ? MG_EV_HTTP_REQUEST : MG_EV_HTTP_REPLY; - char addr[32]; - mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr), - MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT); - DBG(("%p %s %.*s %.*s", nc, addr, (int) hm->method.len, hm->method.p, - (int) hm->uri.len, hm->uri.p)); - /* Whole HTTP message is fully buffered, call event handler */ - mg_http_call_endpoint_handler(nc, trigger_ev, hm); - mbuf_remove(io, req_len + hm->body.len); - pd->rcvd -= hm->message.len; - pd->body_rcvd = 0; + else if (hm->message.len > pd->rcvd) { + /* Not yet received all HTTP body, deliver MG_EV_HTTP_CHUNK */ + deliver_chunk(nc, hm, req_len); + if (nc->recv_mbuf_limit > 0 && nc->recv_mbuf.len >= nc->recv_mbuf_limit) { + LOG(LL_ERROR, ("%p recv buffer (%lu bytes) exceeds the limit " + "%lu bytes, and not drained, closing", + nc, (unsigned long) nc->recv_mbuf.len, + (unsigned long) nc->recv_mbuf_limit)); + nc->flags |= MG_F_CLOSE_IMMEDIATELY; + } + } else { + /* We did receive all HTTP body. */ + int request_done = 1; + int trigger_ev = nc->listener ? MG_EV_HTTP_REQUEST : MG_EV_HTTP_REPLY; + char addr[32]; + mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr), + MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT); + DBG(("%p %s %.*s %.*s", nc, addr, (int) hm->method.len, hm->method.p, + (int) hm->uri.len, hm->uri.p)); + deliver_chunk(nc, hm, req_len); + /* Whole HTTP message is fully buffered, call event handler */ + mg_http_call_endpoint_handler(nc, trigger_ev, hm); + mbuf_remove(io, hm->message.len); + pd->rcvd -= hm->message.len; #if MG_ENABLE_FILESYSTEM - /* We don't have a generic mechanism of communicating that we are done - * responding to a request (should probably add one). But if we are - * serving - * a file, we are definitely not done. */ - if (pd->file.fp != NULL) request_done = 0; + /* We don't have a generic mechanism of communicating that we are done + * responding to a request (should probably add one). But if we are + * serving + * a file, we are definitely not done. */ + if (pd->file.fp != NULL) request_done = 0; #endif #if MG_ENABLE_HTTP_CGI - /* If this is a CGI request, we are not done either. */ - if (pd->cgi.cgi_nc != NULL) request_done = 0; + /* If this is a CGI request, we are not done either. */ + if (pd->cgi.cgi_nc != NULL) request_done = 0; #endif - pd->finished = request_done; - DBG(("%p finished %d ml %d bl %d", nc, pd->finished, - (int) hm->message.len, (int) hm->body.len)); - if (request_done && io->len > 0) goto again; - } + if (request_done && io->len > 0) goto again; } } } @@ -9377,15 +9347,13 @@ static void mg_do_ssi_include(struct mg_connection *nc, struct http_message *hm, */ if (sscanf(tag, " virtual=\"%[^\"]\"", file_name) == 1) { /* File name is relative to the webserver root */ - if (snprintf(path, sizeof(path), "%s/%s", opts->document_root, file_name) < 0) { - return; - } + snprintf(path, sizeof(path), "%s/%s", opts->document_root, file_name); } else if (sscanf(tag, " abspath=\"%[^\"]\"", file_name) == 1) { /* * File name is relative to the webserver working directory * or it is absolute system path */ - if (snprintf(path, sizeof(path), "%s", file_name) < 0) return; + snprintf(path, sizeof(path), "%s", file_name); } else if (sscanf(tag, " file=\"%[^\"]\"", file_name) == 1 || sscanf(tag, " \"%[^\"]\"", file_name) == 1) { /* File name is relative to the currect document */ diff --git a/mongoose.h b/mongoose.h index 3ebba00a..3d5d2cb5 100644 --- a/mongoose.h +++ b/mongoose.h @@ -4420,16 +4420,8 @@ struct http_message { /* Headers */ struct mg_str header_names[MG_MAX_HTTP_HEADERS]; struct mg_str header_values[MG_MAX_HTTP_HEADERS]; - - /* - * Value of the Content-Length header if present, - * otherwise MG_HTTP_CONTENT_LENGTH_UNKNOWN. - */ - size_t content_length; }; -#define MG_HTTP_CONTENT_LENGTH_UNKNOWN ((size_t) -1) - #if MG_ENABLE_HTTP_WEBSOCKET /* WebSocket message */ struct websocket_message { diff --git a/src/mg_common.h b/src/mg_common.h index 4589412a..9c04cb49 100644 --- a/src/mg_common.h +++ b/src/mg_common.h @@ -1,7 +1,7 @@ #ifndef CS_MONGOOSE_SRC_COMMON_H_ #define CS_MONGOOSE_SRC_COMMON_H_ -#define MG_VERSION "6.18" +#define MG_VERSION "6.17" /* Local tweaks, applied before any of Mongoose's own headers. */ #ifdef MG_LOCALS diff --git a/src/mg_http.c b/src/mg_http.c index 919251aa..70f13dc1 100644 --- a/src/mg_http.c +++ b/src/mg_http.c @@ -174,10 +174,7 @@ struct mg_http_proto_data { struct mg_http_endpoint *endpoints; mg_event_handler_t endpoint_handler; struct mg_reverse_proxy_data reverse_proxy_data; - size_t rcvd; /* How many bytes we have received. */ - size_t body_rcvd; /* How many bytes of body we have received. */ - size_t body_processed; /* How many bytes of body we have processed. */ - int finished; + size_t rcvd; /* How many bytes we have received. */ }; static void mg_http_proto_data_destructor(void *proto_data); @@ -408,7 +405,6 @@ static int mg_http_get_request_len(const char *s, int buf_len) { static const char *mg_http_parse_headers(const char *s, const char *end, int len, struct http_message *req) { int i = 0; - req->content_length = MG_HTTP_CONTENT_LENGTH_UNKNOWN; while (i < (int) ARRAY_SIZE(req->header_names) - 1) { struct mg_str *k = &req->header_names[i], *v = &req->header_values[i]; @@ -434,10 +430,9 @@ static const char *mg_http_parse_headers(const char *s, const char *end, break; } - if (mg_ncasecmp(k->p, "Content-Length", 14) == 0) { + if (!mg_ncasecmp(k->p, "Content-Length", 14)) { req->body.len = (size_t) to64(v->p); req->message.len = len + req->body.len; - req->content_length = req->body.len; } i++; @@ -553,7 +548,6 @@ static void mg_http_transfer_file_data(struct mg_connection *nc) { pd->file.keepalive)); if (!pd->file.keepalive) nc->flags |= MG_F_SEND_AND_CLOSE; mg_http_free_proto_data_file(&pd->file); - pd->finished = 1; } } else if (pd->file.type == DATA_PUT) { struct mbuf *io = &nc->recv_mbuf; @@ -566,7 +560,6 @@ static void mg_http_transfer_file_data(struct mg_connection *nc) { if (n == 0 || pd->file.sent >= pd->file.cl) { if (!pd->file.keepalive) nc->flags |= MG_F_SEND_AND_CLOSE; mg_http_free_proto_data_file(&pd->file); - pd->finished = 1; } } #if MG_ENABLE_HTTP_CGI @@ -722,26 +715,13 @@ static void mg_http_call_endpoint_handler(struct mg_connection *nc, int ev, struct http_message *hm); static void deliver_chunk(struct mg_connection *c, struct http_message *hm, - struct mg_http_proto_data *pd, int req_len) { + int req_len) { /* Incomplete message received. Send MG_EV_HTTP_CHUNK event */ hm->body.len = c->recv_mbuf.len - req_len; - if (hm->content_length != MG_HTTP_CONTENT_LENGTH_UNKNOWN) { - size_t body_remain = hm->content_length - pd->body_processed; - if (hm->body.len > body_remain) { - hm->body.len = body_remain; - } - } - if (pd != NULL) { - pd->body_rcvd = pd->body_processed + hm->body.len; - } c->flags &= ~MG_F_DELETE_CHUNK; mg_call(c, c->handler, c->user_data, MG_EV_HTTP_CHUNK, hm); /* Delete processed data if user set MG_F_DELETE_CHUNK flag */ - if (c->flags & MG_F_DELETE_CHUNK) { - pd->body_processed += hm->body.len; - c->recv_mbuf.len = req_len; - hm->body.len = 0; - } + if (c->flags & MG_F_DELETE_CHUNK) c->recv_mbuf.len = req_len; } /* @@ -812,7 +792,7 @@ void mg_http_handler(struct mg_connection *nc, int ev, int ev2 = is_req ? MG_EV_HTTP_REQUEST : MG_EV_HTTP_REPLY; hm->message.len = io->len; hm->body.len = io->buf + io->len - hm->body.p; - deliver_chunk(nc, hm, pd, req_len); + deliver_chunk(nc, hm, req_len); mg_http_call_endpoint_handler(nc, ev2, hm); } if (pd != NULL && pd->endpoint_handler != NULL && @@ -824,8 +804,6 @@ void mg_http_handler(struct mg_connection *nc, int ev, #if MG_ENABLE_FILESYSTEM if (pd != NULL && pd->file.fp != NULL) { mg_http_transfer_file_data(nc); - if (pd->finished) { - } } #endif @@ -850,7 +828,8 @@ void mg_http_handler(struct mg_connection *nc, int ev, again: req_len = mg_parse_http(io->buf, io->len, hm, is_req); - if (req_len > 0 && (pd == NULL || pd->finished)) { + + if (req_len > 0) { /* New request - new proto data */ pd = mg_http_create_proto_data(nc); pd->rcvd = io->len; @@ -932,50 +911,42 @@ void mg_http_handler(struct mg_connection *nc, int ev, } } #endif /* MG_ENABLE_HTTP_WEBSOCKET */ - else { - deliver_chunk(nc, hm, pd, req_len); - if (hm->message.len > pd->rcvd && - (hm->content_length == MG_HTTP_CONTENT_LENGTH_UNKNOWN || - pd->body_rcvd < hm->content_length)) { - /* Not yet received all HTTP body, deliver MG_EV_HTTP_CHUNK */ - if (nc->recv_mbuf_limit > 0 && - nc->recv_mbuf.len >= nc->recv_mbuf_limit) { - LOG(LL_ERROR, ("%p recv buffer (%lu bytes) exceeds the limit " - "%lu bytes, and not drained, closing", - nc, (unsigned long) nc->recv_mbuf.len, - (unsigned long) nc->recv_mbuf_limit)); - nc->flags |= MG_F_CLOSE_IMMEDIATELY; - } - } else { - /* We did receive all HTTP body. */ - int request_done = 1; - int trigger_ev = nc->listener ? MG_EV_HTTP_REQUEST : MG_EV_HTTP_REPLY; - char addr[32]; - mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr), - MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT); - DBG(("%p %s %.*s %.*s", nc, addr, (int) hm->method.len, hm->method.p, - (int) hm->uri.len, hm->uri.p)); - /* Whole HTTP message is fully buffered, call event handler */ - mg_http_call_endpoint_handler(nc, trigger_ev, hm); - mbuf_remove(io, req_len + hm->body.len); - pd->rcvd -= hm->message.len; - pd->body_rcvd = 0; + else if (hm->message.len > pd->rcvd) { + /* Not yet received all HTTP body, deliver MG_EV_HTTP_CHUNK */ + deliver_chunk(nc, hm, req_len); + if (nc->recv_mbuf_limit > 0 && nc->recv_mbuf.len >= nc->recv_mbuf_limit) { + LOG(LL_ERROR, ("%p recv buffer (%lu bytes) exceeds the limit " + "%lu bytes, and not drained, closing", + nc, (unsigned long) nc->recv_mbuf.len, + (unsigned long) nc->recv_mbuf_limit)); + nc->flags |= MG_F_CLOSE_IMMEDIATELY; + } + } else { + /* We did receive all HTTP body. */ + int request_done = 1; + int trigger_ev = nc->listener ? MG_EV_HTTP_REQUEST : MG_EV_HTTP_REPLY; + char addr[32]; + mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr), + MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT); + DBG(("%p %s %.*s %.*s", nc, addr, (int) hm->method.len, hm->method.p, + (int) hm->uri.len, hm->uri.p)); + deliver_chunk(nc, hm, req_len); + /* Whole HTTP message is fully buffered, call event handler */ + mg_http_call_endpoint_handler(nc, trigger_ev, hm); + mbuf_remove(io, hm->message.len); + pd->rcvd -= hm->message.len; #if MG_ENABLE_FILESYSTEM - /* We don't have a generic mechanism of communicating that we are done - * responding to a request (should probably add one). But if we are - * serving - * a file, we are definitely not done. */ - if (pd->file.fp != NULL) request_done = 0; + /* We don't have a generic mechanism of communicating that we are done + * responding to a request (should probably add one). But if we are + * serving + * a file, we are definitely not done. */ + if (pd->file.fp != NULL) request_done = 0; #endif #if MG_ENABLE_HTTP_CGI - /* If this is a CGI request, we are not done either. */ - if (pd->cgi.cgi_nc != NULL) request_done = 0; + /* If this is a CGI request, we are not done either. */ + if (pd->cgi.cgi_nc != NULL) request_done = 0; #endif - pd->finished = request_done; - DBG(("%p finished %d ml %d bl %d", nc, pd->finished, - (int) hm->message.len, (int) hm->body.len)); - if (request_done && io->len > 0) goto again; - } + if (request_done && io->len > 0) goto again; } } } diff --git a/src/mg_http.h b/src/mg_http.h index 385c210a..f368b2ed 100644 --- a/src/mg_http.h +++ b/src/mg_http.h @@ -62,16 +62,8 @@ struct http_message { /* Headers */ struct mg_str header_names[MG_MAX_HTTP_HEADERS]; struct mg_str header_values[MG_MAX_HTTP_HEADERS]; - - /* - * Value of the Content-Length header if present, - * otherwise MG_HTTP_CONTENT_LENGTH_UNKNOWN. - */ - size_t content_length; }; -#define MG_HTTP_CONTENT_LENGTH_UNKNOWN ((size_t) -1) - #if MG_ENABLE_HTTP_WEBSOCKET /* WebSocket message */ struct websocket_message { diff --git a/src/mg_http_ssi.c b/src/mg_http_ssi.c index b96d6112..d1a95948 100644 --- a/src/mg_http_ssi.c +++ b/src/mg_http_ssi.c @@ -29,15 +29,13 @@ static void mg_do_ssi_include(struct mg_connection *nc, struct http_message *hm, */ if (sscanf(tag, " virtual=\"%[^\"]\"", file_name) == 1) { /* File name is relative to the webserver root */ - if (snprintf(path, sizeof(path), "%s/%s", opts->document_root, file_name) < 0) { - return; - } + snprintf(path, sizeof(path), "%s/%s", opts->document_root, file_name); } else if (sscanf(tag, " abspath=\"%[^\"]\"", file_name) == 1) { /* * File name is relative to the webserver working directory * or it is absolute system path */ - if (snprintf(path, sizeof(path), "%s", file_name) < 0) return; + snprintf(path, sizeof(path), "%s", file_name); } else if (sscanf(tag, " file=\"%[^\"]\"", file_name) == 1 || sscanf(tag, " \"%[^\"]\"", file_name) == 1) { /* File name is relative to the currect document */ diff --git a/src/mg_net.c b/src/mg_net.c index b621b0ef..ec2f5354 100644 --- a/src/mg_net.c +++ b/src/mg_net.c @@ -707,13 +707,13 @@ static int mg_recv_udp(struct mg_connection *nc, char *buf, size_t len) { } else { mbuf_append(&nc->recv_mbuf, buf, n); } + mbuf_trim(&lc->recv_mbuf); lc->last_io_time = nc->last_io_time = (time_t) mg_time(); #if !defined(NO_LIBC) && MG_ENABLE_HEXDUMP if (nc->mgr && nc->mgr->hexdump_file != NULL) { mg_hexdump_connection(nc, nc->mgr->hexdump_file, buf, n, MG_EV_RECV); } #endif - mbuf_trim(&lc->recv_mbuf); if (n != 0) { mg_call(nc, NULL, nc->user_data, MG_EV_RECV, &n); } diff --git a/src/mg_ssl_if_openssl.c b/src/mg_ssl_if_openssl.c index 18d8b706..c2c9bc40 100644 --- a/src/mg_ssl_if_openssl.c +++ b/src/mg_ssl_if_openssl.c @@ -78,10 +78,9 @@ enum mg_ssl_if_result mg_ssl_if_conn_init( SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2); SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv3); SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1); - SSL_CTX_set_session_id_context( - ctx->ssl_ctx, - (const unsigned char *) mg_default_session_id_context, - strlen(mg_default_session_id_context)); + SSL_CTX_set_session_id_context(ctx->ssl_ctx, + (void *) mg_default_session_id_context, + strlen(mg_default_session_id_context)); #ifdef MG_SSL_OPENSSL_NO_COMPRESSION SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_COMPRESSION); #endif diff --git a/test/unit_test.c b/test/unit_test.c index f5e05523..43dd3eb7 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -16,7 +16,6 @@ */ #include "unit_test.h" - #include "common/cs_md5.h" #include "common/test_main.h" #include "common/test_util.h" @@ -198,17 +197,20 @@ static const char *test_mgr_with_ssl(int use_ssl) { struct mg_connection *nc; struct mg_bind_opts bopts; int port, port2; +#if !MG_ENABLE_SSL + (void) use_ssl; +#endif mg_mgr_init(&mgr, NULL); /* mgr.hexdump_file = "-"; */ memset(&bopts, 0, sizeof(bopts)); - if (use_ssl) { #if MG_ENABLE_SSL + if (use_ssl) { bopts.ssl_cert = S_PEM; bopts.ssl_ca_cert = CA_PEM; -#endif } +#endif ASSERT((nc = mg_bind_opt(&mgr, addr, eh1, bopts)) != NULL); port2 = htons(nc->sa.sin.sin_port); ASSERT(port2 > 0); @@ -779,16 +781,9 @@ static const char *test_parse_address(void) { }; static const char *need_lookup[] = {"udp://a.com:53", "locl_host:12", NULL}; static const char *invalid[] = { - "99999", - "1k", - "1.2.3", - "1.2.3.4:", - "1.2.3.4:2p", - "blah://12", - ":123x", + "99999", "1k", "1.2.3", "1.2.3.4:", "1.2.3.4:2p", "blah://12", ":123x", "veeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeery.long:12345", - "udp://missingport", - NULL}; + "udp://missingport", NULL}; char host[50]; union socket_address sa; int i, proto; @@ -1497,8 +1492,7 @@ static const char *test_parse_http_message(void) { static const char *a = "GET / HTTP/1.0\n\n"; static const char *b = "GET /blah HTTP/1.0\r\nFoo: bar \r\n\r\n"; static const char *c = "get b c\nz: k \nb: t\nvvv\n\n xx"; - static const char *d = - "a b c\r\nContent-Length: 21 \r\nb: t\r\nvvv\r\n\r\nabc"; + static const char *d = "a b c\nContent-Length: 21 \nb: t\nvvv\n\n"; static const char *e = "GET /foo?a=b&c=d HTTP/1.0\n\n"; static const char *f = "POST /x HTTP/1.0\n\n"; static const char *g = "WOHOO /x HTTP/1.0\n\n"; @@ -1543,19 +1537,14 @@ static const char *test_parse_http_message(void) { ASSERT_EQ(memcmp(req.header_values[1].p, "t", 1), 0); ASSERT_EQ(req.header_names[1].len, 1); ASSERT_EQ(req.body.len, 0); - ASSERT_EQ64(req.content_length, MG_HTTP_CONTENT_LENGTH_UNKNOWN); - ASSERT_EQ(mg_parse_http(d, strlen(d), &req, 1), (int) strlen(d) - 3); + ASSERT_EQ(mg_parse_http(d, strlen(d), &req, 1), (int) strlen(d)); ASSERT_EQ(req.body.len, 21); - ASSERT_EQ(req.content_length, 21); - ASSERT_EQ(req.message.len, 21 + strlen(d) - 3); + ASSERT_EQ(req.message.len, 21 + strlen(d)); ASSERT(mg_get_http_header(&req, "foo") == NULL); ASSERT((v = mg_get_http_header(&req, "contENT-Length")) != NULL); ASSERT_EQ(v->len, 2); ASSERT_STREQ_NZ(v->p, "21"); - ASSERT((v = mg_get_http_header(&req, "B")) != NULL); - ASSERT_EQ(v->len, 1); - ASSERT_STREQ_NZ(v->p, "t"); ASSERT_EQ(mg_parse_http(e, strlen(e), &req, 1), (int) strlen(e)); ASSERT_EQ(mg_vcmp(&req.uri, "/foo"), 0); @@ -1841,7 +1830,7 @@ static const char *test_http_endpoints(void) { "0123456789")) != NULL); memset(buf, 0, sizeof(buf)); nc->user_data = buf; - DBG(("== WAIT 1 ==")); + DBG(("== WAIT ==")); poll_until(&mgr, 1, c_str_ne, buf, (void *) ""); ASSERT_STREQ(buf, "[/ 10] 25"); @@ -1849,7 +1838,7 @@ static const char *test_http_endpoints(void) { "0123456789")) != NULL); memset(buf, 0, sizeof(buf)); nc->user_data = buf; - DBG(("== WAIT 2 ==")); + DBG(("== WAIT ==")); poll_until(&mgr, 1, c_str_ne, buf, (void *) ""); ASSERT_STREQ(buf, "[/ 10] 25"); @@ -1857,7 +1846,7 @@ static const char *test_http_endpoints(void) { "foo")) != NULL); memset(buf, 0, sizeof(buf)); nc->user_data = buf; - DBG(("== WAIT 3 ==")); + DBG(("== WAIT ==")); poll_until(&mgr, 1, c_str_ne, buf, (void *) ""); ASSERT_STREQ(buf, "[/foo?a=b 3] 31"); @@ -1865,7 +1854,7 @@ static const char *test_http_endpoints(void) { "0123456789")) != NULL); memset(buf, 0, sizeof(buf)); nc->user_data = buf; - DBG(("== WAIT 4 ==")); + DBG(("== WAIT ==")); poll_until(&mgr, 1, c_str_ne, buf, (void *) ""); ASSERT_STREQ(buf, "[/foo 10] 28"); @@ -1873,7 +1862,7 @@ static const char *test_http_endpoints(void) { "0123456789")) != NULL); memset(buf, 0, sizeof(buf)); nc->user_data = buf; - DBG(("== WAIT 5 ==")); + DBG(("== WAIT ==")); poll_until(&mgr, 1, c_str_ne, buf, (void *) ""); ASSERT_STREQ(buf, "[I am Hello1] 32"); @@ -1881,7 +1870,7 @@ static const char *test_http_endpoints(void) { NULL, "0123456789")) != NULL); memset(buf, 0, sizeof(buf)); nc->user_data = buf; - DBG(("== WAIT 6 ==")); + DBG(("== WAIT ==")); poll_until(&mgr, 1, c_str_ne, buf, (void *) ""); ASSERT_STREQ(buf, "[I am Hello two] 35"); @@ -1890,7 +1879,6 @@ static const char *test_http_endpoints(void) { memset(buf, 0, sizeof(buf)); nc->user_data = buf; - DBG(("== WAIT 7 ==")); poll_until(&mgr, 1, c_str_ne, buf, (void *) ""); ASSERT_STREQ(buf, "[I am Hello again] 37"); @@ -1906,7 +1894,6 @@ static const char *serve_file_verify(struct http_message *hm) { char *data = read_file("unit_test.c", &size); if (data == NULL || size != hm->body.len || memcmp(hm->body.p, data, size) != 0) { - DBG(("%d %d", (int) size, (int) hm->body.len)); return "wrong data"; } free(data); @@ -1959,59 +1946,35 @@ static const char *test_http_serve_file(void) { return NULL; } -static void file_srv(struct mg_connection *c, int ev, void *ev_data) { +static void srv1(struct mg_connection *c, int ev, void *ev_data) { if (ev == MG_EV_HTTP_REQUEST) { mg_http_serve_file(c, (struct http_message *) ev_data, "unit_test.c", mg_mk_str("text/plain"), mg_mk_str("")); } } -struct chunk_clt_ctx { - int seq; - int status; - size_t num_chunks; - size_t chunks_rcvd; - size_t content_length; -}; - -static void chunk_clt(struct mg_connection *c, int ev, void *ev_data) { +static void srv2(struct mg_connection *c, int ev, void *ev_data) { static cs_md5_ctx c1, c2; struct http_message *hm = (struct http_message *) ev_data; - struct chunk_clt_ctx *ctx = (struct chunk_clt_ctx *) c->user_data; switch (ev) { case MG_EV_CONNECT: cs_md5_init(&c1); + cs_md5_init(&c2); break; case MG_EV_HTTP_CHUNK: cs_md5_update(&c1, (const unsigned char *) hm->body.p, hm->body.len); - ctx->chunks_rcvd += hm->body.len; - DBG(("%p = seq %d, chunk %d bytes, %d", c, ctx->seq, (int) hm->body.len, - (int) ctx->chunks_rcvd)); - ctx->num_chunks++; - ctx->content_length = hm->content_length; c->flags |= MG_F_DELETE_CHUNK; break; case MG_EV_HTTP_REPLY: { unsigned char sig1[16], sig2[sizeof(sig1)]; size_t size; char *data = read_file("unit_test.c", &size); - cs_md5_final(sig1, &c1); - cs_md5_init(&c2); if (data != NULL) cs_md5_update(&c2, (const unsigned char *) data, size); free(data); + cs_md5_final(sig1, &c1); cs_md5_final(sig2, &c2); - DBG(("%p = seq %d, reply", c, ctx->seq)); - if (size != ctx->content_length) { - DBG(("%p: want %d, got %d", c, (int) size, (int) ctx->content_length)); - ctx->status = 3; - } else if (size != ctx->chunks_rcvd) { - DBG(("%p: want %d, got %d", c, (int) size, (int) ctx->chunks_rcvd)); - ctx->status = 4; - } else { - ctx->status = (memcmp(sig1, sig2, sizeof(sig1)) == 0) ? 1 : 2; - } - cs_md5_init(&c1); + *(int *) c->user_data = (memcmp(sig1, sig2, sizeof(sig1)) == 0) ? 1 : 2; break; } } @@ -2021,27 +1984,16 @@ static const char *test_http_serve_file_streaming(void) { struct mg_mgr mgr; struct mg_connection *lc, *nc; const char *local_addr = "127.0.0.1:7732"; - struct chunk_clt_ctx ctx = {0, 0, 0, 0, 0}; - + int status = 0; mg_mgr_init(&mgr, NULL); - ASSERT((lc = mg_bind(&mgr, local_addr, file_srv)) != NULL); + ASSERT((lc = mg_bind(&mgr, local_addr, srv1)) != NULL); mg_set_protocol_http_websocket(lc); - ASSERT((nc = mg_connect(&mgr, local_addr, chunk_clt)) != NULL); + ASSERT((nc = mg_connect(&mgr, local_addr, srv2)) != NULL); mg_set_protocol_http_websocket(nc); - nc->user_data = &ctx; - mg_printf(nc, - "GET / HTTP/1.0\r\n" - "Content-Length: 0\r\n" - "Connection: keep-alive\r\n" - "\r\n"); - poll_until(&mgr, 5, c_int_ne, &ctx.status, (void *) 0); - ASSERT_EQ(ctx.status, 1); - ASSERT_EQ(nc->flags & (MG_F_CLOSE_IMMEDIATELY | MG_F_SEND_AND_CLOSE), 0); - memset(&ctx, 0, sizeof(ctx)); - ctx.seq = 1; - mg_printf(nc, "GET / HTTP/1.1\r\nConnection: close\r\n\r\n"); - poll_until(&mgr, 5, c_int_ne, &ctx.status, (void *) 0); - ASSERT_EQ(ctx.status, 1); + nc->user_data = &status; + mg_printf(nc, "GET / HTTP/1.0\r\n\r\n"); + poll_until(&mgr, 30, c_int_ne, &status, (void *) 0); + ASSERT_EQ(status, 1); mg_mgr_free(&mgr); return NULL; } @@ -2053,11 +2005,9 @@ static const char *test_http(void) { char buf[50] = "", status[100] = "", mime1[20] = "", mime2[100] = ""; char opt_buf[1024] = ""; const char *opt_answer = - "HTTP/1.1 200 OK\r\n" - "Server: Mongoose/" MG_VERSION - "\r\n" - "Allow: GET, POST, HEAD, CONNECT, OPTIONS, MKCOL, PUT, DELETE, PROPFIND, " - "MOVE"; + "HTTP/1.1 200 OK\r\nServer: Mongoose/" MG_VERSION + "\r\nAllow: GET, POST, HEAD, CONNECT, OPTIONS, MKCOL, " + "PUT, DELETE, PROPFIND, MOVE"; char url[1000]; mg_mgr_init(&mgr, NULL); @@ -2135,7 +2085,6 @@ static void http_pipeline_handler(struct mg_connection *c, int ev, "Content-Type: text/plain\r\nContent-Length: 5\r\n"); mg_printf(c, "Hello"); *status = *status + 1; - c->flags |= MG_F_SEND_AND_CLOSE; } else if (ev == MG_EV_HTTP_REPLY) { /* Client reply handler */ *status = *status + 10; @@ -2153,12 +2102,7 @@ static const char *test_http_pipeline(void) { mg_set_protocol_http_websocket(lc); ASSERT(nc1 = mg_connect(&mgr, local_addr, http_pipeline_handler)); mg_set_protocol_http_websocket(nc1); - mg_printf(nc1, - "GET /foo HTTP/1.1\r\n" - "Content-Length: 0\r\n" - "\r\n" - "GET /bar HTTP/1.1\r\n" - "\r\n"); + mg_printf(nc1, "GET / HTTP/1.1\r\n\r\nGET / HTTP/1.1\r\n\r\n"); poll_until(&mgr, 1, c_int_eq, &status, (void *) 22); ASSERT_EQ(status, 22); mg_mgr_free(&mgr); @@ -4281,7 +4225,6 @@ static const char *test_http_multipart2(void) { mbuf_init(&mpd.res, 0); mg_mgr_init(&mgr, NULL); - /* mgr.hexdump_file = "-"; */ nc_listen = mg_bind(&mgr, "8765", cb_mp_srv); nc_listen->user_data = &mpd; @@ -4333,12 +4276,10 @@ static const char *test_http_multipart2(void) { mbuf_init(&mpd.res, 0); mg_printf(c, - "POST /test HTTP/1.1\r\n" - "Host: 127.0.0.1:8766\r\n" - "Content-Length: %" SIZE_T_FMT - "\r\n" - "Connection: keep-alive\r\n" - "Content-Type: multipart/form-data; boundary=Asrf456BGe4h\r\n%s", + "POST /test HTTP/1.1\r\nHost: 127.0.0.1:8766\r\nContent-Length: " + "%" SIZE_T_FMT + "\r\nConnection: keep-alive\r\nContent-Type: multipart/form-data; " + "boundary=Asrf456BGe4h\r\n%s", strlen(multi_part_req), multi_part_req); poll_until(&mgr, 3, c_int_eq, &mpd.request_end, (void *) 1); @@ -4653,13 +4594,7 @@ static const char *test_dns_encode_name(void) { struct mbuf mb; mbuf_init(&mb, 0); ASSERT_EQ(mg_dns_encode_name(&mb, "www.cesanta.com.net.org", 15), 17); - ASSERT_STREQ_NZ(mb.buf, - "\x03" - "www" - "\x07" - "cesanta" - "\x03" - "com"); + ASSERT_STREQ_NZ(mb.buf, "\x03" "www" "\x07" "cesanta" "\x03" "com"); mbuf_free(&mb); return NULL; } @@ -5735,7 +5670,9 @@ static const char *test_socks(void) { char status[100] = ""; mg_mgr_init(&mgr, NULL); - /* mgr.hexdump_file = "-"; */ +#if 0 + mgr.hexdump_file = "-"; +#endif #if 1 cs_log_set_level(LL_INFO);