http.h 12.6 KB
Newer Older
1 2 3
/*****************************************************************************
 * http.h: Headers for the HTTP interface
 *****************************************************************************
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
4
 * Copyright (C) 2001-2007 the VideoLAN team
Antoine Cellerier's avatar
Antoine Cellerier committed
5
 * $Id$
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * Authors: Gildas Bazin <gbazin@netcourrier.com>
 *          Laurent Aimar <fenrir@via.ecp.fr>
 *          Christophe Massiot <massiot@via.ecp.fr>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
Antoine Cellerier's avatar
Antoine Cellerier committed
23
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 25 26 27 28 29 30 31
 *****************************************************************************/

#ifndef _HTTP_H_
#define _HTTP_H_

/*****************************************************************************
 * Preamble
 *****************************************************************************/
32
#include <vlc_common.h>
33
#include <stdlib.h>
34
#include <strings.h>
35
#include <ctype.h>
Clément Stenac's avatar
Clément Stenac committed
36 37
#include <vlc_interface.h>
#include <vlc_playlist.h>
38

Clément Stenac's avatar
Clément Stenac committed
39 40
#include <vlc_aout.h>
#include <vlc_vout.h> /* for fullscreen */
41

42 43 44 45 46
#include <vlc_httpd.h>
#include <vlc_vlm.h>
#include <vlc_network.h>
#include <vlc_acl.h>
#include <vlc_charset.h>
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

#ifdef HAVE_SYS_STAT_H
#   include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
#   include <fcntl.h>
#endif

#ifdef HAVE_UNISTD_H
#   include <unistd.h>
#elif defined( WIN32 ) && !defined( UNDER_CE )
#   include <io.h>
#endif

#ifdef HAVE_DIRENT_H
#   include <dirent.h>
#endif

/* stat() support for large files on win32 */
#if defined( WIN32 ) && !defined( UNDER_CE )
#   define stat _stati64
#endif

/** \defgroup http_intf HTTP Interface
 * This is the HTTP remote control interface. It is fully customizable
 * by writing HTML pages using custom <vlc> tags.
 *
 * These tags use so-called macros.
 *
 * These macros can manipulate variables. For more complex operations,
 * a custom RPN evaluator with many built-in functions is provided.
 * @{
 */

/*****************************************************************************
 * Local defines
 *****************************************************************************/
#define MAX_DIR_SIZE 2560
#define STACK_MAX 100        //< Maximum RPN stack size


/*****************************************************************************
 * Utility functions
 *****************************************************************************/

/** \defgroup http_utils Utilities
 * \ingroup http_intf
 * Utilities
 * @{
 */

/* File and directory functions */

/** This function recursively parses a directory and adds all files */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
101
int ParseDirectory( intf_thread_t *p_intf, char *psz_root,
102
                        char *psz_dir );
103
/** This function loads a file into a buffer */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
104
int FileLoad( FILE *f, char **pp_data, int *pi_data );
105
/** This function creates a suitable URL for a filename */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
106
char *FileToUrl( char *name, bool *pb_index );
107
/** This function returns the real path of a file or directory */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
108
char *RealPath( const char *psz_src );
109 110 111

/** This command parses the "seek" command for the HTTP interface
 * and performs the requested action */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
112
void HandleSeek( intf_thread_t *p_intf, char *p_value );
113 114 115 116 117

/* URI Handling functions */

/** This function extracts the value for a given argument name
 * from an HTTP request */
118
const char *ExtractURIValue( const char *restrict psz_uri,
119 120
                           const char *restrict psz_name,
                           char *restrict psz_value, size_t i_value_max );
121
char *ExtractURIString( const char *restrict psz_uri,
122
                            const char *restrict psz_name );
123
/** \todo Describe this function */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
124
int TestURIParam( char *psz_uri, const char *psz_name );
125 126

/** This function parses a MRL */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
127
input_item_t *MRLParse( intf_thread_t *, const char *psz, char *psz_name );
128 129

/** Return the first word from a string (works in-place) */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
130
char *FirstWord( char *psz, char *new );
131 132 133 134 135 136 137 138 139

/**@}*/

/****************************************************************************
 * Variable handling functions
 ****************************************************************************/

/** \defgroup http_vars Macro variables
 * \ingroup http_intf
140 141 142 143 144
 * These variables can be used in the <vlc> macros and in the RPN evaluator.
 * The variables make a tree: each variable can have an arbitrary
 * number of "children" variables.
 * A number of helper functions are provided to manipulate the main variable
 * structure
145 146 147 148 149
 * @{
 */

