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

📄 httpd.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 5 页
字号:
    url->catch[i_msg].p_sys= p_sys;    vlc_mutex_unlock( &url->lock );    return VLC_SUCCESS;}/* delete an url */void httpd_UrlDelete( httpd_url_t *url ){    httpd_host_t *host = url->host;    int          i;    vlc_mutex_lock( &host->lock );    TAB_REMOVE( host->i_url, host->url, url );    vlc_mutex_destroy( &url->lock );    free( url->psz_url );    free( url->psz_user );    free( url->psz_password );    for( i = 0; i < host->i_client; i++ )    {        httpd_client_t *client = host->client[i];        if( client->url == url )        {            /* TODO complete it */            msg_Warn( host, "force closing connections" );            httpd_ClientClean( client );            TAB_REMOVE( host->i_client, host->client, client );            free( client );            i--;        }    }    free( url );    vlc_mutex_unlock( &host->lock );}void httpd_MsgInit( httpd_message_t *msg ){    msg->cl         = NULL;    msg->i_type     = HTTPD_MSG_NONE;    msg->i_proto    = HTTPD_PROTO_NONE;    msg->i_version  = -1;    msg->i_status   = 0;    msg->psz_status = NULL;    msg->psz_url = NULL;    msg->psz_args = NULL;    msg->i_channel = -1;    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        = 0;}void httpd_MsgClean( httpd_message_t *msg ){    int i;    if( msg->psz_status )    {        free( msg->psz_status );    }    if( msg->psz_url )    {        free( msg->psz_url );    }    if( msg->psz_args )    {        free( msg->psz_args );    }    for( i = 0; i < msg->i_name; i++ )    {        free( msg->name[i] );        free( msg->value[i] );    }    if( msg->name )    {        free( msg->name );    }    if( msg->value )    {        free( msg->value );    }    if( msg->p_body )    {        free( msg->p_body );    }    httpd_MsgInit( msg );}char *httpd_MsgGet( httpd_message_t *msg, char *name ){    int i;    for( i = 0; i < msg->i_name; i++ )    {        if( !strcasecmp( msg->name[i], name ))        {            return msg->value[i];        }    }    return "";}void httpd_MsgAdd( httpd_message_t *msg, char *name, char *psz_value, ... ){    va_list args;    char *value = NULL;    va_start( args, psz_value );#if defined(HAVE_VASPRINTF) && !defined(SYS_DARWIN) && !defined(SYS_BEOS)    vasprintf( &value, psz_value, args );#else    {        int i_size = strlen( psz_value ) + 4096;    /* FIXME stupid system */        value = calloc( i_size, sizeof( char ) );        vsnprintf( value, i_size, psz_value, args );        value[i_size - 1] = 0;    }#endif    va_end( args );    name = strdup( name );    TAB_APPEND( msg->i_name,  msg->name,  name );    TAB_APPEND( msg->i_value, msg->value, value );}static void httpd_ClientInit( httpd_client_t *cl ){    cl->i_state = HTTPD_CLIENT_RECEIVING;    cl->i_activity_date = mdate();    cl->i_activity_timeout = I64C(10000000);    cl->i_buffer_size = 10000;    cl->i_buffer = 0;    cl->p_buffer = malloc( cl->i_buffer_size );    cl->i_mode   = HTTPD_CLIENT_FILE;    cl->b_read_waiting = VLC_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( httpd_client_t *cl ){#ifdef HAVE_GETNAMEINFO    char sz_ip[INET6_ADDRSTRLEN + 2];    int i;    if( (cl->sock.ss_family == AF_INET6) &&        IN6_IS_ADDR_V4MAPPED( &((const struct sockaddr_in6 *)                              &cl->sock)->sin6_addr) )    {        /* If client is using IPv4 but server is using IPv6 */        struct sockaddr_in a;                memset( &a, 0, sizeof( a ) );        a.sin_family = AF_INET;        a.sin_port = ((const struct sockaddr_in6 *)&cl->sock)->sin6_port;        a.sin_addr.s_addr = ((const uint32_t *)&((const struct sockaddr_in6 *)                            &cl->sock)->sin6_addr)[3];        i = getnameinfo( (const struct sockaddr *)&a, sizeof( a ),                         &sz_ip[1], INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST );    }    else        i = getnameinfo( (const struct sockaddr *)&cl->sock, cl->i_sock_size,                         &sz_ip[1], INET6_ADDRSTRLEN, NULL, 0,                         NI_NUMERICHOST );    if( i != 0 )        /* FIXME: msg_Err */        return NULL;            if( strchr( &sz_ip[1], ':' ) != NULL )    {        *sz_ip = '[';        i = strlen( sz_ip );        sz_ip[i++] = ']';        sz_ip[i] = '\0';               return strdup( sz_ip );    }        return strdup( &sz_ip[1] );#else    /* FIXME not thread safe */    return strdup( inet_ntoa( ((const struct sockaddr_in *)&cl->sock)->sin_addr ) );#endif}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 );    if( cl->p_buffer )    {        free( cl->p_buffer );        cl->p_buffer = NULL;    }}static httpd_client_t *httpd_ClientNew( int fd, struct sockaddr_storage *sock,                                        int i_sock_size,                                        tls_session_t *p_tls ){    httpd_client_t *cl = malloc( sizeof( httpd_client_t ) );    cl->i_ref   = 0;    cl->fd      = fd;    memcpy( &cl->sock, sock, sizeof( cl->sock ) );    cl->i_sock_size = i_sock_size;    cl->url     = NULL;    cl->p_tls = p_tls;    httpd_ClientInit( cl );    return cl;}static int httpd_NetRecv( httpd_client_t *cl, char *p, int i_len ){    tls_session_t *p_tls;        p_tls = cl->p_tls;    if( p_tls != NULL)        return tls_Recv( p_tls, p, i_len );    return recv( cl->fd, p, i_len, 0 );}static int httpd_NetSend( httpd_client_t *cl, const char *p, int i_len ){    tls_session_t *p_tls;    p_tls = cl->p_tls;    if( p_tls != NULL)        return tls_Send( p_tls, p, i_len );    return send( cl->fd, p, i_len, 0 );}static void httpd_ClientRecv( httpd_client_t *cl ){    int i_len;    if( cl->query.i_proto == HTTPD_PROTO_NONE )    {        /* enought to see if it's rtp over rtsp or RTSP/HTTP */        i_len = httpd_NetRecv( cl, &cl->p_buffer[cl->i_buffer],                               4 - cl->i_buffer );        if( i_len > 0 )        {            cl->i_buffer += i_len;        }        if( cl->i_buffer >= 4 )        {            /*fprintf( stderr, "peek=%4.4s\n", cl->p_buffer );*/            /* detect type */            if( cl->p_buffer[0] == '$' )            {                /* RTSP (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      = 0;            }            else if( !strncmp( cl->p_buffer, "HTTP", 4 ) )            {                cl->query.i_proto = HTTPD_PROTO_HTTP;                cl->query.i_type  = HTTPD_MSG_ANSWER;            }            else if( !strncmp( cl->p_buffer, "RTSP", 4 ) )            {                cl->query.i_proto = HTTPD_PROTO_RTSP;                cl->query.i_type  = HTTPD_MSG_ANSWER;            }            else if( !strncmp( cl->p_buffer, "GET", 3 ) ||                     !strncmp( cl->p_buffer, "HEAD", 4 ) ||                     !strncmp( cl->p_buffer, "POST", 4 ) )            {                cl->query.i_proto = HTTPD_PROTO_HTTP;                cl->query.i_type  = HTTPD_MSG_NONE;            }            else            {                cl->query.i_proto = HTTPD_PROTO_RTSP;                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( ;; )        {            i_len = httpd_NetRecv (cl, &cl->p_buffer[cl->i_buffer], 1 );            if( i_len <= 0 )            {                break;            }            cl->i_buffer++;            if( cl->i_buffer + 1 >= cl->i_buffer_size )            {                cl->i_buffer_size += 1024;                cl->p_buffer = realloc( cl->p_buffer, cl->i_buffer_size );            }            if( ( cl->i_buffer >= 2 && !strncmp( &cl->p_buffer[cl->i_buffer-2], "\n\n", 2 ) )||                ( cl->i_buffer >= 4 && !strncmp( &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 )                {                    cl->query.i_status =                        strtol( &cl->p_buffer[strlen( "HTTP/1.x" )], &p, 0 );                    while( *p == ' ' )                    {                        p++;                    }                    cl->query.psz_status = strdup( p );                }                else                {                    static const struct                    {                        char *name;                        int  i_type;                        int  i_proto;                    }                    msg_type[] =                    {                        { "GET",        HTTPD_MSG_GET,  HTTPD_PROTO_HTTP },                        { "HEAD",       HTTPD_MSG_HEAD, HTTPD_PROTO_HTTP },                        { "POST",       HTTPD_MSG_POST, HTTPD_PROTO_HTTP },                        { "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 },                        { "TEARDOWN",   HTTPD_MSG_TEARDOWN, HTTPD_PROTO_RTSP },                        { NULL,         HTTPD_MSG_NONE,     HTTPD_PROTO_NONE }                    };                    int  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 != NULL; i++ )                    {                        if( !strncmp( cl->p_buffer, msg_type[i].name,                                      strlen( msg_type[i].name ) ) )                        {                            p = &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( cl->p_buffer, "HTTP/1." ) )                        {                            cl->query.i_proto = HTTPD_PROTO_HTTP;                        }                        else if( strstr( cl->p_buffer, "RTSP/1." ) )                        {                            cl->query.i_proto = HTTPD_PROTO_RTSP;                        }                    }                    else                    {                        char *p2;                        char *p3;                        while( *p == ' ' )                        {                            p++;

⌨️ 快捷键说明

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