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

📄 httpd.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** * httpd.c ***************************************************************************** * Copyright (C) 2004-2006 the VideoLAN team * Copyright © 2004-2007 Rémi Denis-Courmont * $Id: c98b51c22797faa21727b9ff2256a6661d1e7bde $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> *          Rémi 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_httpd.h>#ifdef ENABLE_HTTPD#include <assert.h>#include <vlc_network.h>#include <vlc_tls.h>#include <vlc_acl.h>#include <vlc_strings.h>#include "../libvlc.h"#include <string.h>#include <errno.h>#ifdef HAVE_UNISTD_H#   include <unistd.h>#endif#ifdef HAVE_FCNTL_H#   include <fcntl.h>#endif#ifdef HAVE_POLL# include <poll.h>#endif#if defined( UNDER_CE )#   include <winsock.h>#elif defined( WIN32 )#   include <winsock2.h>#else#   include <sys/socket.h>#endif#if defined( WIN32 )/* We need HUGE buffer otherwise TCP throughput is very limited */#define HTTPD_CL_BUFSIZE 1000000#else#define HTTPD_CL_BUFSIZE 10000#endifstatic void httpd_ClientClean( httpd_client_t *cl );struct httpd_t{    VLC_COMMON_MEMBERS    int          i_host;    httpd_host_t **host;};/* 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 */    char        *psz_hostname;    int         i_port;    int         *fds;    unsigned     nfd;    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;    vlc_acl_t *p_acl;    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;    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 *****************************************************************************/static const struct{    const char psz_ext[8];    const 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" },    /* same as modules/mux/mpjpeg.c here: */    { ".mpjpeg","multipart/x-mixed-replace; boundary=7b3cc56e5f51db803f790dad720ed50a" },    /* 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 */    { "",       "" }};static const char *httpd_MimeFromUrl( const char *psz_url ){    char *psz_ext;    psz_ext = strrchr( psz_url, '.' );    if( psz_ext )    {        int i;        for( i = 0; http_mime[i].psz_ext[0] ; i++ )        {            if( !strcasecmp( http_mime[i].psz_ext, psz_ext ) )            {                return http_mime[i].psz_mime;            }        }    }    return "application/octet-stream";}typedef struct{    unsigned   i_code;    const char psz_reason[36];} http_status_info;static const http_status_info http_reason[] ={  /*{ 100, "Continue" },    { 101, "Switching Protocols" },*/    { 200, "OK" },  /*{ 201, "Created" },    { 202, "Accepted" },    { 203, "Non-authoritative information" },    { 204, "No content" },    { 205, "Reset content" },    { 206, "Partial content" },    { 250, "Low on storage space" },    { 300, "Multiple choices" },*/    { 301, "Moved permanently" },  /*{ 302, "Moved temporarily" },    { 303, "See other" },    { 304, "Not modified" },    { 305, "Use proxy" },    { 307, "Temporary redirect" },    { 400, "Bad request" },*/    { 401, "Unauthorized" },  /*{ 402, "Payment Required" },*/    { 403, "Forbidden" },    { 404, "Not found" },    { 405, "Method not allowed" },  /*{ 406, "Not acceptable" },    { 407, "Proxy authentication required" },    { 408, "Request time-out" },    { 409, "Conflict" },    { 410, "Gone" },    { 411, "Length required" },    { 412, "Precondition failed" },    { 413, "Request entity too large" },    { 414, "Request-URI too large" },    { 415, "Unsupported media Type" },    { 416, "Requested range not satisfiable" },    { 417, "Expectation failed" },    { 451, "Parameter not understood" },    { 452, "Conference not found" },    { 453, "Not enough bandwidth" },*/    { 454, "Session not found" },  /*{ 455, "Method not valid in this State" },*/    { 456, "Header field not valid for resource" },  /*{ 457, "Invalid range" },    { 458, "Read-only parameter" },*/    { 459, "Aggregate operation not allowed" },    { 460, "Non-aggregate operation not allowed" },    { 461, "Unsupported transport" },  /*{ 462, "Destination unreachable" },*/    { 500, "Internal server error" },    { 501, "Not implemented" },  /*{ 502, "Bad gateway" },*/    { 503, "Service unavailable" },  /*{ 504, "Gateway time-out" },*/    { 505, "Protocol version not supported" },    { 551, "Option not supported" },    { 999, "" }};static const char psz_fallback_reason[5][16] ={ "Continue", "OK", "Found", "Client error", "Server error" };static const char *httpd_ReasonFromCode( unsigned i_code ){    const http_status_info *p;    assert( ( i_code >= 100 ) && ( i_code <= 599 ) );    for (p = http_reason; i_code > p->i_code; p++);    if( p->i_code == i_code )        return p->psz_reason;    return psz_fallback_reason[(i_code / 100) - 1];}static size_t httpd_HtmlError (char **body, int code, const char *url){    const char *errname = httpd_ReasonFromCode (code);    assert (errname != NULL);    int res = asprintf (body,        "<?xml version=\"1.0\" encoding=\"ascii\" ?>\n"        "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\""        " \"http://www.w3.org/TR/xhtml10/DTD/xhtml10strict.dtd\">\n"        "<html lang=\"en\">\n"        "<head>\n"        "<title>%s</title>\n"        "</head>\n"        "<body>\n"        "<h1>%d %s%s%s%s</h1>\n"        "<hr />\n"        "<a href=\"http://www.videolan.org\">VideoLAN</a>\n"        "</body>\n"        "</html>\n", errname, code, errname,        (url ? " (" : ""), (url ?: ""), (url ? ")" : ""));    if (res == -1)    {        *body = NULL;        return 0;    }    return (size_t)res;}/***************************************************************************** * High Level Functions: httpd_file_t *****************************************************************************/struct httpd_file_t{    httpd_url_t *url;    char *psz_url;    char *psz_mime;    httpd_file_callback_t pf_fill;    httpd_file_sys_t      *p_sys;};static inthttpd_FileCallBack( httpd_callback_sys_t *p_sys, httpd_client_t *cl,                    httpd_message_t *answer, const httpd_message_t *query ){    httpd_file_t *file = (httpd_file_t*)p_sys;    uint8_t **pp_body, *p_body;    const char *psz_connection;    int *pi_body, i_body;    if( answer == NULL || query == NULL )    {        return VLC_SUCCESS;    }    answer->i_proto  = HTTPD_PROTO_HTTP;    answer->i_version= 1;    answer->i_type   = HTTPD_MSG_ANSWER;    answer->i_status = 200;    httpd_MsgAdd( answer, "Content-type",  "%s", file->psz_mime );    httpd_MsgAdd( answer, "Cache-Control", "%s", "no-cache" );    if( query->i_type != HTTPD_MSG_HEAD )    {        pp_body = &answer->p_body;        pi_body = &answer->i_body;    }    else    {        /* The file still needs to be executed. */        p_body = NULL;        i_body = 0;        pp_body = &p_body;        pi_body = &i_body;    }    if( query->i_type == HTTPD_MSG_POST )    {        /* msg_Warn not supported */    }    uint8_t *psz_args = query->psz_args;    file->pf_fill( file->p_sys, file, psz_args, pp_body, pi_body );    if( query->i_type == HTTPD_MSG_HEAD && p_body != NULL )    {        free( p_body );    }    /* We respect client request */

⌨️ 快捷键说明

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