/**
 * \struct mvar_t
150
 * This structure defines a macro variable
151 152 153
 */
typedef struct mvar_s
{
154 155
    char *name;                 ///< Variable name
    char *value;                ///< Variable value
156

157 158
    int           i_field;      ///< Number of children variables
    struct mvar_s **field;      ///< Children variables array
159 160 161 162
} mvar_t;


/** This function creates a new variable */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
163
mvar_t  *mvar_New( const char *name, const char *value );
164
/** This function deletes a variable */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
165
void     mvar_Delete( mvar_t *v );
166
/** This function adds f to the children variables of v, at last position */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
167
void     mvar_AppendVar( mvar_t *v, mvar_t *f );
168
/** This function duplicates a variable */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
169
mvar_t  *mvar_Duplicate( const mvar_t *v );
170
/** This function adds f to the children variables of v, at fist position */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
171
void     mvar_PushVar( mvar_t *v, mvar_t *f );
172
/** This function removes f from the children variables of v */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
173
void     mvar_RemoveVar( mvar_t *v, mvar_t *f );
174
/** This function retrieves the child variable named "name" */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
175
mvar_t  *mvar_GetVar( mvar_t *s, const char *name );
176
/** This function retrieves the value of the child variable named "field" */
177
const char *mvar_GetValue( mvar_t *v, const char *field );
178 179
/** This function creates a variable with the given name and value and
 * adds it as first child of vars */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
180
void     mvar_PushNewVar( mvar_t *vars, const char *name,
181
                              const char *value );
182 183
/** This function creates a variable with the given name and value and
 * adds it as last child of vars */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
184
void     mvar_AppendNewVar( mvar_t *vars, const char *name,
185
                                const char *value );
186 187
/** @} */

188
/** \defgroup http_sets Sets *
189
 * \ingroup http_intf
190 191 192
 * Sets are an application of the macro variables. There are a number of
 * predefined functions that will give you variables whose children represent
 * VLC internal data (playlist, stream info, ...)
193 194 195 196 197
 * @{
 */

/** This function creates a set variable which represents a series of integer
 * The arg parameter must be of the form "start[:stop[:step]]"  */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
198
mvar_t *mvar_IntegerSetNew( const char *name, const char *arg );
199

200
/** This function creates a set variable with a list of VLC objects */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
201
mvar_t *mvar_ObjectSetNew( intf_thread_t *p_intf, char *name, const char *arg );
202

203
/** This function creates a set variable with the contents of the playlist */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
204
mvar_t *mvar_PlaylistSetNew( intf_thread_t *p_intf, char *name,
205
                                 playlist_t *p_pl );
206 207
/** This function creates a set variable with the contents of the Stream
 * and media info box */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
208
mvar_t *mvar_InfoSetNew( char *name, input_thread_t *p_input );
209
/** This function creates a set variable with the input parameters */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
210
mvar_t *mvar_InputVarSetNew( intf_thread_t *p_intf, char *name,
211 212
                                 input_thread_t *p_input,
                                 const char *psz_variable );
213 214
/** This function creates a set variable representing the files of the psz_dir
 * directory */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
215
mvar_t *mvar_FileSetNew( intf_thread_t *p_intf, char *name,
216
                             char *psz_dir );
217
/** This function creates a set variable representing the VLM streams */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
218
mvar_t *mvar_VlmSetNew( char *name, vlm_t *vlm );
219 220

/** This function converts the listing of a playlist node into a mvar set */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
221
void PlaylistListNode( intf_thread_t *p_intf, playlist_t *p_pl,
222 223
                           playlist_item_t *p_node, char *name, mvar_t *s,
                           int i_depth );
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247

/**@}*/

/*****************************************************************************
 * RPN Evaluator
 *****************************************************************************/

/** \defgroup http_rpn RPN Evaluator
 * \ingroup http_intf
 * @{
 */

/**
 * \struct rpn_stack_t
 * This structure represents a stack of RPN commands for the HTTP interface
 * It is attached to a request
 */
typedef struct
{
    char *stack[STACK_MAX];
    int  i_stack;
} rpn_stack_t;

/** This function creates the RPN evaluator stack */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
248
void SSInit( rpn_stack_t * );
249
/** This function cleans the evaluator stack */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
250
void SSClean( rpn_stack_t * );
251
/* Evaluate and execute the RPN Stack */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
252
void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
253
                       rpn_stack_t *st, char *exp );
254 255

