http.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:11k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * http.c: HTTP interface
  3.  *****************************************************************************
  4.  * Copyright (C) 2005 the VideoLAN team
  5.  *
  6.  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  21.  *****************************************************************************/
  22. /*****************************************************************************
  23.  * Preamble
  24.  *****************************************************************************/
  25. #ifdef HAVE_CONFIG_H
  26. # include "config.h"
  27. #endif
  28. #include <vlc_common.h>
  29. #include <vlc_access.h>
  30. #ifdef HAVE_UNISTD_H
  31. #   include <unistd.h>
  32. #endif
  33. #include <fcntl.h>
  34. #include <sys/types.h>
  35. #include <errno.h>
  36. /* Include dvbpsi headers */
  37. #ifdef HAVE_DVBPSI_DR_H
  38. #   include <dvbpsi/dvbpsi.h>
  39. #   include <dvbpsi/descriptor.h>
  40. #   include <dvbpsi/pat.h>
  41. #   include <dvbpsi/pmt.h>
  42. #   include <dvbpsi/dr.h>
  43. #   include <dvbpsi/psi.h>
  44. #   include <dvbpsi/demux.h>
  45. #   include <dvbpsi/sdt.h>
  46. #else
  47. #   include "dvbpsi.h"
  48. #   include "descriptor.h"
  49. #   include "tables/pat.h"
  50. #   include "tables/pmt.h"
  51. #   include "descriptors/dr.h"
  52. #   include "psi.h"
  53. #   include "demux.h"
  54. #   include "tables/sdt.h"
  55. #endif
  56. #ifdef ENABLE_HTTPD
  57. #   include "vlc_httpd.h"
  58. #   include "vlc_acl.h"
  59. #endif
  60. #include "dvb.h"
  61. #ifdef ENABLE_HTTPD
  62. struct httpd_file_sys_t
  63. {
  64.     access_t         *p_access;
  65.     httpd_file_t     *p_file;
  66. };
  67. static int HttpCallback( httpd_file_sys_t *p_args,
  68.                          httpd_file_t *p_file,
  69.                          uint8_t *_p_request,
  70.                          uint8_t **_pp_data, int *pi_data );
  71. /*****************************************************************************
  72.  * HTTPOpen: Start the internal HTTP server
  73.  *****************************************************************************/
  74. int HTTPOpen( access_t *p_access )
  75. {
  76.     access_sys_t *p_sys = p_access->p_sys;
  77.     char          *psz_address, *psz_cert = NULL, *psz_key = NULL,
  78.                   *psz_ca = NULL, *psz_crl = NULL, *psz_user = NULL,
  79.                   *psz_password = NULL, *psz_acl = NULL;
  80.     int           i_port       = 0;
  81.     char          psz_tmp[10];
  82.     vlc_acl_t     *p_acl = NULL;
  83.     httpd_file_sys_t *f;
  84.     vlc_mutex_init( &p_sys->httpd_mutex );
  85.     vlc_cond_init( &p_sys->httpd_cond );
  86.     p_sys->b_request_frontend_info = p_sys->b_request_mmi_info = false;
  87.     p_sys->i_httpd_timeout = 0;
  88.     psz_address = var_GetNonEmptyString( p_access, "dvb-http-host" );
  89.     if( psz_address != NULL )
  90.     {
  91.         char *psz_parser = strchr( psz_address, ':' );
  92.         if( psz_parser )
  93.         {
  94.             *psz_parser++ = '';
  95.             i_port = atoi( psz_parser );
  96.         }
  97.     }
  98.     else
  99.         return VLC_SUCCESS;
  100.     /* determine SSL configuration */
  101.     psz_cert = var_GetNonEmptyString( p_access, "dvb-http-intf-cert" );
  102.     if ( psz_cert != NULL )
  103.     {
  104.         msg_Dbg( p_access, "enabling TLS for HTTP interface (cert file: %s)",
  105.                  psz_cert );
  106.         psz_key = config_GetPsz( p_access, "dvb-http-intf-key" );
  107.         psz_ca = config_GetPsz( p_access, "dvb-http-intf-ca" );
  108.         psz_crl = config_GetPsz( p_access, "dvb-http-intf-crl" );
  109.         if ( i_port <= 0 )
  110.             i_port = 8443;
  111.     }
  112.     else
  113.     {
  114.         if ( i_port <= 0 )
  115.             i_port= 8082;
  116.     }
  117.     /* Ugly hack to allow to run several HTTP servers on different ports. */
  118.     sprintf( psz_tmp, ":%d", i_port + 1 );
  119.     config_PutPsz( p_access, "dvb-http-host", psz_tmp );
  120.     msg_Dbg( p_access, "base %s:%d", psz_address, i_port );
  121.     p_sys->p_httpd_host = httpd_TLSHostNew( VLC_OBJECT(p_access), psz_address,
  122.                                             i_port, psz_cert, psz_key, psz_ca,
  123.                                             psz_crl );
  124.     free( psz_cert );
  125.     free( psz_key );
  126.     free( psz_ca );
  127.     free( psz_crl );
  128.     if ( p_sys->p_httpd_host == NULL )
  129.     {
  130.         msg_Err( p_access, "cannot listen on %s:%d", psz_address, i_port );
  131.         free( psz_address );
  132.         return VLC_EGENERIC;
  133.     }
  134.     free( psz_address );
  135.     psz_user = var_GetNonEmptyString( p_access, "dvb-http-user" );
  136.     psz_password = var_GetNonEmptyString( p_access, "dvb-http-password" );
  137.     psz_acl = var_GetNonEmptyString( p_access, "dvb-http-acl" );
  138.     if ( psz_acl != NULL )
  139.     {
  140.         p_acl = ACL_Create( p_access, false );
  141.         if( ACL_LoadFile( p_acl, psz_acl ) )
  142.         {
  143.             ACL_Destroy( p_acl );
  144.             p_acl = NULL;
  145.         }
  146.     }
  147.     /* Declare an index.html file. */
  148.     f = malloc( sizeof(httpd_file_sys_t) );
  149.     f->p_access = p_access;
  150.     f->p_file = httpd_FileNew( p_sys->p_httpd_host, "/index.html",
  151.                                "text/html; charset=UTF-8",
  152.                                psz_user, psz_password, p_acl,
  153.                                HttpCallback, f );
  154.     free( psz_user );
  155.     free( psz_password );
  156.     free( psz_acl );
  157.     if ( p_acl != NULL )
  158.         ACL_Destroy( p_acl );
  159.     if ( f->p_file == NULL )
  160.     {
  161.         free( f );
  162.         p_sys->p_httpd_file = NULL;
  163.         return VLC_EGENERIC;
  164.     }
  165.     p_sys->p_httpd_file = f;
  166.     p_sys->p_httpd_redir = httpd_RedirectNew( p_sys->p_httpd_host,
  167.                                               "/index.html", "/" );
  168.     return VLC_SUCCESS;
  169. }
  170. /*****************************************************************************
  171.  * HTTPClose: Stop the internal HTTP server
  172.  *****************************************************************************/
  173. void HTTPClose( access_t *p_access )
  174. {
  175.     access_sys_t *p_sys = p_access->p_sys;
  176.     if ( p_sys->p_httpd_host != NULL )
  177.     {
  178.         if ( p_sys->p_httpd_file != NULL )
  179.         {
  180.             /* Unlock the thread if it is stuck in HttpCallback */
  181.             vlc_mutex_lock( &p_sys->httpd_mutex );
  182.             if ( p_sys->b_request_frontend_info == true )
  183.             {
  184.                 p_sys->b_request_frontend_info = false;
  185.                 p_sys->psz_frontend_info = strdup("");
  186.             }
  187.             if ( p_sys->b_request_mmi_info == true )
  188.             {
  189.                 p_sys->b_request_mmi_info = false;
  190.                 p_sys->psz_mmi_info = strdup("");
  191.             }
  192.             vlc_cond_signal( &p_sys->httpd_cond );
  193.             vlc_mutex_unlock( &p_sys->httpd_mutex );
  194.             httpd_FileDelete( p_sys->p_httpd_file->p_file );
  195.             httpd_RedirectDelete( p_sys->p_httpd_redir );
  196.         }
  197.         httpd_HostDelete( p_sys->p_httpd_host );
  198.     }
  199.     vlc_mutex_destroy( &p_sys->httpd_mutex );
  200.     vlc_cond_destroy( &p_sys->httpd_cond );
  201. }
  202. static const char *psz_constant_header =
  203.     "<html>n"
  204.     "<head><title>VLC DVB monitoring interface</title></head>n"
  205.     "<body><a href="index.html">Reload this page</a>n"
  206.     "<h1>CAM info</h1>n";
  207. static const char *psz_constant_middle =
  208.     "<hr><h1>Frontend Info</h1>n";
  209. static const char *psz_constant_footer =
  210.     "</body></html>n";
  211. /****************************************************************************
  212.  * HttpCallback: Return the index.html file
  213.  ****************************************************************************/
  214. static int HttpCallback( httpd_file_sys_t *p_args,
  215.                          httpd_file_t *p_file,
  216.                          uint8_t *_psz_request,
  217.                          uint8_t **_pp_data, int *pi_data )
  218. {
  219.     access_sys_t *p_sys = p_args->p_access->p_sys;
  220.     char *psz_request = (char *)_psz_request;
  221.     char **pp_data = (char **)_pp_data;
  222.     vlc_mutex_lock( &p_sys->httpd_mutex );
  223.     p_sys->i_httpd_timeout = mdate() + INT64_C(3000000); /* 3 s */
  224.     p_sys->psz_request = psz_request;
  225.     p_sys->b_request_frontend_info = true;
  226.     if ( p_sys->i_ca_handle )
  227.     {
  228.         p_sys->b_request_mmi_info = true;
  229.     }
  230.     else
  231.     {
  232.         p_sys->psz_mmi_info = strdup( "No available CAM interfacen" );
  233.     }
  234.     do
  235.     {
  236.         vlc_cond_wait( &p_sys->httpd_cond, &p_sys->httpd_mutex );
  237.     }
  238.     while ( p_sys->b_request_frontend_info || p_sys->b_request_mmi_info );
  239.     p_sys->i_httpd_timeout = 0;
  240.     vlc_mutex_unlock( &p_sys->httpd_mutex );
  241.     *pi_data = strlen( psz_constant_header )
  242.                 + strlen( p_sys->psz_mmi_info )
  243.                 + strlen( psz_constant_middle )
  244.                 + strlen( p_sys->psz_frontend_info )
  245.                 + strlen( psz_constant_footer ) + 1;
  246.     *pp_data = malloc( *pi_data );
  247.     sprintf( *pp_data, "%s%s%s%s%s", psz_constant_header,
  248.              p_sys->psz_mmi_info, psz_constant_middle,
  249.              p_sys->psz_frontend_info, psz_constant_footer );
  250.     free( p_sys->psz_frontend_info );
  251.     free( p_sys->psz_mmi_info );
  252.     return VLC_SUCCESS;
  253. }
  254. /****************************************************************************
  255.  * HTTPExtractValue: Extract a GET variable from psz_request
  256.  ****************************************************************************/
  257. char *HTTPExtractValue( char *psz_uri, const char *psz_name,
  258.                             char *psz_value, int i_value_max )
  259. {
  260.     char *p = psz_uri;
  261.     while( (p = strstr( p, psz_name )) )
  262.     {
  263.         /* Verify that we are dealing with a post/get argument */
  264.         if( (p == psz_uri || *(p - 1) == '&' || *(p - 1) == 'n')
  265.               && p[strlen(psz_name)] == '=' )
  266.             break;
  267.         p++;
  268.     }
  269.     if( p )
  270.     {
  271.         int i_len;
  272.         p += strlen( psz_name );
  273.         if( *p == '=' ) p++;
  274.         if( strchr( p, '&' ) )
  275.         {
  276.             i_len = strchr( p, '&' ) - p;
  277.         }
  278.         else
  279.         {
  280.             /* for POST method */
  281.             if( strchr( p, 'n' ) )
  282.             {
  283.                 i_len = strchr( p, 'n' ) - p;
  284.                 if( i_len && *(p+i_len-1) == 'r' ) i_len--;
  285.             }
  286.             else
  287.             {
  288.                 i_len = strlen( p );
  289.             }
  290.         }
  291.         i_len = __MIN( i_value_max - 1, i_len );
  292.         if( i_len > 0 )
  293.         {
  294.             strncpy( psz_value, p, i_len );
  295.             psz_value[i_len] = '';
  296.         }
  297.         else
  298.         {
  299.             strncpy( psz_value, "", i_value_max );
  300.         }
  301.         p += i_len;
  302.     }
  303.     else
  304.     {
  305.         strncpy( psz_value, "", i_value_max );
  306.     }
  307.     return p;
  308. }
  309. #endif /* ENABLE_HTTPD */