Changeset 2c16687563b6e6096f5621db56917d9ef05424b2

Show
Ignore:
Timestamp:
22/06/08 19:31:07 (5 months ago)
Author:
Rémi Denis-Courmont <rdenis@simphalempin.com>
git-committer:
Rémi Denis-Courmont <rdenis@simphalempin.com> 1214155867 +0300
git-parent:

[f5623dec1ca290e9adcbbc34ba4fe3f03a4c2e69]

git-author:
Bill C. Riemers <briemers+git@redhat.com> 1214009271 -0400
Message:

http: fix Content-Length and stream closure issues.

Changes:
1. Don't send Connection: close or Connection: Keep-Alive.

So we will maintain a persistent connection with HTTP 1.1.

2. Close the connection if and only if the server does not send

Connection: close, and a zero length is received indicated by either
Content-Length: 0 or a 0 length size in the byte range.

3. Correct i_remaining to deal with file larger than 2GBi.
4. Update i_remaining in Read and OpenWithCookies?.
5. Use -1 for uninitialized size so we can tell the difference from a

zero length result.

Signed-off-by: Rémi Denis-Courmont <rdenis@simphalempin.com>

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/access/http.c

    ra735127 r2c16687  
    189189    char       *psz_icy_title; 
    190190 
    191     int i_remaining; 
     191    int64_t i_remaining; 
    192192 
    193193    bool b_seekable; 
     
    195195    bool b_continuous; 
    196196    bool b_pace_control; 
     197    bool b_persist; 
    197198 
    198199    vlc_array_t * cookies; 
     
    280281    p_sys->psz_icy_title = NULL; 
    281282    p_sys->i_remaining = 0; 
     283    p_sys->b_persist = false; 
     284    p_access->info.i_size = -1; 
     285    p_access->info.i_pos  = 0; 
     286    p_access->info.b_eof  = false; 
    282287 
    283288    p_sys->cookies = saved_cookies; 
     
    639644    } 
    640645 
    641     if( p_access->info.i_size > 0 && 
     646    if( p_access->info.i_size >= 0 && 
    642647        i_len + p_access->info.i_pos > p_access->info.i_size ) 
    643648    { 
     
    683688        } 
    684689    } 
    685  
    686     if( p_sys->b_continuous && (ssize_t)i_len > p_sys->i_remaining ) 
    687     { 
     690    else if( p_access->info.i_size != -1 && (int64_t)i_len > p_sys->i_remaining) { 
    688691        /* Only ask for the remaining length */ 
    689         int i_new_len = p_sys->i_remaining; 
    690         if( i_new_len == 0 ) 
    691         { 
    692             Request( p_access, 0 ); 
    693             i_read = Read( p_access, p_buffer, i_len ); 
    694             return i_read; 
    695         } 
    696         i_len = i_new_len; 
    697     } 
     692        i_len = (size_t)p_sys->i_remaining; 
     693        if(i_len == 0) { 
     694            p_access->info.b_eof = true; 
     695            return 0; 
     696        } 
     697    } 
     698 
    698699 
    699700    if( p_sys->i_icy_meta > 0 && p_access->info.i_pos > 0 ) 
     
    765766    } 
    766767 
    767     if( p_sys->b_continuous
     768    if( p_access->info.i_size != -1
    768769    { 
    769770        p_sys->i_remaining -= i_read; 
     
    10081009    p_sys->psz_icy_genre = NULL; 
    10091010    p_sys->psz_icy_title = NULL; 
    1010  
    1011     p_access->info.i_size = 0; 
     1011    p_sys->i_remaining = 0; 
     1012    p_sys->b_persist = false; 
     1013 
     1014    p_access->info.i_size = -1; 
    10121015    p_access->info.i_pos  = i_tell; 
    10131016    p_access->info.b_eof  = false; 
     
    11071110    char           *psz ; 
    11081111    v_socket_t     *pvs = p_sys->p_vs; 
    1109  
     1112    bool b_connection_close = false; 
     1113    p_sys->b_persist = false; 
     1114 
     1115    p_sys->i_remaining = 0; 
    11101116    if( p_sys->b_proxy ) 
    11111117    { 
     
    11501156                p_sys->psz_user_agent ); 
    11511157    /* Offset */ 
    1152     if( p_sys->i_version == 1 ) 
    1153     { 
     1158    if( p_sys->i_version == 1 && ! p_sys->b_continuous ) 
     1159    { 
     1160        p_sys->b_persist = true; 
    11541161        net_Printf( VLC_OBJECT(p_access), p_sys->fd, pvs, 
    11551162                    "Range: bytes=%"PRIu64"-\r\n", i_tell ); 
     
    11941201 
    11951202 
    1196     if( p_sys->b_continuous ) 
    1197     { 
    1198         net_Printf( VLC_OBJECT( p_access ), p_sys->fd, pvs, 
    1199                     "Connection: Keep-Alive\r\n" ); 
    1200     } 
    1201     else if( p_sys->i_version == 1 ) 
    1202     { 
    1203         net_Printf( VLC_OBJECT( p_access ), p_sys->fd, pvs, 
    1204                     "Connection: Close\r\n"); 
    1205     } 
    1206  
    12071203    if( net_Printf( VLC_OBJECT(p_access), p_sys->fd, pvs, "\r\n" ) < 0 ) 
    12081204    { 
     
    12941290        if( !strcasecmp( psz, "Content-Length" ) ) 
    12951291        { 
    1296             if( p_sys->b_continuous ) 
    1297             { 
    1298                 p_access->info.i_size = -1; 
    1299                 msg_Dbg( p_access, "this frame size=%lld", atoll(p ) ); 
    1300                 p_sys->i_remaining = atoll( p ); 
    1301             } 
    1302             else 
    1303             { 
    1304                 p_access->info.i_size = i_tell + atoll( p ); 
    1305                 msg_Dbg( p_access, "stream size=%"PRId64, p_access->info.i_size ); 
     1292            int64_t i_size = i_tell + (p_sys->i_remaining = atoll( p )); 
     1293            if(i_size > p_access->info.i_size) { 
     1294                p_access->info.i_size = i_size; 
     1295            } 
     1296            msg_Dbg( p_access, "this frame size=%"PRId64, p_sys->i_remaining ); 
     1297        } 
     1298        else if( !strcasecmp( psz, "Content-Range" ) ) { 
     1299            int64_t i_ntell = i_tell; 
     1300            int64_t i_nend = (p_access->info.i_size > 0)?(p_access->info.i_size - 1):i_tell; 
     1301            int64_t i_nsize = p_access->info.i_size; 
     1302            sscanf(p,"bytes %"PRId64"-%"PRId64"/%"PRId64,&i_ntell,&i_nend,&i_nsize); 
     1303            if(i_nend > i_ntell ) { 
     1304                p_access->info.i_pos = i_ntell; 
     1305                p_sys->i_remaining = i_nend+1-i_ntell; 
     1306                int64_t i_size = (i_nsize > i_nend) ? i_nsize : (i_nend + 1); 
     1307                if(i_size > p_access->info.i_size) { 
     1308                    p_access->info.i_size = i_size; 
     1309                } 
     1310                msg_Dbg( p_access, "stream size=%"PRId64",pos=%"PRId64",remaining=%"PRId64,i_nsize,i_ntell,p_sys->i_remaining); 
     1311            } 
     1312        } 
     1313        else if( !strcasecmp( psz, "Connection" ) ) { 
     1314            msg_Dbg( p_access, "Connection: %s",p ); 
     1315            int i = -1; 
     1316            sscanf(p, "close%n",&i); 
     1317            if( i >= 0 ) { 
     1318                p_sys->b_persist = false; 
    13061319            } 
    13071320        } 
     
    14561469 
    14571470        free( psz ); 
     1471    } 
     1472    /* We close the stream for zero length data, unless of course the 
     1473     * server has already promised to do this for us. 
     1474     */ 
     1475    if( p_access->info.i_size != -1 && p_sys->i_remaining == 0 && p_sys->b_persist ) { 
     1476        Disconnect( p_access ); 
    14581477    } 
    14591478    return VLC_SUCCESS;