/* Push an operand on top of the RPN stack */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
256
void SSPush  ( rpn_stack_t *, const char * );
257
/* Remove the first operand from the RPN Stack */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
258
char *SSPop  ( rpn_stack_t * );
259
/* Pushes an operand at a given position in the stack */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
260
void SSPushN ( rpn_stack_t *, int );
261
/* Removes an operand at the given position in the stack */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
262
int  SSPopN  ( rpn_stack_t *, mvar_t  * );
263 264 265 266 267 268 269 270 271 272

/**@}*/


/****************************************************************************
 * Macro handling (<vlc ... stuff)
 ****************************************************************************/

/** \defgroup http_macros <vlc> Macros Handling
 * \ingroup http_intf
273 274 275 276
 * A macro is a code snippet in the HTML page looking like
 * <vlc id="macro_id" param1="value1" param2="value2">
 * Macros string ids are mapped to macro types, and specific handling code
 * must be written for each macro type
277 278 279 280 281 282 283 284 285
 * @{
 */


/** \struct macro_t
 * This structure represents a HTTP Interface macro.
 */
typedef struct
{
286 287 288
    char *id;           ///< Macro ID string
    char *param1;       ///< First parameter
    char *param2;       ///< Second parameter
289 290 291
} macro_t;

/** This function parses a file for macros */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
292
void Execute( httpd_file_sys_t *p_args,
293 294 295 296 297 298 299 300 301 302
                  char *p_request, int i_request,
                  char **pp_data, int *pi_data,
                  char **pp_dst,
                  char *_src, char *_end );

/**@}*/

/**
 * Core stuff
 */
Rémi Duraffort's avatar
Rémi Duraffort committed
303
/** \struct httpd_file_sys_t
304 305 306 307 308 309 310 311 312 313 314 315
 * This structure represent a single HTML file to be parsed by the macros
 * handling engine */
struct httpd_file_sys_t
{
    intf_thread_t    *p_intf;
    httpd_file_t     *p_file;
    httpd_redirect_t *p_redir;
    httpd_redirect_t *p_redir2;

    char          *file;
    char          *name;

316
    bool    b_html, b_handler;
317 318 319 320 321 322

    /* inited for each access */
    rpn_stack_t   stack;
    mvar_t        *vars;
};

Rémi Duraffort's avatar
Rémi Duraffort committed
323
/** \struct http_association_t
324 325 326 327 328 329 330 331 332
 * Structure associating an extension to an external program
 */
typedef struct http_association_t
{
    char                *psz_ext;
    int                 i_argc;
    char                **ppsz_argv;
} http_association_t;

Rémi Duraffort's avatar
Rémi Duraffort committed
333
/** \struct httpd_handler_sys_t
334 335 336 337 338 339 340 341 342 343 344 345
 * This structure represent a single CGI file to be parsed by the macros
 * handling engine */
struct httpd_handler_sys_t
{
    httpd_file_sys_t file;

    /* HACK ALERT: this is added below so that casting httpd_handler_sys_t
     * to httpd_file_sys_t works */
    httpd_handler_t  *p_handler;
    http_association_t *p_association;
};

Rémi Duraffort's avatar
Rémi Duraffort committed
346
/** \struct intf_sys_t
347 348 349 350 351 352 353 354 355
 * Internal service structure for the HTTP interface
 */
struct intf_sys_t
{
    httpd_host_t        *p_httpd_host;

    int                 i_files;
    httpd_file_sys_t    **pp_files;

356 357
    int                 i_handlers;
    http_association_t  **pp_handlers;
358
    httpd_handler_t     *p_art_handler;
359

360 361 362
    playlist_t          *p_playlist;
    input_thread_t      *p_input;
    vlm_t               *p_vlm;
363 364 365

    char                *psz_address;
    unsigned short      i_port;
366 367 368
};

/** This function is the main HTTPD Callback used by the HTTP Interface */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
369
int HttpCallback( httpd_file_sys_t *p_args,
370 371 372
                      httpd_file_t *,
                      uint8_t *p_request,
                      uint8_t **pp_data, int *pi_data );
373
/** This function is the HTTPD Callback used for CGIs */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
374
int  HandlerCallback( httpd_handler_sys_t *p_args,
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
375
                          httpd_handler_t *p_handler, char *_p_url,
376 377 378 379
                          uint8_t *_p_request, int i_type,
                          uint8_t *_p_in, int i_in,
                          char *psz_remote_addr, char *psz_remote_host,
                          uint8_t **_pp_data, int *pi_data );
380 381 382 383
/**@}*/

#endif