]> git.sesse.net Git - vlc/blobdiff - src/network/httpd.c
Fix the interpretation of command "help" by VLM.
[vlc] / src / network / httpd.c
index b85b8064952228bf97028a9c11375f4347ade22b..dad2c141d2f4d2cbc3b5d7feb1a4aa2ecff2fa29 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include <vlc/vlc.h>
+#include <vlc_httpd.h>
 
 #ifdef ENABLE_HTTPD
 
 #include <assert.h>
 
-#include <vlc_httpd.h>
 #include <vlc_network.h>
 #include <vlc_tls.h>
 #include <vlc_acl.h>
@@ -205,7 +209,8 @@ static struct
     { ".jpg",   "image/jpeg" },
     { ".jpeg",  "image/jpeg" },
     { ".png",   "image/png" },
-    { ".mpjpeg","multipart/x-mixed-replace; boundary=This Random String" },
+    /* same as modules/mux/mpjpeg.c here: */
+    { ".mpjpeg","multipart/x-mixed-replace; boundary=7b3cc56e5f51db803f790dad720ed50a" },
 
     /* media mime */
     { ".avi",   "video/avi" },
@@ -302,9 +307,9 @@ static const http_status_info http_reason[] =
     { 452, "Conference not found" },
     { 453, "Not enough bandwidth" },*/
     { 454, "Session not found" },
-  /*{ 455, "Method not valid in this State" },
+  /*{ 455, "Method not valid in this State" },*/
     { 456, "Header field not valid for resource" },
-    { 457, "Invalid range" },
+  /*{ 457, "Invalid range" },
     { 458, "Read-only parameter" },*/
     { 459, "Aggregate operation not allowed" },
     { 460, "Non-aggregate operation not allowed" },
