static void mupnp_ssdpresponse_server_thread(mUpnpThread* thread) { mUpnpSSDPResponseServer* server; mUpnpSSDPPacket* ssdpPkt; void* userData; mupnp_log_debug_l4("Entering...\n"); server = (mUpnpSSDPResponseServer*)mupnp_thread_getuserdata(thread); userData = mupnp_ssdpresponse_server_getuserdata(server); if (mupnp_ssdpresponse_server_isopened(server) == false) return; ssdpPkt = mupnp_ssdp_packet_new(); mupnp_ssdp_packet_setuserdata(ssdpPkt, userData); while (mupnp_thread_isrunnable(thread) == true) { if (mupnp_httpu_socket_recv(server->httpuSock, ssdpPkt) <= 0) break; mupnp_ssdp_packet_print(ssdpPkt); mupnp_ssdpresponse_server_performlistener(server, ssdpPkt); mupnp_ssdp_packet_clear(ssdpPkt); } mupnp_ssdp_packet_delete(ssdpPkt); mupnp_log_debug_l4("Leaving...\n"); }
static void mupnp_http_server_thread(mUpnpThread *thread) { mUpnpHttpServer *httpServer; mUpnpThread *httpClientThread; mUpnpHttpServerClientData *clientData; mUpnpSocket *serverSock; mUpnpSocket *clientSock; mupnp_log_debug_l4("Entering...\n"); httpServer = (mUpnpHttpServer *)mupnp_thread_getuserdata(thread); if (mupnp_http_server_isopened(httpServer) == false) return; serverSock = httpServer->sock; while (mupnp_thread_isrunnable(thread) == true) { clientSock = mupnp_socket_stream_new(); if (mupnp_socket_accept(serverSock, clientSock) == false) { mupnp_socket_delete(clientSock); break; } mupnp_socket_settimeout(clientSock, mupnp_http_server_gettimeout(httpServer)); clientData = mupnp_http_server_clientdata_new(httpServer, clientSock); httpClientThread = mupnp_thread_new(); mupnp_thread_setaction(httpClientThread, mupnp_http_server_clientthread); mupnp_thread_setuserdata(httpClientThread, clientData); /**** Thanks for Makela Aapo (10/31/05) ****/ mupnp_http_server_lock(httpServer); mupnp_threadlist_add(httpServer->clientThreads, httpClientThread); mupnp_http_server_unlock(httpServer); mupnp_thread_start(httpClientThread); } mupnp_log_debug_l4("Leaving...\n"); }
static void mupnp_http_server_clientthread(mUpnpThread *thread) { mUpnpHttpServerClientData *clientData; mUpnpHttpServer *httpServer; mUpnpSocket *clientSock; void *httpServerUserData; mUpnpHttpRequest *httpReq; char *version = NULL; mupnp_log_debug_l4("Entering...\n"); clientData = (mUpnpHttpServerClientData *)mupnp_thread_getuserdata(thread); httpServer = clientData->httpServer; clientSock = clientData->clientSock; httpServerUserData = mupnp_http_server_getuserdata(httpServer); httpReq = mupnp_http_request_new(); mupnp_http_request_setsocket(httpReq, clientSock); /**** Thanks for Makela Aapo (10/31/05) ****/ while (mupnp_http_request_read(httpReq, clientSock) == true && mupnp_thread_isrunnable(thread) == true) { /* Check some validity of the request */ version = mupnp_http_request_getversion(httpReq); if (mupnp_strcmp(version, MUPNP_HTTP_VER11) == 0) { /* According to HTTP/1.1 spec, we must not tolerate HTTP/1.1 request without HOST-header */ if (mupnp_http_request_gethost(httpReq) == NULL) { mupnp_http_request_postbadrequest(httpReq); continue; } } if (httpServer->listener != NULL) { mupnp_http_request_setuserdata(httpReq, httpServerUserData); httpServer->listener(httpReq); } /* Close connection according to HTTP version and headers */ if (mupnp_strcmp(version, MUPNP_HTTP_VER10) == 0) { /* Terminate connection after HTTP/1.0 request */ break; } /* We are having HTTP/1.1 or better => terminate, if requested */ if (mupnp_http_request_iskeepaliveconnection(httpReq) == false) { break; } } mupnp_log_debug_s("Dropping HTTP client\n"); mupnp_http_request_delete(httpReq); mupnp_socket_close(clientSock); mupnp_socket_delete(clientSock); mupnp_http_server_clientdata_delete(clientData); mupnp_thread_setuserdata(thread, NULL); // This code frequently crashes. mutex lock referencing free'd memory. mupnp_http_server_lock(httpServer); mupnp_thread_remove(thread); mupnp_http_server_unlock(httpServer); mupnp_log_debug_l4("Leaving...\n"); mupnp_thread_delete(thread); }