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

📄 httpd.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
    msg->i_name     = 0;    msg->name       = NULL;    msg->i_value    = 0;    msg->value      = NULL;    msg->i_body_offset = 0;    msg->i_body        = 0;    msg->p_body        = NULL;}void httpd_MsgClean( httpd_message_t *msg ){    int i;    free( msg->psz_url );    free( msg->psz_args );    for( i = 0; i < msg->i_name; i++ )    {        free( msg->name[i] );        free( msg->value[i] );    }    free( msg->name );    free( msg->value );    free( msg->p_body );    httpd_MsgInit( msg );}const char *httpd_MsgGet( const httpd_message_t *msg, const char *name ){    int i;    for( i = 0; i < msg->i_name; i++ )    {        if( !strcasecmp( msg->name[i], name ))        {            return msg->value[i];        }    }    return NULL;}void httpd_MsgAdd( httpd_message_t *msg, const char *name, const char *psz_value, ... ){    va_list args;    char *value = NULL;    va_start( args, psz_value );    if( vasprintf( &value, psz_value, args ) == -1 )        value = NULL;    va_end( args );    if( value == NULL )        return;    name = strdup( name );    if( name == NULL )    {        free( value );        return;    }    TAB_APPEND( msg->i_name,  msg->name,  (char*)name );    TAB_APPEND( msg->i_value, msg->value, value );}static void httpd_ClientInit( httpd_client_t *cl, mtime_t now ){    cl->i_state = HTTPD_CLIENT_RECEIVING;    cl->i_activity_date = now;    cl->i_activity_timeout = INT64_C(10000000);    cl->i_buffer_size = HTTPD_CL_BUFSIZE;    cl->i_buffer = 0;    cl->p_buffer = malloc( cl->i_buffer_size );    cl->i_mode   = HTTPD_CLIENT_FILE;    cl->b_read_waiting = false;    httpd_MsgInit( &cl->query );    httpd_MsgInit( &cl->answer );}void httpd_ClientModeStream( httpd_client_t *cl ){    cl->i_mode   = HTTPD_CLIENT_STREAM;}void httpd_ClientModeBidir( httpd_client_t *cl ){    cl->i_mode   = HTTPD_CLIENT_BIDIR;}char* httpd_ClientIP( const httpd_client_t *cl, char *psz_ip ){    return net_GetPeerAddress( cl->fd, psz_ip, NULL ) ? NULL : psz_ip;}char* httpd_ServerIP( const httpd_client_t *cl, char *psz_ip ){    return net_GetSockAddress( cl->fd, psz_ip, NULL ) ? NULL : psz_ip;}static void httpd_ClientClean( httpd_client_t *cl ){    if( cl->fd >= 0 )    {        if( cl->p_tls != NULL )            tls_ServerSessionClose( cl->p_tls );        net_Close( cl->fd );        cl->fd = -1;    }    httpd_MsgClean( &cl->answer );    httpd_MsgClean( &cl->query );    free( cl->p_buffer );    cl->p_buffer = NULL;}static httpd_client_t *httpd_ClientNew( int fd, tls_session_t *p_tls, mtime_t now ){    httpd_client_t *cl = malloc( sizeof( httpd_client_t ) );    if( !cl ) return NULL;    cl->i_ref   = 0;    cl->fd      = fd;    cl->url     = NULL;    cl->p_tls = p_tls;    httpd_ClientInit( cl, now );    return cl;}staticssize_t httpd_NetRecv (httpd_client_t *cl, uint8_t *p, size_t i_len){    tls_session_t *p_tls;    ssize_t val;    p_tls = cl->p_tls;    do        val = p_tls ? tls_Recv (p_tls, p, i_len)                    : recv (cl->fd, p, i_len, 0);    while (val == -1 && errno == EINTR);    return val;}staticssize_t httpd_NetSend (httpd_client_t *cl, const uint8_t *p, size_t i_len){    tls_session_t *p_tls;    ssize_t val;    p_tls = cl->p_tls;    do        val = p_tls ? tls_Send( p_tls, p, i_len )                    : send (cl->fd, p, i_len, 0);    while (val == -1 && errno == EINTR);    return val;}static const struct{    const char name[16];    int  i_type;    int  i_proto;}msg_type[] ={    { "OPTIONS",       HTTPD_MSG_OPTIONS,      HTTPD_PROTO_RTSP },    { "DESCRIBE",      HTTPD_MSG_DESCRIBE,     HTTPD_PROTO_RTSP },    { "SETUP",         HTTPD_MSG_SETUP,        HTTPD_PROTO_RTSP },    { "PLAY",          HTTPD_MSG_PLAY,         HTTPD_PROTO_RTSP },    { "PAUSE",         HTTPD_MSG_PAUSE,        HTTPD_PROTO_RTSP },    { "GET_PARAMETER", HTTPD_MSG_GETPARAMETER, HTTPD_PROTO_RTSP },    { "TEARDOWN",      HTTPD_MSG_TEARDOWN,     HTTPD_PROTO_RTSP },    { "GET",           HTTPD_MSG_GET,          HTTPD_PROTO_HTTP },    { "HEAD",          HTTPD_MSG_HEAD,         HTTPD_PROTO_HTTP },    { "POST",          HTTPD_MSG_POST,         HTTPD_PROTO_HTTP },    { "",              HTTPD_MSG_NONE,         HTTPD_PROTO_NONE }};static void httpd_ClientRecv( httpd_client_t *cl ){    int i_len;    /* ignore leading whites */    if( ( cl->query.i_proto == HTTPD_PROTO_NONE ) &&        ( cl->i_buffer == 0 ) )    {        unsigned char c;        i_len = httpd_NetRecv( cl, &c, 1 );        if( ( i_len > 0 ) && ( strchr( "\r\n\t ", c ) == NULL ) )        {            cl->p_buffer[0] = c;            cl->i_buffer++;        }    }    else    if( cl->query.i_proto == HTTPD_PROTO_NONE )    {        /* enough to see if it's Interleaved RTP over RTSP or RTSP/HTTP */        i_len = httpd_NetRecv( cl, &cl->p_buffer[cl->i_buffer],                               7 - cl->i_buffer );        if( i_len > 0 )        {            cl->i_buffer += i_len;        }        if( ( cl->i_buffer >= 4 ) && ( cl->p_buffer[0] == '$' ) )        {            /* Interleaved RTP over RTSP */            cl->query.i_proto = HTTPD_PROTO_RTSP;            cl->query.i_type  = HTTPD_MSG_CHANNEL;            cl->query.i_channel = cl->p_buffer[1];            cl->query.i_body  = (cl->p_buffer[2] << 8)|cl->p_buffer[3];            cl->query.p_body  = malloc( cl->query.i_body );            cl->i_buffer      -= 4;            memcpy( cl->query.p_body, cl->p_buffer + 4, cl->i_buffer );        }        else        /* The smallest legal request is 7 bytes ("GET /\r\n"),         * this is the maximum we can ask at this point. */        if( cl->i_buffer >= 7 )        {            if( !memcmp( cl->p_buffer, "HTTP/1.", 7 ) )            {                cl->query.i_proto = HTTPD_PROTO_HTTP;                cl->query.i_type  = HTTPD_MSG_ANSWER;            }            else if( !memcmp( cl->p_buffer, "RTSP/1.", 7 ) )            {                cl->query.i_proto = HTTPD_PROTO_RTSP;                cl->query.i_type  = HTTPD_MSG_ANSWER;            }            else            {                /* We need the full request line to determine the protocol. */                cl->query.i_proto = HTTPD_PROTO_HTTP0;                cl->query.i_type  = HTTPD_MSG_NONE;            }        }    }    else if( cl->query.i_body > 0 )    {        /* we are reading the body of a request or a channel */        i_len = httpd_NetRecv( cl, &cl->query.p_body[cl->i_buffer],                               cl->query.i_body - cl->i_buffer );        if( i_len > 0 )        {            cl->i_buffer += i_len;        }        if( cl->i_buffer >= cl->query.i_body )        {            cl->i_state = HTTPD_CLIENT_RECEIVE_DONE;        }    }    else    {        /* we are reading a header -> char by char */        for( ;; )        {            if( cl->i_buffer == cl->i_buffer_size )            {                uint8_t *newbuf = realloc( cl->p_buffer, cl->i_buffer_size + 1024 );                if( newbuf == NULL )                {                    i_len = 0;                    break;                }                cl->p_buffer = newbuf;                cl->i_buffer_size += 1024;            }            i_len = httpd_NetRecv (cl, &cl->p_buffer[cl->i_buffer], 1 );            if( i_len <= 0 )            {                break;            }            cl->i_buffer++;            if( ( cl->query.i_proto == HTTPD_PROTO_HTTP0 )             && ( cl->p_buffer[cl->i_buffer - 1] == '\n' ) )            {                /* Request line is now complete */                const char *p = memchr( cl->p_buffer, ' ', cl->i_buffer );                size_t len;                assert( cl->query.i_type == HTTPD_MSG_NONE );                if( p == NULL ) /* no URI: evil guy */                {                    i_len = 0; /* drop connection */                    break;                }                do                    p++; /* skips extra spaces */                while( *p == ' ' );                p = memchr( p, ' ', ((char *)cl->p_buffer) + cl->i_buffer - p );                if( p == NULL ) /* no explicit protocol: HTTP/0.9 */                {                    i_len = 0; /* not supported currently -> drop */                    break;                }                do                    p++; /* skips extra spaces ever again */                while( *p == ' ' );                len = ((char *)cl->p_buffer) + cl->i_buffer - p;                if( len < 7 ) /* foreign protocol */                    i_len = 0; /* I don't understand -> drop */                else                if( memcmp( p, "HTTP/1.", 7 ) == 0 )                {                    cl->query.i_proto = HTTPD_PROTO_HTTP;                    cl->query.i_version = atoi( p + 7 );                }                else                if( memcmp( p, "RTSP/1.", 7 ) == 0 )                {                    cl->query.i_proto = HTTPD_PROTO_RTSP;                    cl->query.i_version = atoi( p + 7 );                }                else                if( memcmp( p, "HTTP/", 5 ) == 0 )                {                    const uint8_t sorry[] =                       "HTTP/1.1 505 Unknown HTTP version\r\n\r\n";                    httpd_NetSend( cl, sorry, sizeof( sorry ) - 1 );                    i_len = 0; /* drop */                }                else                if( memcmp( p, "RTSP/", 5 ) == 0 )                {                    const uint8_t sorry[] =                        "RTSP/1.0 505 Unknown RTSP version\r\n\r\n";                    httpd_NetSend( cl, sorry, sizeof( sorry ) - 1 );                    i_len = 0; /* drop */                }                else /* yet another foreign protocol */                    i_len = 0;                if( i_len == 0 )                    break;            }            if( ( cl->i_buffer >= 2 && !memcmp( &cl->p_buffer[cl->i_buffer-2], "\n\n", 2 ) )||                ( cl->i_buffer >= 4 && !memcmp( &cl->p_buffer[cl->i_buffer-4], "\r\n\r\n", 4 ) ) )            {                char *p;                /* we have finished the header so parse it and set i_body */                cl->p_buffer[cl->i_buffer] = '\0';                if( cl->query.i_type == HTTPD_MSG_ANSWER )                {                    /* FIXME:                     * assume strlen( "HTTP/1.x" ) = 8                     */                    cl->query.i_status =                        strtol( (char *)&cl->p_buffer[8],                                &p, 0 );                    while( *p == ' ' )                        p++;                }                else                {                    unsigned i;                    p = NULL;                    cl->query.i_type = HTTPD_MSG_NONE;                    /*fprintf( stderr, "received new request=%s\n", cl->p_buffer);*/                    for( i = 0; msg_type[i].name[0]; i++ )                    {                        if( !strncmp( (char *)cl->p_buffer, msg_type[i].name,                                      strlen( msg_type[i].name ) ) )                        {                            p = (char *)&cl->p_buffer[strlen(msg_type[i].name) + 1 ];                            cl->query.i_type = msg_type[i].i_type;                            if( cl->query.i_proto != msg_type[i].i_proto )                            {                                p = NULL;                                cl->query.i_proto = HTTPD_PROTO_NONE;                                cl->query.i_type = HTTPD_MSG_NONE;                            }                            break;                        }                    }                    if( p == NULL )                    {                        if( strstr( (char *)cl->p_buffer, "HTTP/1." ) )                        {                            cl->query.i_proto = HTTPD_PROTO_HTTP;                        }                        else if( strstr( (char *)cl->p_buffer, "RTSP/1." ) )                        {                            cl->query.i_proto = HTTPD_PROTO_RTSP;                        }                    }                    else                    {                        char *p2;                        char *p3;                        while( *p == ' ' )                        {                            p++;                        }                        p2 = strchr( p, ' ' );                        if( p2 )                        {                            *p2++ = '\0';                        }                        if( !strncasecmp( p, "rtsp:", 5 ) )                        {                            /* for rtsp url, you have rtsp://localhost:port/path */                            p += 5;                            while( *p == '/' ) p++;                            while( *p && *p != '/' ) p++;                        }                        cl->query.psz_url = strdup( p );                        if( ( p3 = strchr( cl->query.psz_url, '?' ) )  )                        {                            *p3++ = '\0';                            cl->query.psz_args = (uint8_t *)strdup( p3 );                        }                        p = p2;                    }                }                if( p )                {

⌨️ 快捷键说明

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