@@ -437,7 +442,7 @@ httpd_FileCallBack( httpd_callback_sys_t *p_sys, httpd_client_t *cl,
     psz_connection = httpd_MsgGet( &cl->query, "Connection" );
     if( psz_connection != NULL )
     {
-        httpd_MsgAdd( answer, "Connection", psz_connection );
+        httpd_MsgAdd( answer, "Connection", "%s", psz_connection );
     }
 
     httpd_MsgAdd( answer, "Content-Length", "%d", answer->i_body );
@@ -484,14 +489,18 @@ httpd_file_t *httpd_FileNew( httpd_host_t *host,
     return file;
 }
 
-void httpd_FileDelete( httpd_file_t *file )
+httpd_file_sys_t *httpd_FileDelete( httpd_file_t *file )
 {
+    httpd_file_sys_t *p_sys = file->p_sys;
+
     httpd_UrlDelete( file->url );
 
     free( file->psz_url );
     free( file->psz_mime );
 
     free( file );
+
+    return p_sys;
 }
 
 /*****************************************************************************
@@ -618,10 +627,12 @@ httpd_handler_t *httpd_HandlerNew( httpd_host_t *host, const char *psz_url,
     return handler;
 }
 
-void httpd_HandlerDelete( httpd_handler_t *handler )
+httpd_handler_sys_t *httpd_HandlerDelete( httpd_handler_t *handler )
 {
+    httpd_handler_sys_t *p_sys = handler->p_sys;
     httpd_UrlDelete( handler->url );
     free( handler );
+    return p_sys;
 }
 
 /*****************************************************************************
@@ -807,7 +818,7 @@ static int httpd_StreamCallBack( httpd_callback_sys_t *p_sys,
 
         if( !strcmp( stream->psz_mime, "video/x-ms-asf-stream" ) )
         {
-            vlc_bool_t b_xplaystream = VLC_FALSE;
+            bool b_xplaystream = false;
             int i;
 
             httpd_MsgAdd( answer, "Content-type", "%s",
@@ -823,7 +834,7 @@ static int httpd_StreamCallBack( httpd_callback_sys_t *p_sys,
                 if( !strcasecmp( query->name[i],  "Pragma" ) &&
                     strstr( query->value[i], "xPlayStrm=1" ) )
                 {
-                    b_xplaystream = VLC_TRUE;
+                    b_xplaystream = true;
                 }
             }
 
@@ -886,11 +897,9 @@ httpd_stream_t *httpd_StreamNew( httpd_host_t *host,
 int httpd_StreamHeader( httpd_stream_t *stream, uint8_t *p_data, int i_data )
 {
     vlc_mutex_lock( &stream->lock );
-    if( stream->p_header )
-    {
-        free( stream->p_header );
-        stream->p_header = NULL;
-    }
+    free( stream->p_header );
+    stream->p_header = NULL;
+
     stream->i_header = i_data;
     if( i_data > 0 )
     {
@@ -942,9 +951,9 @@ void httpd_StreamDelete( httpd_stream_t *stream )
 {
     httpd_UrlDelete( stream->url );
     vlc_mutex_destroy( &stream->lock );
-    if( stream->psz_mime ) free( stream->psz_mime );
-    if( stream->p_header ) free( stream->p_header );
-    if( stream->p_buffer ) free( stream->p_buffer );
+    free( stream->psz_mime );
+    free( stream->p_header );
+    free( stream->p_buffer );
     free( stream );
 }
 
@@ -972,7 +981,7 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, const char *psz_hostname,
     httpd_host_t *host;
     tls_server_t *p_tls;
     char *psz_host;
-    vlc_value_t  lockval;
+    vlc_value_t  lockval, ptrval;
     int i;
 
     if( psz_hostname == NULL )
@@ -987,16 +996,20 @@ 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, "httpd_mutex", VLC_VAR_MUTEX );
+    var_Create( p_this->p_libvlc, "httpd_object", VLC_VAR_ADDRESS );
     var_Get( p_this->p_libvlc, "httpd_mutex", &lockval );
     vlc_mutex_lock( lockval.p_address );
+    var_Get( p_this->p_libvlc, "httpd_object", &ptrval );
 
-    if( !(httpd = vlc_object_find( p_this, VLC_OBJECT_HTTPD, FIND_ANYWHERE )) )
+    if( ptrval.p_address != NULL )
+        httpd = ptrval.p_address;
+    else
     {
         msg_Info( p_this, "creating httpd" );
         httpd = (httpd_t *)vlc_custom_create( p_this, sizeof (*httpd),
-                                              VLC_OBJECT_HTTPD,
+                                              VLC_OBJECT_GENERIC,
                                               psz_object_type );
-        if (httpd == NULL)
+        if( httpd == NULL )
         {
             vlc_mutex_unlock( lockval.p_address );
             free( psz_host );
@@ -1006,6 +1019,8 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, const char *psz_hostname,
         httpd->i_host = 0;
         httpd->host   = NULL;
 
+        ptrval.p_address = httpd;
+        var_Set( p_this->p_libvlc, "httpd_object", ptrval );
         vlc_object_yield( httpd );
         vlc_object_attach( httpd, p_this->p_libvlc );
     }
@@ -1063,8 +1078,9 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, const char *psz_hostname,
         goto error;
 
     vlc_object_lock( host );
-    if( vlc_object_waitpipe( host ) == -1 )
+    if( vlc_object_waitpipe( VLC_OBJECT( host ) ) == -1 )
     {
+        msg_Err( host, "signaling pipe error: %m" );
         vlc_object_unlock( host );
         goto error;
     }
@@ -1094,7 +1110,7 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, const char *psz_hostname,
 
     /* create the thread */
     if( vlc_thread_create( host, "httpd host thread", httpd_HostThread,
-                           VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
+                           VLC_THREAD_PRIORITY_LOW, false ) )
     {
         msg_Err( p_this, "cannot spawn http host thread" );
         goto error;
@@ -1112,7 +1128,7 @@ error:
     {
         vlc_object_release( httpd );
         vlc_object_detach( httpd );
-        vlc_object_destroy( httpd );
+        vlc_object_release( httpd );
     }
     vlc_mutex_unlock( lockval.p_address );
 
@@ -1120,7 +1136,7 @@ error:
     {
         net_ListenClose( host->fds );
         vlc_mutex_destroy( &host->lock );
-        vlc_object_destroy( host );
+        vlc_object_release( host );
     }
 
     if( p_tls != NULL )
@@ -1176,14 +1192,20 @@ void httpd_HostDelete( httpd_host_t *host )
     free( host->psz_hostname );
 
     vlc_mutex_destroy( &host->lock );
-    vlc_object_destroy( host );
+    vlc_object_release( host );
 
     vlc_object_release( httpd );
     if( httpd->i_host <= 0 )
     {
+        vlc_value_t ptrval;
+
         msg_Dbg( httpd, "no host left, stopping httpd" );
+
+        ptrval.p_address = NULL;
+        var_Set( httpd->p_libvlc, "httpd_object", ptrval );
         vlc_object_detach( httpd );
-        vlc_object_destroy( httpd );
+        vlc_object_release( httpd );
+
     }
     vlc_mutex_unlock( lockval.p_address );
 }
@@ -1191,7 +1213,7 @@ void httpd_HostDelete( httpd_host_t *host )
 /* register a new url */
 static httpd_url_t *httpd_UrlNewPrivate( httpd_host_t *host, const char *psz_url,
                                          const char *psz_user, const char *psz_password,
-                                         const vlc_acl_t *p_acl, vlc_bool_t b_check )
+                                         const vlc_acl_t *p_acl, bool b_check )
 {
     httpd_url_t *url;
     int         i;
@@ -1238,7 +1260,7 @@ httpd_url_t *httpd_UrlNew( httpd_host_t *host, const char *psz_url,
                            const vlc_acl_t *p_acl )
 {
     return httpd_UrlNewPrivate( host, psz_url, psz_user,
-                                psz_password, p_acl, VLC_FALSE );
+                                psz_password, p_acl, false );
 }
 
 httpd_url_t *httpd_UrlNewUnique( httpd_host_t *host, const char *psz_url,
@@ -1246,7 +1268,7 @@ httpd_url_t *httpd_UrlNewUnique( httpd_host_t *host, const char *psz_url,
                                  const vlc_acl_t *p_acl )
 {
     return httpd_UrlNewPrivate( host, psz_url, psz_user,
-                                psz_password, p_acl, VLC_TRUE );
+                                psz_password, p_acl, true );
 }
 
 /* register callback on a url */
