1 /*****************************************************************************
2 * http.c: HTTP interface
3 *****************************************************************************
4 * Copyright (C) 2005 the VideoLAN team
6 * Authors: Christophe Massiot <massiot@via.ecp.fr>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_access.h>
34 #include <vlc_httpd.h>
36 #include <sys/types.h>
38 /* Include dvbpsi headers */
39 # include <dvbpsi/dvbpsi.h>
40 # include <dvbpsi/descriptor.h>
41 # include <dvbpsi/pat.h>
42 # include <dvbpsi/pmt.h>
43 # include <dvbpsi/dr.h>
44 # include <dvbpsi/psi.h>
45 # include <dvbpsi/demux.h>
46 # include <dvbpsi/sdt.h>
50 struct httpd_file_sys_t
56 static int HttpCallback( httpd_file_sys_t *p_args,
59 uint8_t **_pp_data, int *pi_data );
61 /*****************************************************************************
62 * HTTPOpen: Start the internal HTTP server
63 *****************************************************************************/
64 int HTTPOpen( access_t *p_access )
66 access_sys_t *p_sys = p_access->p_sys;
67 char *psz_user = NULL, *psz_password = NULL;
71 vlc_mutex_init( &p_sys->httpd_mutex );
72 vlc_cond_init( &p_sys->httpd_cond );
73 p_sys->b_request_frontend_info = p_sys->b_request_mmi_info = false;
74 p_sys->i_httpd_timeout = 0;
76 p_sys->p_httpd_host = vlc_http_HostNew( VLC_OBJECT(p_access) );
77 if ( p_sys->p_httpd_host == NULL )
83 psz_user = var_GetNonEmptyString( p_access, "dvb-http-user" );
84 psz_password = var_GetNonEmptyString( p_access, "dvb-http-password" );
86 /* Declare an index.html file. */
87 f = malloc( sizeof(httpd_file_sys_t) );
88 f->p_access = p_access;
89 f->p_file = httpd_FileNew( p_sys->p_httpd_host, "/index.html",
90 "text/html; charset=UTF-8",
91 psz_user, psz_password, NULL,
97 if ( f->p_file == NULL )
100 p_sys->p_httpd_file = NULL;
104 p_sys->p_httpd_file = f;
105 p_sys->p_httpd_redir = httpd_RedirectNew( p_sys->p_httpd_host,
106 "/index.html", "/" );
111 /*****************************************************************************
112 * HTTPClose: Stop the internal HTTP server
113 *****************************************************************************/
114 void HTTPClose( access_t *p_access )
116 access_sys_t *p_sys = p_access->p_sys;
118 if ( p_sys->p_httpd_host != NULL )
120 if ( p_sys->p_httpd_file != NULL )
122 /* Unlock the thread if it is stuck in HttpCallback */
123 vlc_mutex_lock( &p_sys->httpd_mutex );
124 if ( p_sys->b_request_frontend_info )
126 p_sys->b_request_frontend_info = false;
127 p_sys->psz_frontend_info = strdup("");
129 if ( p_sys->b_request_mmi_info )
131 p_sys->b_request_mmi_info = false;
132 p_sys->psz_mmi_info = strdup("");
134 vlc_cond_signal( &p_sys->httpd_cond );
135 vlc_mutex_unlock( &p_sys->httpd_mutex );
137 httpd_FileDelete( p_sys->p_httpd_file->p_file );
138 httpd_RedirectDelete( p_sys->p_httpd_redir );
141 httpd_HostDelete( p_sys->p_httpd_host );
144 vlc_mutex_destroy( &p_sys->httpd_mutex );
145 vlc_cond_destroy( &p_sys->httpd_cond );
149 static const char *psz_constant_header =
151 "<head><title>VLC DVB monitoring interface</title></head>\n"
152 "<body><a href=\"index.html\">Reload this page</a>\n"
153 "<h1>CAM info</h1>\n";
155 static const char *psz_constant_middle =
156 "<hr><h1>Frontend Info</h1>\n";
158 static const char *psz_constant_footer =
161 /****************************************************************************
162 * HttpCallback: Return the index.html file
163 ****************************************************************************/
164 static int HttpCallback( httpd_file_sys_t *p_args,
165 httpd_file_t *p_file,
166 uint8_t *_psz_request,
167 uint8_t **_pp_data, int *pi_data )
170 access_sys_t *p_sys = p_args->p_access->p_sys;
171 char *psz_request = (char *)_psz_request;
172 char **pp_data = (char **)_pp_data;
174 vlc_mutex_lock( &p_sys->httpd_mutex );
176 p_sys->i_httpd_timeout = mdate() + INT64_C(3000000); /* 3 s */
177 p_sys->psz_request = psz_request;
178 p_sys->b_request_frontend_info = true;
179 if ( p_sys->p_cam != NULL )
181 p_sys->b_request_mmi_info = true;
185 p_sys->psz_mmi_info = strdup( "No available CAM interface\n" );
190 vlc_cond_wait( &p_sys->httpd_cond, &p_sys->httpd_mutex );
192 while ( p_sys->b_request_frontend_info || p_sys->b_request_mmi_info );
194 p_sys->i_httpd_timeout = 0;
195 vlc_mutex_unlock( &p_sys->httpd_mutex );
197 *pi_data = strlen( psz_constant_header )
198 + strlen( p_sys->psz_mmi_info )
199 + strlen( psz_constant_middle )
200 + strlen( p_sys->psz_frontend_info )
201 + strlen( psz_constant_footer ) + 1;
202 *pp_data = malloc( *pi_data );
204 sprintf( *pp_data, "%s%s%s%s%s", psz_constant_header,
205 p_sys->psz_mmi_info, psz_constant_middle,
206 p_sys->psz_frontend_info, psz_constant_footer );
207 free( p_sys->psz_frontend_info );
208 free( p_sys->psz_mmi_info );
213 /****************************************************************************
214 * HTTPExtractValue: Extract a GET variable from psz_request
215 ****************************************************************************/
216 const char *HTTPExtractValue( const char *psz_uri, const char *psz_name,
217 char *psz_value, int i_value_max )
219 const char *p = psz_uri;
221 while( (p = strstr( p, psz_name )) )
223 /* Verify that we are dealing with a post/get argument */
224 if( (p == psz_uri || *(p - 1) == '&' || *(p - 1) == '\n')
225 && p[strlen(psz_name)] == '=' )
234 p += strlen( psz_name );
237 if( strchr( p, '&' ) )
239 i_len = strchr( p, '&' ) - p;
243 /* for POST method */
244 if( strchr( p, '\n' ) )
246 i_len = strchr( p, '\n' ) - p;
247 if( i_len && *(p+i_len-1) == '\r' ) i_len--;
254 i_len = __MIN( i_value_max - 1, i_len );
257 strncpy( psz_value, p, i_len );
258 psz_value[i_len] = '\0';
262 strncpy( psz_value, "", i_value_max );
268 strncpy( psz_value, "", i_value_max );
274 #endif /* ENABLE_HTTPD */