⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpd.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** * httpd.c ***************************************************************************** * Copyright (C) 2004-2005 VideoLAN * $Id: httpd.c 11100 2005-05-22 07:46:02Z courmisch $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> *          Remi Denis-Courmont <rem # videolan.org> * * 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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************/#include <stdlib.h>#include <vlc/vlc.h>#ifdef ENABLE_HTTPD#include "vlc_httpd.h"#include "network.h"#include "vlc_tls.h"#include <string.h>#include <errno.h>#ifdef HAVE_UNISTD_H#   include <unistd.h>#endif#ifdef HAVE_FCNTL_H#   include <fcntl.h>#endif#if defined( UNDER_CE )#   include <winsock.h>#elif defined( WIN32 )#   include <winsock2.h>#   include <ws2tcpip.h>#else#   include <netdb.h>                                         /* hostent ... */#   include <sys/socket.h>#   include <netinet/in.h>#   ifdef HAVE_ARPA_INET_H#       include <arpa/inet.h>                    /* inet_ntoa(), inet_aton() */#   endif#endif#if defined(WIN32) && !defined(UNDER_CE)static const struct in6_addr in6addr_any = {{IN6ADDR_ANY_INIT}};#elif defined(UNDER_CE) && defined(AF_INET6)#   undef AF_INET6#endif#ifndef PF_INET#    define PF_INET AF_INET                                          /* BeOS */#endif#if 0typedef struct httpd_t          httpd_t;typedef struct httpd_host_t     httpd_host_t;typedef struct httpd_url_t      httpd_url_t;typedef struct httpd_client_t   httpd_client_t;enum{    HTTPD_MSG_NONE,    /* answer */    HTTPD_MSG_ANSWER,    /* channel communication */    HTTPD_MSG_CHANNEL,    /* http request */    HTTPD_MSG_GET,    HTTPD_MSG_HEAD,    HTTPD_MSG_POST,    /* rtsp request */    HTTPD_MSG_OPTIONS,    HTTPD_MSG_DESCRIBE,    HTTPD_MSG_SETUP,    HTTPD_MSG_PLAY,    HTTPD_MSG_PAUSE,    HTTPD_MSG_TEARDOWN,    /* just to track the count of MSG */    HTTPD_MSG_MAX};enum{    HTTPD_PROTO_NONE,    HTTPD_PROTO_HTTP,    HTTPD_PROTO_RTSP,};typedef struct{    httpd_client_t *cl; /* NULL if not throught a connection e vlc internal */    int     i_type;    int     i_proto;    int     i_version;    /* for an answer */    int     i_status;    char    *psz_status;    /* for a query */    char    *psz_url;    char    *psz_args;  /* FIXME find a clean way to handle GET(psz_args) and POST(body) through the same code */    /* for rtp over rtsp */    int     i_channel;    /* options */    int     i_name;    char    **name;    int     i_value;    char    **value;    /* body */    int64_t i_body_offset;    int     i_body;    uint8_t *p_body;} httpd_message_t;typedef struct httpd_callback_sys_t httpd_callback_sys_t;/* answer could be null, int this case no answer is requested */typedef int (*httpd_callback_t)( httpd_callback_sys_t *, httpd_client_t *, httpd_message_t *answer, httpd_message_t *query );/* create a new host */httpd_host_t *httpd_HostNew( vlc_object_t *, char *psz_host, int i_port );/* delete a host */void          httpd_HostDelete( httpd_host_t * );/* register a new url */httpd_url_t *httpd_UrlNew( httpd_host_t *, char *psz_url );/* register callback on a url */int          httpd_UrlCatch( httpd_url_t *, int i_msg,                             httpd_callback_t, httpd_callback_sys_t * );/* delete an url */void         httpd_UrlDelete( httpd_url_t * );void httpd_ClientModeStream( httpd_client_t *cl );void httpd_ClientModeBidir( httpd_client_t *cl );static void httpd_ClientClean( httpd_client_t *cl );/* High level */typedef struct httpd_file_t     httpd_file_t;typedef struct httpd_file_sys_t httpd_file_sys_t;typedef int (*httpd_file_callback_t)( httpd_file_sys_t*, httpd_file_t *, uint8_t *psz_request, uint8_t **pp_data, int *pi_data );httpd_file_t *httpd_FileNew( httpd_host_t *,                             char *psz_url, char *psz_mime,                             char *psz_user, char *psz_password,                             httpd_file_callback_t pf_fill,                             httpd_file_sys_t *p_sys );void         httpd_FileDelete( httpd_file_t * );typedef struct httpd_redirect_t httpd_redirect_t;httpd_redirect_t *httpd_RedirectNew( httpd_host_t *, char *psz_url_dst, char *psz_url_src );void              httpd_RedirectDelete( httpd_redirect_t * );#if 0typedef struct httpd_stream_t httpd_stream_t;httpd_stream_t *httpd_StreamNew( httpd_host_t * );int             httpd_StreamHeader( httpd_stream_t *, uint8_t *p_data, int i_data );int             httpd_StreamSend( httpd_stream_t *, uint8_t *p_data, int i_data );void            httpd_StreamDelete( httpd_stream_t * );#endif/* Msg functions facilities */void         httpd_MsgInit( httpd_message_t * );void         httpd_MsgAdd( httpd_message_t *, char *psz_name, char *psz_value, ... );/* return "" if not found. The string is not allocated */char        *httpd_MsgGet( httpd_message_t *, char *psz_name );void         httpd_MsgClean( httpd_message_t * );#endif#if 0struct httpd_t{    VLC_COMMON_MEMBERS    /* vlc_mutex_t  lock; */    int          i_host;    httpd_host_t **host;};#endifstatic void httpd_ClientClean( httpd_client_t *cl );/* each host run in his own thread */struct httpd_host_t{    VLC_COMMON_MEMBERS    httpd_t     *httpd;    /* ref count */    int         i_ref;    /* address/port and socket for listening at connections */    struct sockaddr_storage sock;    int                     i_sock_size;    int                     fd;    vlc_mutex_t lock;    /* all registered url (becarefull that 2 httpd_url_t could point at the same url)     * This will slow down the url research but make my live easier     * All url will have their cb trigger, but only the first one can answer     * */    int         i_url;    httpd_url_t **url;    int            i_client;    httpd_client_t **client;        /* TLS data */    tls_server_t *p_tls;};struct httpd_url_t{    httpd_host_t *host;    vlc_mutex_t lock;    char    *psz_url;    char    *psz_user;    char    *psz_password;    struct    {        httpd_callback_t     cb;        httpd_callback_sys_t *p_sys;    } catch[HTTPD_MSG_MAX];};/* status */enum{    HTTPD_CLIENT_RECEIVING,    HTTPD_CLIENT_RECEIVE_DONE,    HTTPD_CLIENT_SENDING,    HTTPD_CLIENT_SEND_DONE,    HTTPD_CLIENT_WAITING,    HTTPD_CLIENT_DEAD,    HTTPD_CLIENT_TLS_HS_IN,    HTTPD_CLIENT_TLS_HS_OUT};/* mode */enum{    HTTPD_CLIENT_FILE,      /* default */    HTTPD_CLIENT_STREAM,    /* regulary get data from cb */    HTTPD_CLIENT_BIDIR,     /* check for reading and get data from cb */};struct httpd_client_t{    httpd_url_t *url;    int     i_ref;    struct  sockaddr_storage sock;    int     i_sock_size;    int     fd;    int     i_mode;    int     i_state;    int     b_read_waiting; /* stop as soon as possible sending */    mtime_t i_activity_date;    mtime_t i_activity_timeout;    /* buffer for reading header */    int     i_buffer_size;    int     i_buffer;    uint8_t *p_buffer;    /* */    httpd_message_t query;  /* client -> httpd */    httpd_message_t answer; /* httpd -> client */        /* TLS data */    tls_session_t *p_tls;};/***************************************************************************** * Various functions *****************************************************************************//*char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";*/static void b64_decode( char *dest, char *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{    char *psz_ext;    char *psz_mime;} http_mime[] ={    { ".htm",   "text/html" },    { ".html",  "text/html" },    { ".txt",   "text/plain" },    { ".xml",   "text/xml" },    { ".dtd",   "text/dtd" },    { ".css",   "text/css" },    /* image mime */    { ".gif",   "image/gif" },    { ".jpe",   "image/jpeg" },    { ".jpg",   "image/jpeg" },    { ".jpeg",  "image/jpeg" },    { ".png",   "image/png" },    { ".mpjpeg","multipart/x-mixed-replace; boundary=This Random String" },    /* media mime */    { ".avi",   "video/avi" },    { ".asf",   "video/x-ms-asf" },    { ".m1a",   "audio/mpeg" },    { ".m2a",   "audio/mpeg" },    { ".m1v",   "video/mpeg" },    { ".m2v",   "video/mpeg" },    { ".mp2",   "audio/mpeg" },    { ".mp3",   "audio/mpeg" },    { ".mpa",   "audio/mpeg" },    { ".mpg",   "video/mpeg" },    { ".mpeg",  "video/mpeg" },    { ".mpe",   "video/mpeg" },    { ".mov",   "video/quicktime" },    { ".moov",  "video/quicktime" },    { ".ogg",   "application/ogg" },    { ".ogm",   "application/ogg" },    { ".wav",   "audio/wav" },    { ".wma",   "audio/x-ms-wma" },    { ".wmv",   "video/x-ms-wmv" },    /* end */    { NULL,     NULL }};static char *httpd_MimeFromUrl( char *psz_url ){    char *psz_ext;    psz_ext = strrchr( psz_url, '.' );    if( psz_ext )    {        int i;        for( i = 0; http_mime[i].psz_ext != NULL ; i++ )        {            if( !strcasecmp( http_mime[i].psz_ext, psz_ext ) )            {                return http_mime[i].psz_mime;            }        }    }    return "application/octet-stream";}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -