From df5cfb2c91c000312f8f7b61f33689d0c0b78e49 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Tue, 12 Mar 2019 18:15:02 -0700 Subject: [PATCH] fixes memory leaks in http i/o drivers --- include/noun/retrieve.h | 5 +++ include/vere/vere.h | 4 +- noun/retrieve.c | 10 +++++ vere/cttp.c | 25 +++++------ vere/http.c | 93 +++++++++++++++++++++++++---------------- vere/reck.c | 4 +- 6 files changed, 90 insertions(+), 51 deletions(-) diff --git a/include/noun/retrieve.h b/include/noun/retrieve.h index 4a9398c0b3..f47099d3a0 100644 --- a/include/noun/retrieve.h +++ b/include/noun/retrieve.h @@ -139,6 +139,11 @@ c3_o u3r_sing(u3_noun a, u3_noun b); + /* u3rz_sing(): transferring u3r_sing + */ + c3_o + u3rz_sing(u3_noun a, u3_noun b); + /* u3r_sung(): yes iff (a) and (b) are the same noun, unifying equals. ** ** Make sure you have no live, uncounted pointers to any noun diff --git a/include/vere/vere.h b/include/vere/vere.h index 743c3d57e0..b25b4603db 100644 --- a/include/vere/vere.h +++ b/include/vere/vere.h @@ -1060,13 +1060,13 @@ void u3_http_ef_that(u3_noun tat); - /* u3_http_ef_http_server: send %http-server to http. + /* u3_http_ef_http_server(): dispatch an %http-server effect from %light. */ void u3_http_ef_http_server(c3_l sev_l, c3_l coq_l, c3_l seq_l, - u3_noun rep); + u3_noun cad); /* u3_http_ef_thou(): send %thou effect to http. */ diff --git a/noun/retrieve.c b/noun/retrieve.c index 93c79c23da..279d812573 100644 --- a/noun/retrieve.c +++ b/noun/retrieve.c @@ -633,6 +633,16 @@ u3r_sing(u3_noun a, u3_noun b) } } +/* u3rz_sing(): transferring u3r_sing +*/ +c3_o +u3rz_sing(u3_noun a, u3_noun b) +{ + c3_o ret_o = u3r_sing(a, b); + u3z(a); u3z(b); + return ret_o; +} + /* u3r_sung(): yes iff (a) and (b) are the same noun, unifying equals. */ c3_o diff --git a/vere/cttp.c b/vere/cttp.c index 869b3cb8b6..dd3baf79c3 100644 --- a/vere/cttp.c +++ b/vere/cttp.c @@ -1061,26 +1061,27 @@ u3_cttp_ef_http_client(u3_noun fav) { u3_creq* ceq_u; - if (c3y == u3r_sing(u3i_string("request"), u3k(u3h(fav)))) { + if ( c3y == u3rz_sing(u3i_string("request"), u3k(u3h(fav))) ) { u3_noun p_fav, q_fav; - if (c3y == u3r_cell(u3t(fav), &p_fav, &q_fav)) { - ceq_u = _cttp_creq_new_from_request(u3r_word(0, p_fav), u3k(q_fav)); + u3x_cell(u3t(fav), &p_fav, &q_fav); - if ( ceq_u ) { - _cttp_creq_start(ceq_u); - } else { - uL(fprintf(uH, "cttp: strange request (unparsable url)\n")); - } - } else { - uL(fprintf(uH, "cttp: strange request (unparsable request)\n")); + ceq_u = _cttp_creq_new_from_request(u3r_word(0, p_fav), u3k(q_fav)); + + if ( ceq_u ) { + _cttp_creq_start(ceq_u); } - } else if (c3y == u3r_sing(u3i_string("cancel-request"), u3k(u3h(fav)))) { + else { + uL(fprintf(uH, "cttp: strange request (unparsable url)\n")); + } + } + else if ( c3y == u3rz_sing(u3i_string("cancel-request"), u3k(u3h(fav))) ) { ceq_u =_cttp_creq_find(u3r_word(0, u3t(fav))); if ( ceq_u ) { _cttp_creq_quit(ceq_u); } - } else { + } + else { uL(fprintf(uH, "cttp: strange request (unknown type)\n")); } diff --git a/vere/http.c b/vere/http.c index 4f364302fe..10223344b8 100644 --- a/vere/http.c +++ b/vere/http.c @@ -1566,72 +1566,95 @@ u3_http_ef_thou(c3_l sev_l, u3z(rep); } -/* responds to an incoming %http-server card from %light -*/ -void -u3_http_ef_http_server(c3_l sev_l, - c3_l coq_l, - c3_l seq_l, - u3_noun rep) +static u3_hreq* +_http_search_req(c3_l sev_l, + c3_l coq_l, + c3_l seq_l) { u3_http* htp_u; u3_hcon* hon_u; u3_hreq* req_u; c3_w bug_w = u3C.wag_w & u3o_verbose; - if (c3y == u3r_sing(u3i_string("set-config"), u3k(u3h(rep)))) { - // sets server configuration - u3_http_ef_form(u3k(u3t(rep))); - } - else if ( !(htp_u = _http_serv_find(sev_l)) ) { + if ( !(htp_u = _http_serv_find(sev_l)) ) { if ( bug_w ) { uL(fprintf(uH, "http: server not found: %x\r\n", sev_l)); } + return 0; } else if ( !(hon_u = _http_conn_find(htp_u, coq_l)) ) { if ( bug_w ) { uL(fprintf(uH, "http: connection not found: %x/%d\r\n", sev_l, coq_l)); } + return 0; } else if ( !(req_u = _http_req_find(hon_u, seq_l)) ) { if ( bug_w ) { uL(fprintf(uH, "http: request not found: %x/%d/%d\r\n", sev_l, coq_l, seq_l)); } + return 0; } - else if (c3y == u3r_sing(u3i_string("response"), u3k(u3h(rep)))) { - // responds to data - u3_noun response = u3t(rep); - if (c3y == u3r_sing(u3i_string("start"), u3k(u3h(response)))) { - // Separate the %start message into its components. - u3_noun response_header, data, complete; - u3_noun status, headers; - if (c3y == u3r_trel(u3t(response), &response_header, &data, &complete) && - c3y == u3r_cell(response_header, &status, &headers)) { + return req_u; +} + +/* u3_http_ef_http_server(): dispatch an %http-server effect from %light. +*/ +void +u3_http_ef_http_server(c3_l sev_l, + c3_l coq_l, + c3_l seq_l, + u3_noun cad) +{ + u3_hreq* req_u; + + u3_noun tag, dat; + u3x_cell(cad, &tag, &dat); + + // sets server configuration + // + if ( c3y == u3rz_sing(u3i_string("set-config"), u3k(tag)) ) { + u3_http_ef_form(u3k(dat)); + } + // responds to an open request + // + else if ( 0 != (req_u = _http_search_req(sev_l, coq_l, seq_l)) ) { + if ( c3y == u3rz_sing(u3i_string("response"), u3k(tag)) ) { + u3_noun response = dat; + + if ( c3y == u3rz_sing(u3i_string("start"), u3k(u3h(response))) ) { + // Separate the %start message into its components. + // + u3_noun response_header, data, complete; + u3_noun status, headers; + u3x_trel(u3t(response), &response_header, &data, &complete); + u3x_cell(response_header, &status, &headers); + _http_start_respond(req_u, u3k(status), u3k(headers), u3k(data), u3k(complete)); - } else { - uL(fprintf(uH, "http: strange %%start response\n")); } - } else if (c3y == u3r_sing(u3i_string("continue"), u3k(u3h(response)))) { - // Separate the %continue message into its components. - u3_noun data, complete; - if (c3y == u3r_cell(u3t(response), &data, &complete)) { + else if ( c3y == u3rz_sing(u3i_string("continue"), u3k(u3h(response))) ) { + // Separate the %continue message into its components. + // + u3_noun data, complete; + u3x_cell(u3t(response), &data, &complete); + _http_continue_respond(req_u, u3k(data), u3k(complete)); - } else { - uL(fprintf(uH, "http: strange %%continue response\n")); } - } else if (c3y == u3r_sing(u3i_string("cancel"), u3k(u3h(response)))) { - uL(fprintf(uH, "http: %%cancel not handled yet\n")); - } else { + else if (c3y == u3rz_sing(u3i_string("cancel"), u3k(u3h(response)))) { + uL(fprintf(uH, "http: %%cancel not handled yet\n")); + } + else { + uL(fprintf(uH, "http: strange response\n")); + } + } + else { uL(fprintf(uH, "http: strange response\n")); } - } else { - uL(fprintf(uH, "http: strange response\n")); } - u3z(rep); + u3z(cad); } /* _http_serv_start_all(): initialize and start servers based on saved config. diff --git a/vere/reck.c b/vere/reck.c index ffb22adfa3..629c66faef 100644 --- a/vere/reck.c +++ b/vere/reck.c @@ -266,7 +266,7 @@ _reck_kick_spec(u3_noun pox, u3_noun fav) if ( (c3n == u3r_cell(t_pox, &it_pox, &tt_pox)) ) { u3z(pox); u3z(fav); return c3n; } - else if (c3y == u3r_sing(u3i_string("http-server"), u3k(it_pox))) { + else if ( c3y == u3rz_sing(u3i_string("http-server"), u3k(it_pox)) ) { u3_noun pud = tt_pox; u3_noun p_pud, t_pud, tt_pud, q_pud, r_pud, s_pud; c3_l sev_l, coq_l, seq_l; @@ -303,7 +303,7 @@ _reck_kick_spec(u3_noun pox, u3_noun fav) u3z(pox); u3z(fav); return c3y; } - else if (c3y == u3r_sing(u3i_string("http-client"), u3k(it_pox))) { + else if ( c3y == u3rz_sing(u3i_string("http-client"), u3k(it_pox)) ) { u3_cttp_ef_http_client(u3k(fav)); u3z(pox); u3z(fav);