@ -55,6 +55,8 @@ typedef struct {
int end_chunked_post ; /**< A flag which indicates if the end of chunked encoding has been sent. */
int end_header ; /**< A flag which indicates we have finished to read POST reply. */
int multiple_requests ; /**< A flag which indicates if we use persistent connections. */
uint8_t * post_data ;
int post_datalen ;
} HTTPContext ;
# define OFFSET(x) offsetof(HTTPContext, x)
@ -66,6 +68,7 @@ static const AVOption options[] = {
{ " headers " , " custom HTTP headers, can override built in default headers " , OFFSET ( headers ) , AV_OPT_TYPE_STRING , { 0 } , 0 , 0 , D | E } ,
{ " user-agent " , " override User-Agent header " , OFFSET ( user_agent ) , AV_OPT_TYPE_STRING , { . str = NULL } , 0 , 0 , DEC } ,
{ " multiple_requests " , " use persistent connections " , OFFSET ( multiple_requests ) , AV_OPT_TYPE_INT , { . dbl = 0 } , 0 , 1 , D | E } ,
{ " post_data " , " custom HTTP post data " , OFFSET ( post_data ) , AV_OPT_TYPE_BINARY , . flags = D | E } ,
{ NULL }
} ;
# define HTTP_CLASS(flavor)\
@ -227,7 +230,7 @@ static int http_getc(HTTPContext *s)
if ( s - > buf_ptr > = s - > buf_end ) {
len = ffurl_read ( s - > hd , s - > buffer , BUFFER_SIZE ) ;
if ( len < 0 ) {
return AVERROR ( EIO ) ;
return len ;
} else if ( len = = 0 ) {
return - 1 ;
} else {
@ -247,7 +250,7 @@ static int http_get_line(HTTPContext *s, char *line, int line_size)
for ( ; ; ) {
ch = http_getc ( s ) ;
if ( ch < 0 )
return AVERROR ( EIO ) ;
return ch ;
if ( ch = = ' \n ' ) {
/* process line */
if ( q > line & & q [ - 1 ] = = ' \r ' )
@ -354,8 +357,8 @@ static int http_read_header(URLContext *h, int *new_location)
int err = 0 ;
for ( ; ; ) {
if ( http_get_line ( s , line , sizeof ( line ) ) < 0 )
return AVERROR ( EIO ) ;
if ( ( err = http_get_line ( s , line , sizeof ( line ) ) ) < 0 )
return err ;
av_dlog ( NULL , " header='%s' \n " , line ) ;
@ -385,6 +388,14 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
/* send http header */
post = h - > flags & AVIO_FLAG_WRITE ;
if ( s - > post_data ) {
/* force POST method and disable chunked encoding when
* custom HTTP post data is set */
post = 1 ;
s - > chunked_post = 0 ;
}
method = post ? " POST " : " GET " ;
authstr = ff_http_auth_create_response ( & s - > auth_state , auth , local_path ,
method ) ;
@ -416,6 +427,9 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
if ( ! has_header ( s - > headers , " \r \n Host: " ) )
len + = av_strlcatf ( headers + len , sizeof ( headers ) - len ,
" Host: %s \r \n " , hoststr ) ;
if ( ! has_header ( s - > headers , " \r \n Content-Length: " ) & & s - > post_data )
len + = av_strlcatf ( headers + len , sizeof ( headers ) - len ,
" Content-Length: %d \r \n " , s - > post_datalen ) ;
/* now add in custom headers */
if ( s - > headers )
@ -437,8 +451,12 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
av_freep ( & authstr ) ;
av_freep ( & proxyauthstr ) ;
if ( ffurl_write ( s - > hd , s - > buffer , strlen ( s - > buffer ) ) < 0 )
return AVERROR ( EIO ) ;
if ( ( err = ffurl_write ( s - > hd , s - > buffer , strlen ( s - > buffer ) ) ) < 0 )
return err ;
if ( s - > post_data )
if ( ( err = ffurl_write ( s - > hd , s - > post_data , s - > post_datalen ) ) < 0 )
return err ;
/* init input buffer */
s - > buf_ptr = s - > buffer ;
@ -449,7 +467,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
s - > willclose = 0 ;
s - > end_chunked_post = 0 ;
s - > end_header = 0 ;
if ( post ) {
if ( post & & ! s - > post_data ) {
/* Pretend that it did work. We didn't read any header yet, since
* we ' ve still to send the POST data , but the code calling this
* function will check http_code after we return . */
@ -512,8 +530,8 @@ static int http_read(URLContext *h, uint8_t *buf, int size)
for ( ; ; ) {
do {
if ( http_get_line ( s , line , sizeof ( line ) ) < 0 )
return AVERROR ( EIO ) ;
if ( ( err = http_get_line ( s , line , sizeof ( line ) ) ) < 0 )
return err ;
} while ( ! * line ) ; /* skip CR LF from last chunk */
s - > chunksize = strtoll ( line , NULL , 16 ) ;