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

📄 httpd.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
{    httpd_file_t *file = malloc( sizeof( httpd_file_t ) );    if( ( file->url = httpd_UrlNewUnique( host, psz_url, psz_user,                                          psz_password, p_acl )        ) == NULL )    {        free( file );        return NULL;    }    file->psz_url  = strdup( psz_url );    if( psz_mime && *psz_mime )    {        file->psz_mime = strdup( psz_mime );    }    else    {        file->psz_mime = strdup( httpd_MimeFromUrl( psz_url ) );    }    file->pf_fill = pf_fill;    file->p_sys   = p_sys;    httpd_UrlCatch( file->url, HTTPD_MSG_HEAD, httpd_FileCallBack,                    (httpd_callback_sys_t*)file );    httpd_UrlCatch( file->url, HTTPD_MSG_GET,  httpd_FileCallBack,                    (httpd_callback_sys_t*)file );    httpd_UrlCatch( file->url, HTTPD_MSG_POST, httpd_FileCallBack,                    (httpd_callback_sys_t*)file );    return file;}void httpd_FileDelete( httpd_file_t *file ){    httpd_UrlDelete( file->url );    free( file->psz_url );    free( file->psz_mime );    free( file );}/***************************************************************************** * High Level Functions: httpd_handler_t (for CGIs) *****************************************************************************/struct httpd_handler_t{    httpd_url_t *url;    httpd_handler_callback_t pf_fill;    httpd_handler_sys_t      *p_sys;};static int httpd_HandlerCallBack( httpd_callback_sys_t *p_sys, httpd_client_t *cl, httpd_message_t *answer, httpd_message_t *query ){    httpd_handler_t *handler = (httpd_handler_t*)p_sys;    uint8_t *psz_args = query->psz_args;    char psz_remote_addr[NI_MAXNUMERICHOST];    if( answer == NULL || query == NULL )    {        return VLC_SUCCESS;    }    answer->i_proto  = HTTPD_PROTO_NONE;    answer->i_type   = HTTPD_MSG_ANSWER;    /* We do it ourselves, thanks */    answer->i_status = 0;    answer->psz_status = NULL;    if( httpd_ClientIP( cl, psz_remote_addr ) == NULL )        *psz_remote_addr = '\0';    handler->pf_fill( handler->p_sys, handler, query->psz_url, psz_args,                      query->i_type, query->p_body, query->i_body,                      psz_remote_addr, NULL,                      &answer->p_body, &answer->i_body );    if( query->i_type == HTTPD_MSG_HEAD )    {        char *p = (char *)answer->p_body;        while ( (p = strchr( p, '\r' )) != NULL )        {            if( p[1] && p[1] == '\n' && p[2] && p[2] == '\r'                 && p[3] && p[3] == '\n' )            {                break;            }        }        if( p != NULL )        {            p[4] = '\0';            answer->i_body = strlen((char*)answer->p_body) + 1;            answer->p_body = realloc( answer->p_body, answer->i_body );        }    }    if( strncmp( (char *)answer->p_body, "HTTP/1.", 7 ) )    {        int i_status, i_headers;        char *psz_headers, *psz_new, *psz_status;        if( !strncmp( (char *)answer->p_body, "Status: ", 8 ) )        {            /* Apache-style */            i_status = strtol( (char *)&answer->p_body[8], &psz_headers, 0 );            if( *psz_headers ) psz_headers++;            if( *psz_headers ) psz_headers++;            i_headers = answer->i_body - (psz_headers - (char *)answer->p_body);        }        else        {            i_status = 200;            psz_headers = (char *)answer->p_body;            i_headers = answer->i_body;        }        switch( i_status )        {        case 200:            psz_status = "OK";            break;        case 401:            psz_status = "Unauthorized";            break;        default:            if( (i_status < 0) || (i_status > 999) )                i_status = 500;            psz_status = "Undefined";            break;        }        answer->i_body = sizeof("HTTP/1.0 xxx \r\n")                        + strlen(psz_status) + i_headers - 1;        psz_new = (char *)malloc( answer->i_body + 1);        sprintf( psz_new, "HTTP/1.0 %03d %s\r\n", i_status, psz_status );        memcpy( &psz_new[strlen(psz_new)], psz_headers, i_headers );        free( answer->p_body );        answer->p_body = (uint8_t *)psz_new;    }    return VLC_SUCCESS;}httpd_handler_t *httpd_HandlerNew( httpd_host_t *host, const char *psz_url,                                   const char *psz_user,                                   const char *psz_password,                                   const vlc_acl_t *p_acl,                                   httpd_handler_callback_t pf_fill,                                   httpd_handler_sys_t *p_sys ){    httpd_handler_t *handler = malloc( sizeof( httpd_handler_t ) );    if( ( handler->url = httpd_UrlNewUnique( host, psz_url, psz_user,                                             psz_password, p_acl )        ) == NULL )    {        free( handler );        return NULL;    }    handler->pf_fill = pf_fill;    handler->p_sys   = p_sys;    httpd_UrlCatch( handler->url, HTTPD_MSG_HEAD, httpd_HandlerCallBack,                    (httpd_callback_sys_t*)handler );    httpd_UrlCatch( handler->url, HTTPD_MSG_GET,  httpd_HandlerCallBack,                    (httpd_callback_sys_t*)handler );    httpd_UrlCatch( handler->url, HTTPD_MSG_POST, httpd_HandlerCallBack,                    (httpd_callback_sys_t*)handler );    return handler;}void httpd_HandlerDelete( httpd_handler_t *handler ){    httpd_UrlDelete( handler->url );    free( handler );}/***************************************************************************** * High Level Functions: httpd_redirect_t *****************************************************************************/struct httpd_redirect_t{    httpd_url_t *url;    char        *psz_dst;};static int httpd_RedirectCallBack( httpd_callback_sys_t *p_sys,                                   httpd_client_t *cl, httpd_message_t *answer,                                   httpd_message_t *query ){    httpd_redirect_t *rdir = (httpd_redirect_t*)p_sys;    char *p_body;    if( answer == NULL || query == NULL )    {        return VLC_SUCCESS;    }    answer->i_proto  = query->i_proto;    answer->i_version= query->i_version;    answer->i_type   = HTTPD_MSG_ANSWER;    answer->i_status = 301;    answer->psz_status = strdup( "Moved Permanently" );    answer->i_body = asprintf( &p_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>\n"        "<head>\n"        "<title>Redirection</title>\n"        "</head>\n"        "<body>\n"        "<h1>You should be "        "<a href=\"%s\">redirected</a></h1>\n"        "<hr />\n"        "<p><a href=\"http://www.videolan.org\">VideoLAN</a>\n</p>"        "<hr />\n"        "</body>\n"        "</html>\n", rdir->psz_dst );    answer->p_body = (unsigned char *)p_body;    /* XXX check if it's ok or we need to set an absolute url */    httpd_MsgAdd( answer, "Location",  "%s", rdir->psz_dst );    httpd_MsgAdd( answer, "Content-Length", "%d", answer->i_body );    return VLC_SUCCESS;}httpd_redirect_t *httpd_RedirectNew( httpd_host_t *host, const char *psz_url_dst,                                     const char *psz_url_src ){    httpd_redirect_t *rdir = malloc( sizeof( httpd_redirect_t ) );    if( !( rdir->url = httpd_UrlNewUnique( host, psz_url_src, NULL, NULL, NULL ) ) )    {        free( rdir );        return NULL;    }    rdir->psz_dst = strdup( psz_url_dst );    /* Redirect apply for all HTTP request and RTSP DESCRIBE resquest */    httpd_UrlCatch( rdir->url, HTTPD_MSG_HEAD, httpd_RedirectCallBack,                    (httpd_callback_sys_t*)rdir );    httpd_UrlCatch( rdir->url, HTTPD_MSG_GET, httpd_RedirectCallBack,                    (httpd_callback_sys_t*)rdir );    httpd_UrlCatch( rdir->url, HTTPD_MSG_POST, httpd_RedirectCallBack,                    (httpd_callback_sys_t*)rdir );    httpd_UrlCatch( rdir->url, HTTPD_MSG_DESCRIBE, httpd_RedirectCallBack,                    (httpd_callback_sys_t*)rdir );    return rdir;}void httpd_RedirectDelete( httpd_redirect_t *rdir ){    httpd_UrlDelete( rdir->url );    free( rdir->psz_dst );    free( rdir );}/***************************************************************************** * High Level Funtions: httpd_stream_t *****************************************************************************/struct httpd_stream_t{    vlc_mutex_t lock;    httpd_url_t *url;    char    *psz_mime;    /* Header to send as first packet */    uint8_t *p_header;    int     i_header;    /* circular buffer */    int         i_buffer_size;      /* buffer size, can't be reallocated smaller */    uint8_t     *p_buffer;          /* buffer */    int64_t     i_buffer_pos;       /* absolute position from begining */    int64_t     i_buffer_last_pos;  /* a new connection will start with that */};static int httpd_StreamCallBack( httpd_callback_sys_t *p_sys,                                 httpd_client_t *cl, httpd_message_t *answer,                                 httpd_message_t *query ){    httpd_stream_t *stream = (httpd_stream_t*)p_sys;    if( answer == NULL || query == NULL || cl == NULL )    {        return VLC_SUCCESS;    }    if( answer->i_body_offset > 0 )    {        int64_t i_write;        int     i_pos;#if 0        fprintf( stderr, "httpd_StreamCallBack i_body_offset=%lld\n",                 answer->i_body_offset );#endif        if( answer->i_body_offset >= stream->i_buffer_pos )        {            /* fprintf( stderr, "httpd_StreamCallBack: no data\n" ); */            return VLC_EGENERIC;    /* wait, no data available */        }        if( answer->i_body_offset + stream->i_buffer_size <            stream->i_buffer_pos )        {            /* this client isn't fast enough */#if 0            fprintf( stderr, "fixing i_body_offset (old=%lld new=%lld)\n",                     answer->i_body_offset, stream->i_buffer_last_pos );#endif            answer->i_body_offset = stream->i_buffer_last_pos;        }        i_pos   = answer->i_body_offset % stream->i_buffer_size;        i_write = stream->i_buffer_pos - answer->i_body_offset;        if( i_write > HTTPD_CL_BUFSIZE )        {            i_write = HTTPD_CL_BUFSIZE;        }        else if( i_write <= 0 )        {            return VLC_EGENERIC;    /* wait, no data available */        }        /* Don't go past the end of the circular buffer */        i_write = __MIN( i_write, stream->i_buffer_size - i_pos );        /* using HTTPD_MSG_ANSWER -> data available */        answer->i_proto  = HTTPD_PROTO_HTTP;        answer->i_version= 0;        answer->i_type   = HTTPD_MSG_ANSWER;        answer->i_body = i_write;        answer->p_body = malloc( i_write );        memcpy( answer->p_body, &stream->p_buffer[i_pos], i_write );        answer->i_body_offset += i_write;        return VLC_SUCCESS;    }    else    {        answer->i_proto  = HTTPD_PROTO_HTTP;        answer->i_version= 0;        answer->i_type   = HTTPD_MSG_ANSWER;        answer->i_status = 200;        answer->psz_status = strdup( "OK" );        if( query->i_type != HTTPD_MSG_HEAD )        {            httpd_ClientModeStream( cl );            vlc_mutex_lock( &stream->lock );            /* Send the header */            if( stream->i_header > 0 )            {                answer->i_body = stream->i_header;                answer->p_body = malloc( stream->i_header );                memcpy( answer->p_body, stream->p_header, stream->i_header );            }            answer->i_body_offset = stream->i_buffer_last_pos;            vlc_mutex_unlock( &stream->lock );        }        else        {            httpd_MsgAdd( answer, "Content-Length", "%d", 0 );            answer->i_body_offset = 0;        }        if( !strcmp( stream->psz_mime, "video/x-ms-asf-stream" ) )        {            vlc_bool_t b_xplaystream = VLC_FALSE;            int i;            httpd_MsgAdd( answer, "Content-type", "%s",                          "application/octet-stream" );            httpd_MsgAdd( answer, "Server", "Cougar 4.1.0.3921" );            httpd_MsgAdd( answer, "Pragma", "no-cache" );            httpd_MsgAdd( answer, "Pragma", "client-id=%d", rand()&0x7fff );            httpd_MsgAdd( answer, "Pragma", "features=\"broadcast\"" );            /* Check if there is a xPlayStrm=1 */            for( i = 0; i < query->i_name; i++ )            {                if( !strcasecmp( query->name[i],  "Pragma" ) &&                    strstr( query->value[i], "xPlayStrm=1" ) )                {                    b_xplaystream = VLC_TRUE;                }            }            if( !b_xplaystream )            {                answer->i_body_offset = 0;            }        }        else        {            httpd_MsgAdd( answer, "Content-type",  "%s", stream->psz_mime );        }        httpd_MsgAdd( answer, "Cache-Control", "%s", "no-cache" );        return VLC_SUCCESS;    }}httpd_stream_t *httpd_StreamNew( httpd_host_t *host,                                 const char *psz_url, const char *psz_mime,                                 const char *psz_user, const char *psz_password,                                 const vlc_acl_t *p_acl ){    httpd_stream_t *stream = malloc( sizeof( httpd_stream_t ) );    if( ( stream->url = httpd_UrlNewUnique( host, psz_url, psz_user,                                            psz_password, p_acl )        ) == NULL )    {        free( stream );        return NULL;    }    vlc_mutex_init( host, &stream->lock );

⌨️ 快捷键说明

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