libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit b49eb1361d97478f5ae80f6b00e781a38aaee301
parent d74282806eb98340cea23a4b8db8da3c16f5e3c6
Author: Andrey Uzunov <andrey.uzunov@gmail.com>
Date:   Tue,  3 Sep 2013 10:48:18 +0000

mhd2spdy: segfaults on cleaning up proxy structs fixed

Diffstat:
Msrc/examples/mhd2spdy.c | 5+++--
Msrc/examples/mhd2spdy_http.c | 104+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/examples/mhd2spdy_spdy.c | 77+++++++++++++++++++++++++++++++++++++++++++++++------------------------------
3 files changed, 107 insertions(+), 79 deletions(-)

diff --git a/src/examples/mhd2spdy.c b/src/examples/mhd2spdy.c @@ -23,6 +23,7 @@ * TODOs: * - non blocking SSL connect * - check certificate + * - on closing spdy session, close sockets for all requests * @author Andrey Uzunov */ @@ -87,7 +88,7 @@ run_everything () glob_opt.streams_opened = 0; glob_opt.responses_pending = 0; - glob_opt.global_memory = 0; + //glob_opt.global_memory = 0; srand(time(NULL)); @@ -217,7 +218,7 @@ run_everything () EVP_cleanup(); PRINT_INFO2("spdy streams: %i; http requests: %i", glob_opt.streams_opened, glob_opt.responses_pending); - PRINT_INFO2("memory allocated %zu bytes", glob_opt.global_memory); + //PRINT_INFO2("memory allocated %zu bytes", glob_opt.global_memory); print_stat(); diff --git a/src/examples/mhd2spdy_http.c b/src/examples/mhd2spdy_http.c @@ -38,7 +38,7 @@ const char * uri) //TODO not freed once in a while if(NULL == (http_uri = au_malloc(sizeof(struct HTTP_URI )))) - DIE("no memory"); + return NULL; http_uri->uri = strdup(uri); return http_uri; } @@ -94,7 +94,8 @@ http_cb_response (void *cls, if(proxy->spdy_error) return MHD_CONTENT_READER_END_WITH_ERROR; - if(0 == proxy->http_body_size &&( proxy->done || !proxy->spdy_active)){ + if(0 == proxy->http_body_size && (proxy->done || !proxy->spdy_active)) + { PRINT_INFO("sent end of stream"); return MHD_CONTENT_READER_END_OF_STREAM; } @@ -124,7 +125,7 @@ http_cb_response (void *cls, if(NULL == (newbody = au_malloc(proxy->http_body_size - max))) { PRINT_INFO("no memory"); - return -2; + return MHD_CONTENT_READER_END_WITH_ERROR; } memcpy(newbody, proxy->http_body + max, proxy->http_body_size - max); } @@ -147,12 +148,6 @@ http_cb_response (void *cls, static void http_cb_response_done(void *cls) { - - //TODO - /*struct Proxy *proxy = (struct Proxy *)cls; - - PRINT_INFO2("http_cb_response_done for %s", proxy->url); - */ } @@ -175,15 +170,16 @@ http_cb_request (void *cls, struct Proxy *proxy; struct SPDY_Headers spdy_headers; bool with_body = false; - - //PRINT_INFO2("request cb %i; %s", *ptr,url); + struct HTTP_URI *http_uri; - if (NULL == *ptr) - DIE("ptr is null"); - struct HTTP_URI *http_uri = (struct HTTP_URI *)*ptr; + if (NULL == ptr || NULL == *ptr) + return MHD_NO; + + http_uri = (struct HTTP_URI *)*ptr; if(NULL == http_uri->proxy) - { + { + //first call for this request if (0 != strcmp (method, MHD_HTTP_METHOD_GET) && 0 != strcmp (method, MHD_HTTP_METHOD_POST)) { free(http_uri->uri); @@ -207,12 +203,15 @@ http_cb_request (void *cls, } proxy = http_uri->proxy; + + if(proxy->spdy_error || proxy->http_error) + return MHD_NO; // handled at different place TODO? leaks? if(proxy->spdy_active) { if(0 == strcmp (method, MHD_HTTP_METHOD_POST)) { - PRINT_INFO("POST processing"); + PRINT_INFO("POST processing"); int rc= spdylay_session_resume_data(proxy->spdy_connection->session, proxy->stream_id); PRINT_INFO2("rc is %i stream is %i", rc, proxy->stream_id); @@ -231,24 +230,8 @@ http_cb_request (void *cls, PRINT_INFO("not enough memory (malloc/realloc returned NULL)"); return MHD_NO; } - /* - if(NULL == proxy->received_body) - proxy->received_body = malloc(*upload_data_size); - else - proxy->received_body = realloc(proxy->received_body, proxy->received_body_size + *upload_data_size); - if(NULL == proxy->received_body) - { - //TODO handle it better? - PRINT_INFO("not enough memory (realloc returned NULL)"); - return MHD_NO; - } - - memcpy(proxy->received_body + proxy->received_body_size, upload_data, *upload_data_size); - proxy->received_body_size += *upload_data_size; - */ - *upload_data_size = 0; - //raise(SIGINT); + *upload_data_size = 0; return MHD_YES; } @@ -257,12 +240,15 @@ http_cb_request (void *cls, PRINT_INFO("unnecessary call to http_cb_request"); return MHD_YES; } + + //second call for this request PRINT_INFO2("received request for '%s %s %s'", method, http_uri->uri, version); proxy->url = http_uri->uri; - with_body = 0 == strcmp (method, MHD_HTTP_METHOD_POST) && 0 != strcmp ("0", + with_body = 0 == strcmp (method, MHD_HTTP_METHOD_POST) + && 0 != strcmp ("0", MHD_lookup_connection_value(connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_CONTENT_LENGTH)); PRINT_INFO2("body will be sent %i", with_body); @@ -271,7 +257,6 @@ http_cb_request (void *cls, if(ret != 0) DIE("parse_uri failed"); proxy->http_uri = http_uri; - proxy->spdy_active = true; spdy_headers.num = MHD_get_connection_values (connection, MHD_HEADER_KIND, @@ -298,7 +283,7 @@ http_cb_request (void *cls, if(0 != spdy_request(spdy_headers.nv, proxy, with_body)) { free(spdy_headers.nv); - free_proxy(proxy); + //free_proxy(proxy); return MHD_NO; } @@ -310,7 +295,7 @@ http_cb_request (void *cls, proxy, &http_cb_response_done); - if (proxy->http_response == NULL) + if (NULL == proxy->http_response) DIE("no response"); if(MHD_NO == MHD_add_response_header (proxy->http_response, @@ -323,6 +308,8 @@ http_cb_request (void *cls, "Keep-Alive", "timeout=5, max=100")) PRINT_INFO("SPDY_name_value_add failed: "); + proxy->spdy_active = true; + return MHD_YES; } @@ -333,6 +320,9 @@ http_create_response(struct Proxy* proxy, { size_t i; + if(!proxy->http_active) + return; + for(i = 0; nv[i]; i += 2) { if(0 == strcmp(":status", nv[i])) { @@ -363,10 +353,13 @@ http_create_response(struct Proxy* proxy, if(MHD_NO == MHD_queue_response (proxy->http_connection, proxy->status, proxy->http_response)){ PRINT_INFO("No queue"); - abort(); + //TODO + //abort(); + proxy->http_error = true; } MHD_destroy_response (proxy->http_response); + proxy->http_response = NULL; } void @@ -375,11 +368,22 @@ http_cb_request_completed (void *cls, void **con_cls, enum MHD_RequestTerminationCode toe) { - struct HTTP_URI *http_uri = (struct HTTP_URI *)*con_cls; - if(NULL == http_uri) return; - struct Proxy *proxy = (struct Proxy *)http_uri->proxy; + struct HTTP_URI *http_uri; + struct Proxy *proxy; + + http_uri = (struct HTTP_URI *)*con_cls; + if(NULL == http_uri) + return; + proxy = (struct Proxy *)http_uri->proxy; + assert(NULL != proxy); - PRINT_INFO2("http_cb_request_completed %i for %s",toe, http_uri->uri); + PRINT_INFO2("http_cb_request_completed %i for %s; id %i",toe, http_uri->uri, proxy->id); + + if(NULL != proxy->http_response) + { + MHD_destroy_response (proxy->http_response); + proxy->http_response = NULL; + } if(proxy->spdy_active) { @@ -387,14 +391,20 @@ http_cb_request_completed (void *cls, if(MHD_REQUEST_TERMINATED_COMPLETED_OK != toe) { proxy->http_error = true; - assert(proxy->stream_id > 0); - //send RST_STREAM_STATUS_CANCEL - PRINT_INFO("send rst_stream" ); - spdylay_submit_rst_stream(proxy->spdy_connection->session, proxy->stream_id, 5); + if(proxy->stream_id > 0 && NULL != proxy->spdy_connection->session) + { + //send RST_STREAM_STATUS_CANCEL + PRINT_INFO2("send rst_stream %i",proxy->spdy_active ); + spdylay_submit_rst_stream(proxy->spdy_connection->session, proxy->stream_id, 5); + } } } else - free_proxy(proxy); + { + PRINT_INFO2("proxy free http id %i ", proxy->id); + //DLL_remove(proxy->spdy_connection->proxies_head, proxy->spdy_connection->proxies_tail, proxy); + //free_proxy(proxy); + } --glob_opt.responses_pending; } diff --git a/src/examples/mhd2spdy_spdy.c b/src/examples/mhd2spdy_spdy.c @@ -370,14 +370,19 @@ spdy_cb_on_stream_close(spdylay_session *session, --glob_opt.streams_opened; --proxy->spdy_connection->streams_opened; - PRINT_INFO2("closing stream: str opened %i", glob_opt.streams_opened); - - DLL_remove(proxy->spdy_connection->proxies_head, proxy->spdy_connection->proxies_tail, proxy); - + PRINT_INFO2("closing stream: str opened %i; remove proxy %i", glob_opt.streams_opened, proxy->id); + if(proxy->http_active) + { proxy->spdy_active = false; + //DLL_remove(proxy->spdy_connection->proxies_head, proxy->spdy_connection->proxies_tail, proxy); + } else - free_proxy(proxy); + { + PRINT_INFO2("proxy free close id %i ", proxy->id); + //DLL_remove(proxy->spdy_connection->proxies_head, proxy->spdy_connection->proxies_tail, proxy); + //free_proxy(proxy); + } } @@ -615,6 +620,7 @@ spdy_socket_set_tcp_nodelay(int fd) /* * Update |pollfd| based on the state of |connection|. */ + /* void spdy_ctl_poll(struct pollfd *pollfd, struct SPDY_Connection *connection) @@ -630,7 +636,7 @@ spdy_ctl_poll(struct pollfd *pollfd, { pollfd->events |= POLLOUT; } -} +}*/ /* @@ -766,12 +772,26 @@ spdy_connect(const struct URI *uri, void spdy_free_connection(struct SPDY_Connection * connection) { + struct Proxy *proxy; + if(NULL != connection) { + for(proxy = connection->proxies_head; NULL != proxy; proxy=proxy->next) + { + DLL_remove(connection->proxies_head, connection->proxies_tail, proxy); + proxy->spdy_active = false; + proxy->spdy_error = true; + PRINT_INFO2("spdy_free_connection for id %i", proxy->id); + if(!proxy->http_active) + { + //free_proxy(proxy); + } + } spdylay_session_del(connection->session); SSL_free(connection->ssl); free(connection->host); - free(connection); + //free(connection); + connection->session = NULL; } } @@ -835,12 +855,15 @@ spdy_request(const char **nv, if(ret != 0) { spdy_diec("spdylay_spdy_submit_request", ret); } + PRINT_INFO2("adding proxy %i", proxy->id); + if(NULL != connection->proxies_head) + PRINT_INFO2("before proxy %i", connection->proxies_head->id); DLL_insert(connection->proxies_head, connection->proxies_tail, proxy); return ret; } - +/* void spdy_get_pollfdset(struct pollfd fds[], struct SPDY_Connection *connections[], @@ -864,6 +887,7 @@ spdy_get_pollfdset(struct pollfd fds[], for(proxy = glob_opt.spdy_connection->proxies_head; NULL != proxy; proxy=proxy->next) { + abort(); DLL_remove(glob_opt.spdy_connection->proxies_head, glob_opt.spdy_connection->proxies_tail, proxy); proxy->spdy_active = false; } @@ -893,6 +917,7 @@ spdy_get_pollfdset(struct pollfd fds[], for(proxy = connection->proxies_head; NULL != proxy; proxy=proxy->next) { + abort(); DLL_remove(connection->proxies_head, connection->proxies_tail, proxy); proxy->spdy_active = false; } @@ -910,7 +935,7 @@ spdy_get_pollfdset(struct pollfd fds[], //, "TODO max num of conn reached; close something" assert(NULL == connection); } - +*/ int spdy_get_selectfdset(fd_set * read_fd_set, @@ -921,7 +946,7 @@ spdy_get_selectfdset(fd_set * read_fd_set, nfds_t *real_size) { struct SPDY_Connection *connection; - struct Proxy *proxy; + struct SPDY_Connection *next_connection; bool ret; int maxfd = 0; @@ -936,14 +961,9 @@ spdy_get_selectfdset(fd_set * read_fd_set, except_fd_set, glob_opt.spdy_connection); if(!ret) { - //PRINT_INFO("TODO drop connection"); glob_opt.streams_opened -= glob_opt.spdy_connection->streams_opened; - for(proxy = glob_opt.spdy_connection->proxies_head; NULL != proxy; proxy=proxy->next) - { - DLL_remove(glob_opt.spdy_connection->proxies_head, glob_opt.spdy_connection->proxies_tail, proxy); - proxy->spdy_active = false; - } + PRINT_INFO("spdy_free_connection in spdy_get_selectfdset"); spdy_free_connection(glob_opt.spdy_connection); glob_opt.spdy_connection = NULL; } @@ -963,18 +983,15 @@ spdy_get_selectfdset(fd_set * read_fd_set, ret = spdy_ctl_select(read_fd_set, write_fd_set, except_fd_set, connection); + + next_connection = connection->next; if(!ret) { - //PRINT_INFO("TODO drop connection"); glob_opt.streams_opened -= connection->streams_opened; DLL_remove(glob_opt.spdy_connections_head, glob_opt.spdy_connections_tail, connection); glob_opt.total_spdy_connections--; - for(proxy = connection->proxies_head; NULL != proxy; proxy=proxy->next) - { - DLL_remove(connection->proxies_head, connection->proxies_tail, proxy); - proxy->spdy_active = false; - } + PRINT_INFO("spdy_free_connection in spdy_get_selectfdset"); spdy_free_connection(connection); } else @@ -983,7 +1000,7 @@ spdy_get_selectfdset(fd_set * read_fd_set, ++(*real_size); if(maxfd < connection->fd) maxfd = connection->fd; } - connection = connection->next; + connection = next_connection; } //, "TODO max num of conn reached; close something" @@ -992,7 +1009,7 @@ spdy_get_selectfdset(fd_set * read_fd_set, return maxfd; } - +/* void spdy_run(struct pollfd fds[], struct SPDY_Connection *connections[], @@ -1029,9 +1046,13 @@ spdy_run(struct pollfd fds[], } for(proxy = connections[i]->proxies_head; NULL != proxy; proxy=proxy->next) { + abort(); DLL_remove(connections[i]->proxies_head, connections[i]->proxies_tail, proxy); proxy->spdy_active = false; + proxy->spdy_error = true; + PRINT_INFO2("spdy_free_connection for id %i", proxy->id); } + PRINT_INFO("spdy_free_connection in loop"); spdy_free_connection(connections[i]); } } @@ -1039,6 +1060,7 @@ spdy_run(struct pollfd fds[], PRINT_INFO("not called"); } } +*/ void spdy_run_select(fd_set * read_fd_set, @@ -1049,7 +1071,6 @@ spdy_run_select(fd_set * read_fd_set, { int i; int ret; - struct Proxy *proxy; for(i=0; i<size; ++i) { @@ -1071,11 +1092,7 @@ spdy_run_select(fd_set * read_fd_set, DLL_remove(glob_opt.spdy_connections_head, glob_opt.spdy_connections_tail, connections[i]); glob_opt.total_spdy_connections--; } - for(proxy = connections[i]->proxies_head; NULL != proxy; proxy=proxy->next) - { - DLL_remove(connections[i]->proxies_head, connections[i]->proxies_tail, proxy); - proxy->spdy_active = false; - } + PRINT_INFO("in spdy_run_select"); spdy_free_connection(connections[i]); } }