@@ -1322,31 +1344,16 @@ void httpd_MsgClean( httpd_message_t *msg )
 {
     int i;
 
-    if( msg->psz_url )
-    {
-        free( msg->psz_url );
-    }
-    if( msg->psz_args )
-    {
-        free( msg->psz_args );
-    }
+    free( msg->psz_url );
+    free( msg->psz_args );
     for( i = 0; i < msg->i_name; i++ )
     {
         free( msg->name[i] );
         free( msg->value[i] );
     }
-    if( msg->name )
-    {
-        free( msg->name );
-    }
-    if( msg->value )
-    {
-        free( msg->value );
-    }
-    if( msg->p_body )
-    {
-        free( msg->p_body );
-    }
+    free( msg->name );
+    free( msg->value );
+    free( msg->p_body );
     httpd_MsgInit( msg );
 }
 
@@ -1397,7 +1404,7 @@ static void httpd_ClientInit( httpd_client_t *cl, mtime_t now )
     cl->i_buffer = 0;
     cl->p_buffer = malloc( cl->i_buffer_size );
     cl->i_mode   = HTTPD_CLIENT_FILE;
-    cl->b_read_waiting = VLC_FALSE;
+    cl->b_read_waiting = false;
 
     httpd_MsgInit( &cl->query );
     httpd_MsgInit( &cl->answer );
@@ -1436,11 +1443,8 @@ static void httpd_ClientClean( httpd_client_t *cl )
     httpd_MsgClean( &cl->answer );
     httpd_MsgClean( &cl->query );
 
-    if( cl->p_buffer )
-    {
-        free( cl->p_buffer );
-        cl->p_buffer = NULL;
-    }
+    free( cl->p_buffer );
+    cl->p_buffer = NULL;
 }
 
 static httpd_client_t *httpd_ClientNew( int fd, tls_session_t *p_tls, mtime_t now )
@@ -2024,10 +2028,11 @@ static void httpd_HostThread( httpd_host_t *host )
     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 );
     int evfd;
-    vlc_bool_t b_die = VLC_FALSE;
+    bool b_die;
 
     vlc_object_lock( host );
-    evfd = vlc_object_waitpipe( host );
+    evfd = vlc_object_waitpipe( VLC_OBJECT( host ) );
+    b_die = !vlc_object_alive( host );
     vlc_object_unlock( host );
 
     while( !b_die )
@@ -2055,7 +2060,7 @@ static void httpd_HostThread( httpd_host_t *host )
         /* add all socket that should be read/write and close dead connection */
         vlc_mutex_lock( &host->lock );
         mtime_t now = mdate();
