X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Fnetwork%2Fhttpd.c;h=b7252cfc8c2c2e677efcc43a6698fd264ec9b621;hb=a92c4fff8f7690496c9fa11cf99a7c494012c72f;hp=086432093b6d06545b7c7679a9a2c25cd6b0428f;hpb=52b0f7ea4eea7123432ed3cf0db42be3697fef92;p=vlc diff --git a/src/network/httpd.c b/src/network/httpd.c index 086432093b..b7252cfc8c 100644 --- a/src/network/httpd.c +++ b/src/network/httpd.c @@ -2,6 +2,7 @@ * httpd.c ***************************************************************************** * Copyright (C) 2004-2006 the VideoLAN team + * Copyright © 2004-2007 Rémi Denis-Courmont * $Id$ * * Authors: Laurent Aimar @@ -24,9 +25,6 @@ #include -#include -#include - #ifdef ENABLE_HTTPD #include @@ -35,6 +33,7 @@ #include #include #include +#include #include "../libvlc.h" #include @@ -94,10 +93,6 @@ struct httpd_host_t int *fds; unsigned nfd; - /* Statistics */ - counter_t *p_active_counter; - counter_t *p_total_counter; - vlc_mutex_t lock; /* all registered url (becarefull that 2 httpd_url_t could point at the same url) @@ -164,8 +159,6 @@ struct httpd_client_t int i_ref; - struct sockaddr_storage sock; - int i_sock_size; int fd; int i_mode; @@ -192,66 +185,9 @@ struct httpd_client_t /***************************************************************************** * Various functions *****************************************************************************/ -/*char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";*/ -static void b64_decode( char *restrict dest, const char *restrict src ) -{ - int i_level; - int last = 0; - int b64[256] = { - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 00-0F */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 10-1F */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, /* 20-2F */ - 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, /* 30-3F */ - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, /* 40-4F */ - 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, /* 50-5F */ - -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, /* 60-6F */ - 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1, /* 70-7F */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 80-8F */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 90-9F */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* A0-AF */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* B0-BF */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* C0-CF */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* D0-DF */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* E0-EF */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 /* F0-FF */ - }; - - for( i_level = 0; *src != '\0'; src++ ) - { - int c; - - c = b64[(unsigned int)*src]; - if( c == -1 ) - { - continue; - } - - switch( i_level ) - { - case 0: - i_level++; - break; - case 1: - *dest++ = ( last << 2 ) | ( ( c >> 4)&0x03 ); - i_level++; - break; - case 2: - *dest++ = ( ( last << 4 )&0xf0 ) | ( ( c >> 2 )&0x0f ); - i_level++; - break; - case 3: - *dest++ = ( ( last &0x03 ) << 6 ) | c; - i_level = 0; - } - last = c; - } - - *dest = '\0'; -} - static struct { - const char *psz_ext; + const char psz_ext[8]; const char *psz_mime; } http_mime[] = { @@ -294,7 +230,7 @@ static struct /* end */ - { NULL, NULL } + { "", "" } }; static const char *httpd_MimeFromUrl( const char *psz_url ) @@ -307,7 +243,7 @@ static const char *httpd_MimeFromUrl( const char *psz_url ) { int i; - for( i = 0; http_mime[i].psz_ext != NULL ; i++ ) + for( i = 0; http_mime[i].psz_ext[0] ; i++ ) { if( !strcasecmp( http_mime[i].psz_ext, psz_ext ) ) { @@ -338,7 +274,7 @@ static const http_status_info http_reason[] = { 206, "Partial Content" }, { 250, "Low on Storage Space" }, { 300, "Multiple Choices" }*/, - { 301, "Moved Permanently" }/*, + { 301, "Moved permanently" }/*, { 302, "Moved Temporarily" }, - aka "Found" { 303, "See Other" }, { 304, "Not Modified" }, @@ -348,7 +284,7 @@ static const http_status_info http_reason[] = { 401, "Unauthorized" }/*, { 402, "Payment Required" }*/, { 403, "Forbidden" }, - { 404, "Not Found" }/*, + { 404, "Not found" }/*, { 405, "Method Not Allowed" }, { 406, "Not Acceptable" }, { 407, "Proxy Authentication Required" }, @@ -365,7 +301,7 @@ static const http_status_info http_reason[] = { 451, "Parameter Not Understood" }, { 452, "Conference Not Found" }, { 453, "Not Enough Bandwidth" }*/, - { 454, "Session Not Found" }/*, + { 454, "Session not found" }/*, { 455, "Method Not Valid in This State" }, { 456, "Header Field Not Valid for Resource" }, { 457, "Invalid Range" }, @@ -374,11 +310,11 @@ static const http_status_info http_reason[] = { 460, "Only aggregate operation allowed" }*/, { 461, "Unsupported transport" }/*, { 462, "Destination unreachable" }*/, - { 500, "Internal Server Error" }, - { 501, "Not Implemented" }/*, - { 502, "Bad Gateway" }*/, - { 503, "Service Unavailable" }/*, - { 504, "Gateway Time-out" }, + { 500, "Internal server error" }, + { 501, "Not implemented" }/*, + { 502, "Bad gateway" }*/, + { 503, "Service unavailable" }/*, + { 504, "Gateway time-out" }, { 505, "Protocol version not supported" }*/, { 0, NULL } }; @@ -463,7 +399,6 @@ static int httpd_FileCallBack( httpd_callback_sys_t *p_sys, httpd_client_t *cl, answer->i_type = HTTPD_MSG_ANSWER; answer->i_status = 200; - answer->psz_status = strdup( "OK" ); httpd_MsgAdd( answer, "Content-type", "%s", file->psz_mime ); httpd_MsgAdd( answer, "Cache-Control", "%s", "no-cache" ); @@ -582,7 +517,6 @@ static int httpd_HandlerCallBack( httpd_callback_sys_t *p_sys, httpd_client_t *c /* We do it ourselves, thanks */ answer->i_status = 0; - answer->psz_status = NULL; if( httpd_ClientIP( cl, psz_remote_addr ) == NULL ) *psz_remote_addr = '\0'; @@ -631,20 +565,8 @@ static int httpd_HandlerCallBack( httpd_callback_sys_t *p_sys, httpd_client_t *c psz_headers = (char *)answer->p_body; i_headers = answer->i_body; } - switch( i_status ) - { - case 200: - psz_status = "OK"; - break; - case 401: - psz_status = "Unauthorized"; - break; - default: - if( (i_status < 0) || (i_status > 999) ) - i_status = 500; - psz_status = "Undefined"; - break; - } + + psz_status = httpd_ReasonFromCode( i_status ); answer->i_body = sizeof("HTTP/1.0 xxx \r\n") + strlen(psz_status) + i_headers - 1; psz_new = (char *)malloc( answer->i_body + 1); @@ -708,6 +630,7 @@ static int httpd_RedirectCallBack( httpd_callback_sys_t *p_sys, { httpd_redirect_t *rdir = (httpd_redirect_t*)p_sys; char *p_body; + (void)cl; if( answer == NULL || query == NULL ) { @@ -717,7 +640,6 @@ static int httpd_RedirectCallBack( httpd_callback_sys_t *p_sys, answer->i_version= query->i_version; answer->i_type = HTTPD_MSG_ANSWER; answer->i_status = 301; - answer->psz_status = strdup( "Moved Permanently" ); answer->i_body = httpd_HtmlError (&p_body, 301, rdir->psz_dst); answer->p_body = (unsigned char *)p_body; @@ -853,7 +775,6 @@ static int httpd_StreamCallBack( httpd_callback_sys_t *p_sys, answer->i_type = HTTPD_MSG_ANSWER; answer->i_status = 200; - answer->psz_status = strdup( "OK" ); if( query->i_type != HTTPD_MSG_HEAD ) { @@ -1056,8 +977,8 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, const char *psz_hostname, } /* to be sure to avoid multiple creation */ - var_Create( p_this->p_libvlc_global, "httpd_mutex", VLC_VAR_MUTEX ); - var_Get( p_this->p_libvlc_global, "httpd_mutex", &lockval ); + var_Create( p_this->p_libvlc, "httpd_mutex", VLC_VAR_MUTEX ); + var_Get( p_this->p_libvlc, "httpd_mutex", &lockval ); vlc_mutex_lock( lockval.p_address ); if( !(httpd = vlc_object_find( p_this, VLC_OBJECT_HTTPD, FIND_ANYWHERE )) ) @@ -1198,7 +1119,7 @@ void httpd_HostDelete( httpd_host_t *host ) vlc_value_t lockval; int i; - var_Get( httpd->p_libvlc_global, "httpd_mutex", &lockval ); + var_Get( httpd->p_libvlc, "httpd_mutex", &lockval ); vlc_mutex_lock( lockval.p_address ); host->i_ref--; @@ -1211,7 +1132,7 @@ void httpd_HostDelete( httpd_host_t *host ) } TAB_REMOVE( httpd->i_host, httpd->host, host ); - host->b_die = 1; + vlc_object_kill( host ); vlc_thread_join( host ); msg_Dbg( host, "HTTP host removed" ); @@ -1362,7 +1283,6 @@ void httpd_MsgInit( httpd_message_t *msg ) msg->i_version = -1; msg->i_status = 0; - msg->psz_status = NULL; msg->psz_url = NULL; msg->psz_args = NULL; @@ -1376,17 +1296,13 @@ void httpd_MsgInit( httpd_message_t *msg ) msg->i_body_offset = 0; msg->i_body = 0; - msg->p_body = 0; + msg->p_body = NULL; } void httpd_MsgClean( httpd_message_t *msg ) { int i; - if( msg->psz_status ) - { - free( msg->psz_status ); - } if( msg->psz_url ) { free( msg->psz_url ); @@ -1435,19 +1351,19 @@ void httpd_MsgAdd( httpd_message_t *msg, const char *name, const char *psz_value char *value = NULL; va_start( args, psz_value ); -#if defined(HAVE_VASPRINTF) && !defined(__APPLE__) && !defined(SYS_BEOS) - vasprintf( &value, psz_value, args ); -#else - { - int i_size = strlen( psz_value ) + 4096; /* FIXME stupid system */ - value = calloc( i_size, sizeof( char ) ); - vsnprintf( value, i_size, psz_value, args ); - value[i_size - 1] = 0; - } -#endif + if( vasprintf( &value, psz_value, args ) == -1 ) + value = NULL; va_end( args ); + if( value == NULL ) + return; + name = strdup( name ); + if( name == NULL ) + { + free( value ); + return; + } TAB_APPEND( msg->i_name, msg->name, (char*)name ); TAB_APPEND( msg->i_value, msg->value, value ); @@ -1508,9 +1424,7 @@ static void httpd_ClientClean( httpd_client_t *cl ) } } -static httpd_client_t *httpd_ClientNew( int fd, struct sockaddr_storage *sock, - int i_sock_size, - tls_session_t *p_tls, mtime_t now ) +static httpd_client_t *httpd_ClientNew( int fd, tls_session_t *p_tls, mtime_t now ) { httpd_client_t *cl = malloc( sizeof( httpd_client_t ) ); @@ -1518,8 +1432,6 @@ static httpd_client_t *httpd_ClientNew( int fd, struct sockaddr_storage *sock, cl->i_ref = 0; cl->fd = fd; - memcpy( &cl->sock, sock, sizeof( cl->sock ) ); - cl->i_sock_size = i_sock_size; cl->url = NULL; cl->p_tls = p_tls; @@ -1651,16 +1563,13 @@ static void httpd_ClientRecv( httpd_client_t *cl ) strtol( (char *)&cl->p_buffer[8], &p, 0 ); while( *p == ' ' ) - { p++; - } - cl->query.psz_status = strdup( p ); } else { static const struct { - const char *name; + const char name[16]; int i_type; int i_proto; } @@ -1678,16 +1587,16 @@ static void httpd_ClientRecv( httpd_client_t *cl ) { "HEAD", HTTPD_MSG_HEAD, HTTPD_PROTO_HTTP }, { "POST", HTTPD_MSG_POST, HTTPD_PROTO_HTTP }, - { NULL, HTTPD_MSG_NONE, HTTPD_PROTO_NONE } + { "", HTTPD_MSG_NONE, HTTPD_PROTO_NONE } }; - int i; + unsigned i; p = NULL; cl->query.i_type = HTTPD_MSG_NONE; /*fprintf( stderr, "received new request=%s\n", cl->p_buffer);*/ - for( i = 0; msg_type[i].name != NULL; i++ ) + for( i = 0; msg_type[i].name[0]; i++ ) { if( !strncmp( (char *)cl->p_buffer, msg_type[i].name, strlen( msg_type[i].name ) ) ) @@ -1893,9 +1802,9 @@ static void httpd_ClientSend( httpd_client_t *cl ) /* We need to create the header */ int i_size = 0; char *p; + const char *psz_status = httpd_ReasonFromCode( cl->answer.i_status ); - i_size = strlen( "HTTP/1.") + 10 + 10 + - strlen( cl->answer.psz_status ? cl->answer.psz_status : "" ) + 5; + i_size = strlen( "HTTP/1.") + 10 + 10 + strlen( psz_status ) + 5; for( i = 0; i < cl->answer.i_name; i++ ) { i_size += strlen( cl->answer.name[i] ) + 2 + @@ -1913,7 +1822,7 @@ static void httpd_ClientSend( httpd_client_t *cl ) p += sprintf( p, "%s/1.%d %d %s\r\n", cl->answer.i_proto == HTTPD_PROTO_HTTP ? "HTTP" : "RTSP", cl->answer.i_version, - cl->answer.i_status, cl->answer.psz_status ); + cl->answer.i_status, psz_status ); for( i = 0; i < cl->answer.i_name; i++ ) { p += sprintf( p, "%s: %s\r\n", cl->answer.name[i], @@ -2022,11 +1931,8 @@ static void httpd_ClientTlsHsOut( httpd_client_t *cl ) static void httpd_HostThread( httpd_host_t *host ) { tls_session_t *p_tls = NULL; - - host->p_total_counter = stats_CounterCreate( host, - VLC_VAR_INTEGER, STATS_COUNTER ); - host->p_active_counter = stats_CounterCreate( host, - VLC_VAR_INTEGER, STATS_COUNTER ); + counter_t *p_total_counter = stats_CounterCreate( host, VLC_VAR_INTEGER, STATS_COUNTER ); + counter_t *p_active_counter = stats_CounterCreate( host, VLC_VAR_INTEGER, STATS_COUNTER ); while( !host->b_die ) { @@ -2043,7 +1949,7 @@ static void httpd_HostThread( httpd_host_t *host ) struct pollfd ufd[host->nfd + host->i_client]; unsigned nfd; - for (nfd = 0; nfd < host->nfd; nfd++) + for( nfd = 0; nfd < host->nfd; nfd++ ) { ufd[nfd].fd = host->fds[nfd]; ufd[nfd].events = POLLIN; @@ -2064,7 +1970,7 @@ static void httpd_HostThread( httpd_host_t *host ) cl->i_activity_date+cl->i_activity_timeout < now) ) ) ) { httpd_ClientClean( cl ); - stats_UpdateInteger( host, host->p_active_counter, -1, NULL ); + stats_UpdateInteger( host, p_active_counter, -1, NULL ); TAB_REMOVE( host->i_client, host->client, cl ); free( cl ); i_client--; @@ -2136,7 +2042,6 @@ static void httpd_HostThread( httpd_host_t *host ) answer->i_type = HTTPD_MSG_ANSWER; answer->i_version= 0; answer->i_status = 200; - answer->psz_status = strdup( "Ok" ); answer->i_body = 0; answer->p_body = NULL; @@ -2173,7 +2078,6 @@ static void httpd_HostThread( httpd_host_t *host ) answer->i_type = HTTPD_MSG_ANSWER; answer->i_version= 0; answer->i_status = 501; - answer->psz_status = strdup( "Unimplemented" ); answer->i_body = httpd_HtmlError (&p, 501, NULL); answer->p_body = (uint8_t *)p; @@ -2201,54 +2105,51 @@ static void httpd_HostThread( httpd_host_t *host ) { char ip[NI_MAXNUMERICHOST]; - if( httpd_ClientIP( cl, ip ) != NULL ) + if( ( httpd_ClientIP( cl, ip ) == NULL ) + || ACL_Check( url->p_acl, ip ) ) { - if( ACL_Check( url->p_acl, ip ) ) - { - b_hosts_failed = VLC_TRUE; - break; - } - } - else b_hosts_failed = VLC_TRUE; + break; + } } if( answer && ( *url->psz_user || *url->psz_password ) ) { /* create the headers */ const char *b64 = httpd_MsgGet( query, "Authorization" ); /* BASIC id */ - char *auth; - char *id; + char *user = NULL, *pass = NULL; - asprintf( &id, "%s:%s", url->psz_user, url->psz_password ); if( b64 != NULL - && !strncasecmp( b64, "BASIC", 5 ) ) + && !strncasecmp( b64, "BASIC", 5 ) ) { b64 += 5; while( *b64 == ' ' ) - { b64++; + + user = vlc_b64_decode( b64 ); + if (user != NULL) + { + pass = strchr (user, ':'); + if (pass != NULL) + *pass++ = '\0'; } - auth = malloc( strlen(b64) + 1 ); - b64_decode( auth, b64 ); - } - else - { - auth = strdup( "" ); } - if( strcmp( id, auth ) ) + if ((user == NULL) || (pass == NULL) + || strcmp (user, url->psz_user) + || strcmp (pass, url->psz_password)) { - httpd_MsgAdd( answer, "WWW-Authenticate", "Basic realm=\"%s\"", url->psz_user ); + httpd_MsgAdd( answer, + "WWW-Authenticate", + "Basic realm=\"%s\"", + url->psz_user ); /* We fail for all url */ b_auth_failed = VLC_TRUE; - free( id ); - free( auth ); + free( user ); break; } - free( id ); - free( auth ); + free( user ); } if( !url->catch[i_msg].cb( url->catch[i_msg].p_sys, cl, answer, query ) ) @@ -2283,18 +2184,15 @@ static void httpd_HostThread( httpd_host_t *host ) if( b_hosts_failed ) { answer->i_status = 403; - answer->psz_status = strdup( "Forbidden" ); } else if( b_auth_failed ) { answer->i_status = 401; - answer->psz_status = strdup( "Authorization Required" ); } else { /* no url registered */ answer->i_status = 404; - answer->psz_status = strdup( "Not found" ); } answer->i_body = httpd_HtmlError (&p, @@ -2420,7 +2318,7 @@ static void httpd_HostThread( httpd_host_t *host ) vlc_mutex_unlock( &host->lock ); /* we will wait 100ms or 20ms (not too big 'cause HTTPD_CLIENT_WAITING) */ - switch (poll (ufd, nfd, b_low_delay ? 20 : 100)) + switch( poll( ufd, nfd, b_low_delay ? 20 : 100) ) { case -1: if (errno != EINTR) @@ -2433,81 +2331,19 @@ static void httpd_HostThread( httpd_host_t *host ) continue; } - now = mdate(); - - /* accept new connections */ - for (nfd = 0; nfd < host->nfd; nfd++) - { - assert (ufd[nfd].fd == host->fds[nfd]); - - if (ufd[nfd].revents == 0) - continue; - - struct sockaddr_storage addr; - socklen_t addrlen = sizeof (addr); - - int fd = accept (ufd[nfd].fd, (struct sockaddr *)&addr, &addrlen); - if (fd == -1) - continue; - - net_SetupSocket (fd); - - int i_state = 0; - - if (p_tls != NULL) - { - switch (tls_ServerSessionHandshake (p_tls, fd)) - { - case -1: - msg_Err( host, "Rejecting TLS connection" ); - net_Close (fd); - fd = -1; - p_tls = NULL; - break; - - case 1: /* missing input - most likely */ - i_state = HTTPD_CLIENT_TLS_HS_IN; - break; - - case 2: /* missing output */ - i_state = HTTPD_CLIENT_TLS_HS_OUT; - break; - } - - if (p_tls == NULL) - break; // wasted TLS session, cannot accept() anymore - } - - httpd_client_t *cl; - char ip[NI_MAXNUMERICHOST]; - stats_UpdateInteger( host, host->p_total_counter, 1, NULL ); - stats_UpdateInteger( host, host->p_active_counter, 1, NULL ); - cl = httpd_ClientNew( fd, &addr, addrlen, p_tls, now ); - httpd_ClientIP( cl, ip ); - msg_Dbg( host, "Connection from %s", ip ); - p_tls = NULL; - vlc_mutex_lock( &host->lock ); - TAB_APPEND( host->i_client, host->client, cl ); - vlc_mutex_unlock( &host->lock ); - cl->i_state = i_state; // override state for TLS - break; // cannot accept more than one because of TLS - } - - /* now try all others socket */ + /* Handle client sockets */ vlc_mutex_lock( &host->lock ); - + now = mdate(); for( int i_client = 0; i_client < host->i_client; i_client++ ) { httpd_client_t *cl = host->client[i_client]; - const struct pollfd *pufd = ufd + nfd; + const struct pollfd *pufd = &ufd[host->nfd + i_client]; - assert (pufd < ufd + (sizeof (ufd) / sizeof (ufd[0]))); + assert( pufd < &ufd[sizeof(ufd) / sizeof(ufd[0])] ); - if (cl->fd != pufd->fd) + if( cl->fd != pufd->fd ) continue; // we were not waiting for this client - nfd++; - - if (pufd->revents == 0) + if( pufd->revents == 0 ) continue; // no event received cl->i_activity_date = now; @@ -2537,10 +2373,70 @@ static void httpd_HostThread( httpd_host_t *host ) } } vlc_mutex_unlock( &host->lock ); + + /* Handle server sockets (accept new connections) */ + for( nfd = 0; nfd < host->nfd; nfd++ ) + { + httpd_client_t *cl; + int i_state = -1; + + assert (ufd[nfd].fd == host->fds[nfd]); + + if( ufd[nfd].revents == 0 ) + continue; + + /* */ + int kludge[] = { ufd[nfd].fd, -1 }; + int fd = net_Accept( host, kludge, 0 ); + if( fd < 0 ) + continue; + + if( p_tls != NULL ) + { + switch( tls_ServerSessionHandshake( p_tls, fd ) ) + { + case -1: + msg_Err( host, "Rejecting TLS connection" ); + net_Close( fd ); + fd = -1; + p_tls = NULL; + break; + + case 1: /* missing input - most likely */ + i_state = HTTPD_CLIENT_TLS_HS_IN; + break; + + case 2: /* missing output */ + i_state = HTTPD_CLIENT_TLS_HS_OUT; + break; + } + + if( (p_tls == NULL) != (host->p_tls == NULL) ) + break; // wasted TLS session, cannot accept() anymore + } + + stats_UpdateInteger( host, p_total_counter, 1, NULL ); + stats_UpdateInteger( host, p_active_counter, 1, NULL ); + cl = httpd_ClientNew( fd, p_tls, now ); + p_tls = NULL; + vlc_mutex_lock( &host->lock ); + TAB_APPEND( host->i_client, host->client, cl ); + vlc_mutex_unlock( &host->lock ); + if( i_state != -1 ) + cl->i_state = i_state; // override state for TLS + + if (host->p_tls != NULL) + break; // cannot accept further without new TLS session + } + } if( p_tls != NULL ) tls_ServerSessionClose( p_tls ); + if( p_total_counter ) + stats_CounterClean( p_total_counter ); + if( p_active_counter ) + stats_CounterClean( p_active_counter ); } #else /* ENABLE_HTTPD */