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 */
+
+ /* custom headers */
+ size_t i_http_headers;
+ httpd_header * p_http_headers;
};
static int httpd_StreamCallBack( httpd_callback_sys_t *p_sys,
answer->i_status = 200;
+ bool b_has_content_type = false;
+ bool b_has_cache_control = false;
+
+ vlc_mutex_lock( &stream->lock );
+ for( size_t i = 0; i < stream->i_http_headers; i++ )
+ {
+ if( strncasecmp( stream->p_http_headers[i].name, "Content-Length", 14 ) )
+ {
+ httpd_MsgAdd( answer, stream->p_http_headers[i].name,
+ stream->p_http_headers[i].value );
+
+ if( !strncasecmp( stream->p_http_headers[i].name, "Content-Type", 12 ) )
+ b_has_content_type = true;
+ else if( !strncasecmp( stream->p_http_headers[i].name, "Cache-Control", 13 ) )
+ b_has_cache_control = true;
+ }
+ }
+ vlc_mutex_unlock( &stream->lock );
+
if( query->i_type != HTTPD_MSG_HEAD )
{
cl->b_stream_mode = true;
}
else
{
- httpd_MsgAdd( answer, "Content-Length", "%d", 0 );
+ httpd_MsgAdd( answer, "Content-Length", "0" );
answer->i_body_offset = 0;
}
+ /* FIXME: move to http access_output */
if( !strcmp( stream->psz_mime, "video/x-ms-asf-stream" ) )
{
bool b_xplaystream = false;
int i;
- httpd_MsgAdd( answer, "Content-type", "%s",
- "application/octet-stream" );
+ httpd_MsgAdd( answer, "Content-type", "application/octet-stream" );
httpd_MsgAdd( answer, "Server", "Cougar 4.1.0.3921" );
httpd_MsgAdd( answer, "Pragma", "no-cache" );
httpd_MsgAdd( answer, "Pragma", "client-id=%lu",
httpd_MsgAdd( answer, "Pragma", "features=\"broadcast\"" );
/* Check if there is a xPlayStrm=1 */
- for( i = 0; i < query->i_name; i++ )
+ for( i = 0; i < query->i_headers; i++ )
{
- if( !strcasecmp( query->name[i], "Pragma" ) &&
- strstr( query->value[i], "xPlayStrm=1" ) )
+ if( !strcasecmp( query->p_headers[i].name, "Pragma" ) &&
+ strstr( query->p_headers[i].value, "xPlayStrm=1" ) )
{
b_xplaystream = true;
}
answer->i_body_offset = 0;
}
}
- else
+ else if( !b_has_content_type )
{
- httpd_MsgAdd( answer, "Content-type", "%s", stream->psz_mime );
+ httpd_MsgAdd( answer, "Content-type", stream->psz_mime );
}
- httpd_MsgAdd( answer, "Cache-Control", "%s", "no-cache" );
+ if( !b_has_cache_control )
+ httpd_MsgAdd( answer, "Cache-Control", "no-cache" );
return VLC_SUCCESS;
}
}
stream->i_buffer_last_pos = 1;
stream->b_has_keyframes = false;
stream->i_last_keyframe_seen_pos = 0;
+ stream->i_http_headers = 0;
+ stream->p_http_headers = NULL;
httpd_UrlCatch( stream->url, HTTPD_MSG_HEAD, httpd_StreamCallBack,
(httpd_callback_sys_t*)stream );
void httpd_StreamDelete( httpd_stream_t *stream )
{
httpd_UrlDelete( stream->url );
+ for( size_t i = 0; i < stream->i_http_headers; i++ )
+ {
+ free( stream->p_http_headers[i].name );
+ free( stream->p_http_headers[i].value );
+ }
+ free( stream->p_http_headers );
vlc_mutex_destroy( &stream->lock );
free( stream->psz_mime );
free( stream->p_header );
msg->psz_url = NULL;
msg->psz_args = NULL;
- msg->i_name = 0;
- msg->name = NULL;
- msg->i_value = 0;
- msg->value = NULL;
+ msg->i_headers = 0;
+ msg->p_headers = NULL;
msg->i_body_offset = 0;
msg->i_body = 0;
{
free( msg->psz_url );
free( msg->psz_args );
- for (int i = 0; i < msg->i_name; i++) {
- free( msg->name[i] );
- free( msg->value[i] );
+ for( size_t i = 0; i < msg->i_headers; i++ )
+ {
+ free( msg->p_headers[i].name );
+ free( msg->p_headers[i].value );
}
- free( msg->name );
- free( msg->value );
+ free( msg->p_headers );
free( msg->p_body );
httpd_MsgInit( msg );
}
const char *httpd_MsgGet( const httpd_message_t *msg, const char *name )
{
- for (int i = 0; i < msg->i_name; i++ )
- if( !strcasecmp( msg->name[i], name ))
- return msg->value[i];
-
+ for( size_t i = 0; i < msg->i_headers; i++ )
+ {
+ if( !strcasecmp( msg->p_headers[i].name, name ))
+ {
+ return msg->p_headers[i].value;
+ }
+ }
return NULL;
}
free( value );
return;
}
-
- TAB_APPEND( msg->i_name, msg->name, (char*)name );
- TAB_APPEND( msg->i_value, msg->value, value );
+ httpd_header * p_tmp = realloc( msg->p_headers, sizeof(httpd_header) * (msg->i_headers + 1));
+ if(p_tmp)
+ {
+ msg->p_headers = p_tmp;
+ msg->p_headers[msg->i_headers].name = name;
+ msg->p_headers[msg->i_headers].value = value;
+ msg->i_headers++;
+ }
+ else
+ {
+ free(name);
+ free(value);
+ }
}
static void httpd_ClientInit( httpd_client_t *cl, mtime_t now )
if( ( colon = strchr( line, ':' ) ) )
{
- char *name;
- char *value;
-
*colon++ = '\0';
while( *colon == ' ' )
{
colon++;
}
- name = strdup( line );
- value = strdup( colon );
-
- TAB_APPEND( cl->query.i_name, cl->query.name, name );
- TAB_APPEND( cl->query.i_value,cl->query.value,value);
+ httpd_MsgAdd( &cl->query, line, colon );
- if( !strcasecmp( name, "Content-Length" ) )
+ if( !strcasecmp( line, "Content-Length" ) )
{
- cl->query.i_body = atol( value );
+ cl->query.i_body = atol( colon );
}
}
const char *psz_status = httpd_ReasonFromCode( cl->answer.i_status );
i_size = strlen( "HTTP/1.") + 10 + 10 + strlen( psz_status ) + 5;
- for( i = 0; i < cl->answer.i_name; i++ )
+ for( i = 0; i < cl->answer.i_headers; i++ )
{
- i_size += strlen( cl->answer.name[i] ) + 2 +
- strlen( cl->answer.value[i] ) + 2;
+ i_size += strlen( cl->answer.p_headers[i].name ) + 2 +
+ strlen( cl->answer.p_headers[i].value ) + 2;
}
if( cl->i_buffer_size < i_size )
cl->answer.i_proto == HTTPD_PROTO_HTTP ? "HTTP/1" : "RTSP/1",
cl->answer.i_version,
cl->answer.i_status, psz_status );
- for( i = 0; i < cl->answer.i_name; i++ )
+ for( i = 0; i < cl->answer.i_headers; i++ )
{
- p += sprintf( p, "%s: %s\r\n", cl->answer.name[i],
- cl->answer.value[i] );
+ p += sprintf( p, "%s: %s\r\n", cl->answer.p_headers[i].name,
+ cl->answer.p_headers[i].value );
}
p += sprintf( p, "\r\n" );
vlc_mutex_unlock( &host->lock );
return NULL;
}
+
+int httpd_StreamSetHTTPHeaders(httpd_stream_t * p_stream, httpd_header * p_headers, size_t i_headers )
+{
+ if( !p_stream )
+ return VLC_EGENERIC;
+
+ vlc_mutex_lock( &p_stream->lock );
+ if( p_stream->p_http_headers )
+ {
+ for( size_t i = 0; i < p_stream->i_http_headers; i++)
+ {
+ free( p_stream->p_http_headers[i].name );
+ free( p_stream->p_http_headers[i].value );
+ }
+ free( p_stream->p_http_headers );
+ p_stream->p_http_headers = NULL;
+ p_stream->i_http_headers = 0;
+ }
+
+ if( !p_headers || !i_headers )
+ {
+ vlc_mutex_unlock( &p_stream->lock );
+ return VLC_SUCCESS;
+ }
+
+ p_stream->p_http_headers = malloc(sizeof(httpd_header) * i_headers );
+ if( !p_stream->p_http_headers )
+ {
+ vlc_mutex_unlock( &p_stream->lock );
+ return VLC_ENOMEM;
+ }
+
+ size_t j = 0;
+ for( size_t i = 0; i < i_headers; i++ )
+ {
+ if( unlikely( !p_headers[i].name || !p_headers[i].value ) )
+ continue;
+
+ p_stream->p_http_headers[j].name = strdup( p_headers[i].name );
+ p_stream->p_http_headers[j].value = strdup( p_headers[i].value );
+
+ if( unlikely( !p_stream->p_http_headers[j].name ||
+ !p_stream->p_http_headers[j].value ) )
+ {
+ free( p_stream->p_http_headers[j].name );
+ free( p_stream->p_http_headers[j].value );
+ break;
+ }
+ j++;
+ }
+ p_stream->i_http_headers = j;
+ vlc_mutex_unlock( &p_stream->lock );
+ return VLC_SUCCESS;
+}