-        vlc_bool_t b_low_delay = VLC_FALSE;
+        bool b_low_delay = false;
 
         for(int i_client = 0; i_client < host->i_client; i_client++ )
         {
@@ -2204,8 +2209,8 @@ static void httpd_HostThread( httpd_host_t *host )
                 }
                 else
                 {
-                    vlc_bool_t b_auth_failed = VLC_FALSE;
-                    vlc_bool_t b_hosts_failed = VLC_FALSE;
+                    bool b_auth_failed = false;
+                    bool b_hosts_failed = false;
 
                     /* Search the url and trigger callbacks */
                     for(int i = 0; i < host->i_url; i++ )
@@ -2223,7 +2228,7 @@ static void httpd_HostThread( httpd_host_t *host )
                                     if( ( httpd_ClientIP( cl, ip ) == NULL )
                                      || ACL_Check( url->p_acl, ip ) )
                                     {
-                                        b_hosts_failed = VLC_TRUE;
+                                        b_hosts_failed = true;
                                         break;
                                     }
                                 }
@@ -2259,7 +2264,7 @@ static void httpd_HostThread( httpd_host_t *host )
                                                       "Basic realm=\"%s\"",
                                                       url->psz_user );
                                         /* We fail for all url */
-                                        b_auth_failed = VLC_TRUE;
+                                        b_auth_failed = true;
                                         free( user );
                                         break;
                                     }
@@ -2329,9 +2334,9 @@ static void httpd_HostThread( httpd_host_t *host )
                 {
                     const char *psz_connection = httpd_MsgGet( &cl->answer, "Connection" );
                     const char *psz_query = httpd_MsgGet( &cl->query, "Connection" );
-                    vlc_bool_t b_connection = VLC_FALSE;
-                    vlc_bool_t b_keepalive = VLC_FALSE;
-                    vlc_bool_t b_query = VLC_FALSE;
+                    bool b_connection = false;
+                    bool b_keepalive = false;
+                    bool b_query = false;
 
                     cl->url = NULL;
                     if( psz_connection )
@@ -2377,7 +2382,7 @@ static void httpd_HostThread( httpd_host_t *host )
                     free( cl->p_buffer );
                     cl->p_buffer = malloc( cl->i_buffer_size );
                     cl->i_state = HTTPD_CLIENT_RECEIVING;
-                    cl->b_read_waiting = VLC_FALSE;
+                    cl->b_read_waiting = false;
                 }
                 else
                 {
@@ -2425,7 +2430,7 @@ static void httpd_HostThread( httpd_host_t *host )
             if (pufd->events != 0)
                 nfd++;
             else
-                b_low_delay = VLC_TRUE;
+                b_low_delay = true;
         }
         vlc_mutex_unlock( &host->lock );
 
@@ -2450,7 +2455,11 @@ static void httpd_HostThread( httpd_host_t *host )
 
         vlc_object_lock( host );
         if( ufd[nfd - 1].revents )
-            b_die = vlc_object_wait( host );
+        {
+            b_die = !vlc_object_alive( host );
+            if( !b_die )
+                b_die = vlc_object_wait( host );
+        }
         vlc_object_unlock( host );
 
         /* Handle client sockets */
@@ -2491,7 +2500,7 @@ static void httpd_HostThread( httpd_host_t *host )
                 cl->i_state == HTTPD_CLIENT_SENDING &&
                 (pufd->revents & POLLIN) )
             {
-                cl->b_read_waiting = VLC_TRUE;
+                cl->b_read_waiting = true;
             }
         }
         vlc_mutex_unlock( &host->lock );
@@ -2501,18 +2510,19 @@ static void httpd_HostThread( httpd_host_t *host )
         {
             httpd_client_t *cl;
             int i_state = -1;
+            int fd = ufd[nfd].fd;
 
-            assert (ufd[nfd].fd == host->fds[nfd]);
+            assert (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 )
+            fd = accept (fd, NULL, NULL);
+            if (fd == -1)
                 continue;
 
+            net_SetupSocket (fd);
             if( p_tls != NULL )
             {
                 switch( tls_ServerSessionHandshake( p_tls, fd ) )
@@ -2564,14 +2574,17 @@ static void httpd_HostThread( httpd_host_t *host )
 #else /* ENABLE_HTTPD */
 
 /* We just define an empty wrapper */
-httpd_host_t *httpd_TLSHostNew( vlc_object_t *a, char *b, int c,
-                                tls_server_t *d )
+httpd_host_t *httpd_TLSHostNew( vlc_object_t *a, const char *b, 
+                                int c,
+                                const char *e, const char *f,
+                                const char *g, const char* h)
 {
     msg_Err( a, "HTTP daemon support is disabled" );
     return NULL;
 }
 
-httpd_host_t *httpd_HostNew( vlc_object_t *a, char *b, int c )
+httpd_host_t *httpd_HostNew( vlc_object_t *a, const char *b,
+                             int c )
 {
     msg_Err( a, "HTTP daemon support is disabled" );
     return NULL;
@@ -2581,15 +2594,15 @@ void httpd_HostDelete( httpd_host_t *a )
 {
 }
 
-httpd_url_t *httpd_UrlNew( httpd_host_t *host, char *psz_url,
-                           char *psz_user, char *psz_password,
+httpd_url_t *httpd_UrlNew( httpd_host_t *host, const char *psz_url,
+                           const char *psz_user, const char *psz_password,
                            const vlc_acl_t *p_acl )
 {
     return NULL;
 }
 
-httpd_url_t *httpd_UrlNewUnique( httpd_host_t *host, char *psz_url,
-                                 char *psz_user, char *psz_password,
+httpd_url_t *httpd_UrlNewUnique( httpd_host_t *host, const char *psz_url,
+                                 const char *psz_user, const char *psz_password,
                                  const vlc_acl_t *p_acl )
 {
     return NULL;
@@ -2605,12 +2618,12 @@ void httpd_UrlDelete( httpd_url_t *a )
 {
 }
 
-char* httpd_ClientIP( httpd_client_t *cl, char *psz_ip )
+char* httpd_ClientIP( const httpd_client_t *cl, char *psz_ip )
 {
     return NULL;
 }
 
-char* httpd_ServerIP( httpd_client_t *cl, char *psz_ip )
+char* httpd_ServerIP( const httpd_client_t *cl, char *psz_ip )
 {
     return NULL;
 }
@@ -2623,13 +2636,16 @@ void httpd_ClientModeBidir( httpd_client_t *a )
 {
 }
 
-void httpd_FileDelete( httpd_file_t *a )
+httpd_file_sys_t *httpd_FileDelete( httpd_file_t *file )
 {
+        return NULL;
 }
 
-httpd_file_t *httpd_FileNew( httpd_host_t *a, char *b, char *c, char *d,
-                             char *e, httpd_file_callback_t f,
-                             httpd_file_sys_t *g )
+httpd_file_t *httpd_FileNew( httpd_host_t *host,
+                             const char *psz_url, const char *psz_mime,
+                             const char *psz_user, const char *psz_password,
+                             const vlc_acl_t *p_acl, httpd_file_callback_t pf_fill,
+                             httpd_file_sys_t *p_sys )
 {
     return NULL;
 }
@@ -2644,16 +2660,17 @@ httpd_handler_t *httpd_HandlerNew( httpd_host_t *host, const char *psz_url,
     return NULL;
 }
 
-void httpd_HandlerDelete( httpd_handler_t *handler )
+httpd_handler_sys_t *httpd_HandlerDelete( httpd_handler_t *handler )
 {
+        return NULL;
 }
 
 void httpd_RedirectDelete( httpd_redirect_t *a )
 {
 }
 
-httpd_redirect_t *httpd_RedirectNew( httpd_host_t *a,
-                                     char *b, char *c )
+httpd_redirect_t *httpd_RedirectNew( httpd_host_t *host, const char *psz_url_dst,
+                                     const char *psz_url_src )
 {
     return NULL;
 }
@@ -2672,8 +2689,10 @@ int httpd_StreamSend ( httpd_stream_t *a, uint8_t *b, int c )
     return 0;
 }
 
-httpd_stream_t *httpd_StreamNew( httpd_host_t *a, char *b, char *c,
-                                 char *d, char *e )
+httpd_stream_t *httpd_StreamNew( httpd_host_t *host,
+                                 const char *psz_url, const char *psz_mime,
+                                 const char *psz_user, const char *psz_password,
+                                 const vlc_acl_t *p_acl )
 {
     return NULL;
 }
@@ -2686,7 +2705,7 @@ void httpd_MsgAdd  ( httpd_message_t *a, const char *b, const char *c, ... )
 {
 }
 
-const char *httpd_MsgGet ( httpd_message_t *a, const char *b )
+const char *httpd_MsgGet( const httpd_message_t *msg, const char *name )
 {
     return "";
 }