Example #1
0
static int asf_http_parse_response(asf_http_streaming_ctrl_t *asf_http_ctrl, HTTP_header_t *http_hdr ) {
	char *content_type, *pragma;
	char features[64] = "\0";
	size_t len;
	if( http_response_parse(http_hdr)<0 ) {
		mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_ASF_Failed2ParseHTTPResponse);
		return -1;
	}
	switch( http_hdr->status_code ) {
		case 200:
			break;
		case 401: // Authentication required
			return ASF_Authenticate_e;
		default:
			mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_ASF_ServerReturn, http_hdr->status_code, http_hdr->reason_phrase);
			return -1;
	}

	content_type = http_get_field( http_hdr, "Content-Type");
//printf("Content-Type: [%s]\n", content_type);

	pragma = http_get_field( http_hdr, "Pragma");
	while( pragma!=NULL ) {
		char *comma_ptr=NULL;
		char *end;
//printf("Pragma: [%s]\n", pragma );
		// The pragma line can get severals attributes
		// separeted with a comma ','.
		do {
			if( !strncasecmp( pragma, "features=", 9) ) {
				pragma += 9;
				end = strstr( pragma, "," );
				if( end==NULL ) {
				  len = strlen(pragma);
				} else {
				  len = (unsigned int)(end-pragma);
				}
				if(len > sizeof(features) - 1) {
				  mp_msg(MSGT_NETWORK,MSGL_WARN,MSGTR_MPDEMUX_ASF_ASFHTTPParseWarnCuttedPragma,pragma,len,sizeof(features) - 1);
				  len = sizeof(features) - 1;
				}
				strncpy( features, pragma, len );
				features[len]='\0';
				break;
			}
			comma_ptr = strstr( pragma, "," );
			if( comma_ptr!=NULL ) {
				pragma = comma_ptr+1;
				if( pragma[0]==' ' ) pragma++;
			}
		} while( comma_ptr!=NULL );
		pragma = http_get_next_field( http_hdr );
	}
	asf_http_ctrl->streaming_type = asf_http_streaming_type( content_type, features, http_hdr );
	return 0;
}
Example #2
0
File: http.c Project: zerix/mpv
static int fixup_open(stream_t *stream,int seekable) {
	HTTP_header_t *http_hdr = stream->streaming_ctrl->data;
	int is_icy = http_hdr && http_get_field(http_hdr, "Icy-MetaInt");
	int is_ultravox = strcasecmp(stream->streaming_ctrl->url->protocol, "unsv") == 0;

	stream->type = STREAMTYPE_STREAM;
	if(!is_icy && !is_ultravox && seekable)
	{
		stream->flags |= MP_STREAM_SEEK;
		stream->seek = http_seek;
	}
	stream->streaming_ctrl->bandwidth = network_bandwidth;
	if ((!is_icy && !is_ultravox) || scast_streaming_start(stream))
	if(nop_streaming_start( stream )) {
		mp_msg(MSGT_NETWORK,MSGL_ERR,"nop_streaming_start failed\n");
		if (stream->fd >= 0)
			closesocket(stream->fd);
		stream->fd = -1;
		streaming_ctrl_free(stream->streaming_ctrl);
		stream->streaming_ctrl = NULL;
		return STREAM_UNSUPPORTED;
	}

	return STREAM_OK;
}
Example #3
0
File: http.c Project: zerix/mpv
static void print_icy_metadata(HTTP_header_t *http_hdr) {
	const char *field_data;
	// note: I skip icy-notice1 and 2, as they contain html <BR>
	// and are IMHO useless info ::atmos
	if( (field_data = http_get_field(http_hdr, "icy-name")) != NULL )
		mp_msg(MSGT_NETWORK,MSGL_INFO,"Name   : %s\n", field_data);
	if( (field_data = http_get_field(http_hdr, "icy-genre")) != NULL )
		mp_msg(MSGT_NETWORK,MSGL_INFO,"Genre  : %s\n", field_data);
	if( (field_data = http_get_field(http_hdr, "icy-url")) != NULL )
		mp_msg(MSGT_NETWORK,MSGL_INFO,"Website: %s\n", field_data);
	// XXX: does this really mean public server? ::atmos
	if( (field_data = http_get_field(http_hdr, "icy-pub")) != NULL )
		mp_msg(MSGT_NETWORK,MSGL_INFO,"Public : %s\n", atoi(field_data)?"yes":"no");
	if( (field_data = http_get_field(http_hdr, "icy-br")) != NULL )
		mp_msg(MSGT_NETWORK,MSGL_INFO,"Bitrate: %skbit/s\n", field_data);
}
Example #4
0
File: http.c Project: zerix/mpv
static int scast_streaming_start(stream_t *stream) {
  int metaint;
  scast_data_t *scast_data;
  HTTP_header_t *http_hdr = stream->streaming_ctrl->data;
  if (!stream || stream->fd < 0 || !http_hdr)
    return -1;
  int is_ultravox = strcasecmp(stream->streaming_ctrl->url->protocol, "unsv") == 0;
  if (is_ultravox)
    metaint = 0;
  else {
    metaint = -1;
    char *h = http_get_field(http_hdr, "Icy-MetaInt");
    if (h)
        metaint = atoi(h);
    if (metaint <= 0)
      return -1;
  }
  stream->streaming_ctrl->buffer = malloc(http_hdr->body_size);
  stream->streaming_ctrl->buffer_size = http_hdr->body_size;
  stream->streaming_ctrl->buffer_pos = 0;
  memcpy(stream->streaming_ctrl->buffer, http_hdr->body, http_hdr->body_size);
  scast_data = malloc(sizeof(scast_data_t));
  scast_data->metaint = metaint;
  scast_data->metapos = 0;
  scast_data->is_ultravox = is_ultravox;
  http_free(http_hdr);
  stream->streaming_ctrl->data = scast_data;
  stream->streaming_ctrl->streaming_read = scast_streaming_read;
  stream->streaming_ctrl->streaming_seek = NULL;
  stream->streaming_ctrl->status = streaming_playing_e;
  stream->streaming = true;
  return 0;
}
Example #5
0
int
http_seek( stream_t *stream, off_t pos ) {
	HTTP_header_t *http_hdr = NULL;
	int fd;
	if( stream==NULL ) return 0;

	if( stream->fd>0 ) closesocket(stream->fd); // need to reconnect to seek in http-stream
	fd = http_send_request( stream->streaming_ctrl->url, pos );
	if( fd<0 ) return 0;

	http_hdr = http_read_response( fd );

	if( http_hdr==NULL ) return 0;

	if( mp_msg_test(MSGT_NETWORK,MSGL_V) )
		http_debug_hdr( http_hdr );

	switch( http_hdr->status_code ) {
		case 200:
		case 206: // OK
			mp_msg(MSGT_NETWORK,MSGL_V,"Content-Type: [%s]\n", http_get_field(http_hdr, "Content-Type") );
			mp_msg(MSGT_NETWORK,MSGL_V,"Content-Length: [%s]\n", http_get_field(http_hdr, "Content-Length") );
			if( http_hdr->body_size>0 ) {
				if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) {
					http_free( http_hdr );
					return -1;
				}
			}
			break;
		default:
			mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_NW_ErrServerReturned, http_hdr->status_code, http_hdr->reason_phrase );
			closesocket( fd );
			fd = -1;
	}
	stream->fd = fd;

	if( http_hdr ) {
		http_free( http_hdr );
		stream->streaming_ctrl->data = NULL;
	}

	stream->pos=pos;

	return 1;
}
int  http_authenticate(HTTP_header_t *http_hdr, URL_t *url, int *auth_retry) {
	char *aut;

	if (*auth_retry == 1) {
		mp_msg(MSGT_NETWORK, MSGL_ERR, MSGTR_MPDEMUX_NW_AuthFailed);
		return -1;
	}

	if (*auth_retry > 0) {
		free(url->username);
		url->username = NULL;
		free(url->password);
		url->password = NULL;
	}

	aut = http_get_field(http_hdr, "WWW-Authenticate");

	if (aut != NULL) {
		char *aut_space;
		aut_space = strstr(aut, "realm=");

		if (aut_space != NULL) aut_space += 6;

		mp_msg(MSGT_NETWORK, MSGL_INFO, MSGTR_MPDEMUX_NW_AuthRequiredFor, aut_space);

	} else {
		mp_msg(MSGT_NETWORK, MSGL_INFO, MSGTR_MPDEMUX_NW_AuthRequired);
	}

	if (network_username) {
		url->username = strdup(network_username);

		if (url->username == NULL) {
			mp_msg(MSGT_NETWORK, MSGL_FATAL, MSGTR_MemAllocFailed);
			return -1;
		}

	} else {
		mp_msg(MSGT_NETWORK, MSGL_ERR, MSGTR_MPDEMUX_NW_AuthFailed);
		return -1;
	}

	if (network_password) {
		url->password = strdup(network_password);

		if (url->password == NULL) {
			mp_msg(MSGT_NETWORK, MSGL_FATAL, MSGTR_MemAllocFailed);
			return -1;
		}

	} else {
		mp_msg(MSGT_NETWORK, MSGL_INFO, MSGTR_MPDEMUX_NW_NoPasswdProvidedTryingBlank);
	}

	(*auth_retry)++;
	return 0;
}
Example #7
0
/*! \brief Process an incoming message */
static void hc_process(HttpConnection* connection) {
    const char* tmp;
    const char* data;
    int content_size, header_size;
	HttpRequest hr;
    HttpServer* server = connection->server;

    /* get the content lenght */
    tmp = http_get_field(connection->header, "Content-Length");
    if(tmp == NULL) {
        content_size = 0;
    } else {
        content_size = atoi(tmp);
    }

    /* find the beginning of the content */
    data = strstr(connection->buffer, HTTP_LINE_SEP HTTP_LINE_SEP) + 4;

    header_size = data - connection->buffer;


    /* check if the message is bigger than current buffer size */
    if(content_size + header_size >= MAX_BUFFER_SIZE) {
        log(WARNING, "Message is too big");
        hc_report_error(connection, "Message is too big");
        return;
    }

    /* check if everything is here */
    if(connection->buffer_size >= header_size + content_size) {

        log(INFO, "Processing request Content-Length=%d", content_size);

        /* inform the request */
		hr.connection = connection;
		hr.header = connection->header;
		hr.data = data;
		hr.data_size = content_size;
		server->callback(server->user_data, &hr);

        /* free the header, we don't need it anymore */
		http_delete(connection->header);
		connection->header = NULL;

        /* move the buffer */
        if(connection->buffer_size > header_size + content_size) {
            memmove(connection->buffer, connection->buffer + header_size +
                    content_size, connection->buffer_size - header_size -
                    content_size);
            connection->buffer_size -= header_size + content_size;
        } else {
            connection->buffer_size = 0;
        }
    }
}
Example #8
0
int
http_authenticate(HTTP_header_t *http_hdr, URL_t *url, int *auth_retry) {
    char *aut;

#define MPDEMUX_NW_AuthFailed _(\
"Authentication failed. Please use the -user and -passwd options to provide your\n"\
"username/password for a list of URLs, or form an URL like:\n"\
"http://*****:*****@hostname/file\n")


    if( *auth_retry==1 ) {
        mp_tmsg(MSGT_NETWORK,MSGL_ERR,MPDEMUX_NW_AuthFailed);
        return -1;
    }
    if( *auth_retry>0 ) {
        free(url->username);
        url->username = NULL;
        free(url->password);
        url->password = NULL;
    }

    aut = http_get_field(http_hdr, "WWW-Authenticate");
    if( aut!=NULL ) {
        char *aut_space;
        aut_space = strstr(aut, "realm=");
        if( aut_space!=NULL ) aut_space += 6;
        mp_tmsg(MSGT_NETWORK,MSGL_INFO,"Authentication required for %s\n", aut_space);
    } else {
        mp_tmsg(MSGT_NETWORK,MSGL_INFO,"Authentication required.\n");
    }
    if( network_username ) {
        url->username = strdup(network_username);
        if( url->username==NULL ) {
            mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
            return -1;
        }
    } else {
        mp_tmsg(MSGT_NETWORK,MSGL_ERR,MPDEMUX_NW_AuthFailed);
        return -1;
    }
    if( network_password ) {
        url->password = strdup(network_password);
        if( url->password==NULL ) {
            mp_tmsg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed.\n");
            return -1;
        }
    } else {
        mp_tmsg(MSGT_NETWORK,MSGL_INFO,"No password provided, trying blank password.\n");
    }
    (*auth_retry)++;
    return 0;
}
int  http_seek(stream_t *stream, off_t pos) 
{

	HTTP_header_t * http_hdr = NULL;
	int fd = -1;

	if (stream == NULL)
	{
		OS_PRINTF("[%s][ERROR] stream == NULL!!!!\n",__func__);
		return 0;
	}
	
	//This if removed for network play issue fix, Gavin 2013-09-09
	//if (stream->fd > 0) closesocket(stream->fd); // need to reconnect to seek in http-stream
	//yliu add :for  fd = 0
#ifdef __LINUX__
	if (stream->fd > 0) 
	{
		closesocket(stream->fd); // need to reconnect to seek in http-stream
	}
#else
	if (stream->fd >= 0) 
	{
		closesocket(stream->fd);
		stream->fd = -1;
	}
#endif
      
	 if(is_file_seq_exit())
	 {
       
	     return -1;
	 }

	fd = http_send_request(stream->streaming_ctrl->url, pos);

	if (fd < 0) 
	{
		OS_PRINTF("[%s][ERROR] fail to send request  fd[%d]!!!!!!!!\n",__func__,fd);
		return 0;
	}

	http_hdr = http_read_response(fd);
       
	if (http_hdr == NULL) 
	{
	//yliu add:
	 closesocket(fd);
       fd = -1;
		OS_PRINTF("[%s][ERROR] fail to read response !!!!!!!!\n",__func__);
		return 0;
	}
      
      stream->streaming_ctrl->chunksize = http_hdr->chunksize;
	if (mp_msg_test(MSGT_NETWORK, MSGL_V))
	{
		http_debug_hdr(http_hdr);
	}

	switch (http_hdr->status_code) {
		case 200:
		case 206: // OK
			//mp_msg(MSGT_NETWORK, MSGL_V, "Content-Type: [%s]\n", http_get_field(http_hdr, "Content-Type"));
			//mp_msg(MSGT_NETWORK, MSGL_V, "Content-Length: [%s]\n", http_get_field(http_hdr, "Content-Length"));
			OS_PRINTF("[%s] Content-Type: [%s]\n",__func__,http_get_field(http_hdr, "Content-Type"));
			OS_PRINTF("[%s] Content-Length: [%s]\n",__func__,http_get_field(http_hdr, "Content-Length"));
                   //  yliu add :for reconnect
                   //if(pos == 0)
                    {
              	if(http_get_field(http_hdr, "Content-Length"))
			   stream->end_pos = atoll(http_get_field(http_hdr, "Content-Length"))+pos;
                   else
                      stream->end_pos = 0;
                    }
			OS_PRINTF("[%s] stream->end_pos: [%ld]\n",__func__,stream->end_pos);
			
			if (http_hdr->body_size > 0) {
				if (streaming_bufferize(stream->streaming_ctrl, http_hdr->body, http_hdr->body_size) < 0) {
					http_free(http_hdr);
                    closesocket(fd);
                    fd = -1;
					return -1;
				}
			}

			break;

			
		default:
			mp_msg(MSGT_NETWORK, MSGL_ERR, MSGTR_MPDEMUX_NW_ErrServerReturned, http_hdr->status_code, http_hdr->reason_phrase);
			closesocket(fd);
			fd = -1;
	}
	//add macro for consistency in Linux Version, yliu 2013-09-10
#if  0
	//This if added for network play issue fix, Gavin 2013-09-09
	if(stream->fd >= 0)
	{
		closesocket(stream->fd); // need to reconnect to seek in http-stream
		stream->fd = -1;
	}
#endif

	stream->fd = fd;

	if (http_hdr) {
		
		http_free(http_hdr);
		stream->streaming_ctrl->data = NULL;
		
	}

	stream->pos = pos;
	return 1;
}
Example #10
0
File: http.c Project: zerix/mpv
//! If this function succeeds you must closesocket stream->fd
static int http_streaming_start(stream_t *stream, int* file_format) {
	HTTP_header_t *http_hdr = NULL;
	int fd = stream->fd;
	int res = STREAM_UNSUPPORTED;
	int redirect = 0;
	int auth_retry=0;
	int seekable=0;
	char *content_type;
	const char *content_length;
	char *next_url;
	URL_t *url = stream->streaming_ctrl->url;

	do
	{
		redirect = 0;
		if (fd >= 0) closesocket(fd);
		fd = http_send_request( url, 0 );
		if( fd<0 ) {
			goto err_out;
		}

		http_free(http_hdr);
		http_hdr = http_read_response( fd );
		if( http_hdr==NULL ) {
			goto err_out;
		}

		if( mp_msg_test(MSGT_NETWORK,MSGL_V) ) {
			http_debug_hdr( http_hdr );
		}

		// Check if we can make partial content requests and thus seek in http-streams
		if( http_hdr!=NULL && http_hdr->status_code==200 ) {
		    const char *accept_ranges = http_get_field(http_hdr,"Accept-Ranges");
		    const char *server = http_get_field(http_hdr, "Server");
		    if (accept_ranges)
			seekable = strncmp(accept_ranges,"bytes",5)==0;
		    else if (server && (strcmp(server, "gvs 1.0") == 0 ||
		                        strncmp(server, "MakeMKV", 7) == 0)) {
			// HACK for youtube and MakeMKV incorrectly claiming not to support seeking
			mp_msg(MSGT_NETWORK, MSGL_WARN, "Broken webserver, incorrectly claims to not support Accept-Ranges\n");
			seekable = 1;
		    }
		}

		print_icy_metadata(http_hdr);

		// Check if the response is an ICY status_code reason_phrase
		if( !strcasecmp(http_hdr->protocol, "ICY") ||
		     http_get_field(http_hdr, "Icy-MetaInt") ) {
			switch( http_hdr->status_code ) {
				case 200: { // OK
					char *field_data;
					// If content-type == video/nsv we most likely have a winamp video stream
					// otherwise it should be mp3. if there are more types consider adding mime type
					// handling like later
					if ( (field_data = http_get_field(http_hdr, "content-type")) != NULL && (!strcmp(field_data, "video/nsv") || !strcmp(field_data, "misc/ultravox")))
						*file_format = DEMUXER_TYPE_NSV;
					else if ( (field_data = http_get_field(http_hdr, "content-type")) != NULL && (!strcmp(field_data, "audio/aacp") || !strcmp(field_data, "audio/aac")))
						*file_format = DEMUXER_TYPE_AAC;
					else
						*file_format = DEMUXER_TYPE_LAVF;
					res = STREAM_ERROR;
					goto out;
				}
				case 400: // Server Full
					mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server is full, skipping!\n");
					goto err_out;
				case 401: // Service Unavailable
					mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server return service unavailable, skipping!\n");
					goto err_out;
				case 403: // Service Forbidden
					mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server return 'Service Forbidden'\n");
					goto err_out;
				case 404: // Resource Not Found
					mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server couldn't find requested stream, skipping!\n");
					goto err_out;
				default:
					mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: unhandled ICY-Errorcode, contact MPlayer developers!\n");
					goto err_out;
			}
		}

		// Assume standard http if not ICY
		switch( http_hdr->status_code ) {
			case 200: // OK
				content_length = http_get_field(http_hdr, "Content-Length");
				if (content_length) {
					mp_msg(MSGT_NETWORK,MSGL_V,"Content-Length: [%s]\n", content_length);
					stream->end_pos = atoll(content_length);
				}
				// Look if we can use the Content-Type
				content_type = http_get_field( http_hdr, "Content-Type" );
				if( content_type!=NULL ) {
					unsigned int i;

					mp_msg(MSGT_NETWORK,MSGL_V,"Content-Type: [%s]\n", content_type );
					// Check in the mime type table for a demuxer type
					for (i = 0; mime_type_table[i].mime_type != NULL; i++) {
						if( !strcasecmp( content_type, mime_type_table[i].mime_type ) ) {
							*file_format = mime_type_table[i].demuxer_type;
							res = seekable;
							goto out;
						}
					}
				}
				// Not found in the mime type table, don't fail,
				// we should try raw HTTP
				res = seekable;
				goto out;
			// Redirect
			case 301: // Permanently
			case 302: // Temporarily
			case 303: // See Other
			case 307: // Temporarily (since HTTP/1.1)
				// TODO: RFC 2616, recommand to detect infinite redirection loops
				next_url = http_get_field( http_hdr, "Location" );
				if( next_url!=NULL ) {
					int is_ultravox = strcasecmp(stream->streaming_ctrl->url->protocol, "unsv") == 0;
					stream->streaming_ctrl->url = url_redirect( &url, next_url );
					if (url_is_protocol(url, "mms")) {
						res = STREAM_REDIRECTED;
						goto err_out;
					}
					if (!url_is_protocol(url, "http")) {
						mp_msg(MSGT_NETWORK,MSGL_ERR,"Unsupported http %d redirect to %s protocol\n", http_hdr->status_code, url->protocol);
						goto err_out;
					}
					if (is_ultravox)
						url_set_protocol(url, "unsv");
					redirect = 1;
				}
				break;
			case 401: // Authentication required
				if( http_authenticate(http_hdr, url, &auth_retry)<0 )
					goto err_out;
				redirect = 1;
				break;
			default:
				mp_msg(MSGT_NETWORK,MSGL_ERR,"Server returned %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase );
				goto err_out;
		}
	} while( redirect );

err_out:
	if (fd >= 0) closesocket( fd );
	fd = -1;
	http_free( http_hdr );
	http_hdr = NULL;
out:
	stream->streaming_ctrl->data = http_hdr;
	stream->fd = fd;
	return res;
}
Example #11
0
File: http.c Project: zerix/mpv
static int nop_streaming_start( stream_t *stream ) {
	HTTP_header_t *http_hdr = NULL;
	char *next_url=NULL;
	int fd,ret;
	if( stream==NULL ) return -1;

	fd = stream->fd;
	if( fd<0 ) {
		fd = http_send_request( stream->streaming_ctrl->url, 0 );
		if( fd<0 ) return -1;
		http_hdr = http_read_response( fd );
		if( http_hdr==NULL ) return -1;

		switch( http_hdr->status_code ) {
			case 200: // OK
				mp_msg(MSGT_NETWORK,MSGL_V,"Content-Type: [%s]\n", http_get_field(http_hdr, "Content-Type") );
				mp_msg(MSGT_NETWORK,MSGL_V,"Content-Length: [%s]\n", http_get_field(http_hdr, "Content-Length") );
				if( http_hdr->body_size>0 ) {
					if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) {
						http_free( http_hdr );
						return -1;
					}
				}
				break;
			// Redirect
			case 301: // Permanently
			case 302: // Temporarily
			case 303: // See Other
			case 307: // Temporarily (since HTTP/1.1)
				ret=-1;
				next_url = http_get_field( http_hdr, "Location" );

				if (next_url != NULL) {
					mp_msg(MSGT_NETWORK,MSGL_STATUS,"Redirected: Using this url instead %s\n",next_url);
							stream->streaming_ctrl->url=url_new_with_proxy(next_url);
					ret=nop_streaming_start(stream); //recursively get streaming started
				} else {
					mp_msg(MSGT_NETWORK,MSGL_ERR,"Redirection failed\n");
					closesocket( fd );
					fd = -1;
				}
				return ret;
				break;
			case 401: //Authorization required
			case 403: //Forbidden
			case 404: //Not found
			case 500: //Server Error
			default:
				mp_msg(MSGT_NETWORK,MSGL_ERR,"Server returned code %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase );
				closesocket( fd );
				fd = -1;
				return -1;
				break;
		}
		stream->fd = fd;
	} else {
		http_hdr = (HTTP_header_t*)stream->streaming_ctrl->data;
		if( http_hdr->body_size>0 ) {
			if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) {
				http_free( http_hdr );
				stream->streaming_ctrl->data = NULL;
				return -1;
			}
		}
	}

	if( http_hdr ) {
		http_free( http_hdr );
		stream->streaming_ctrl->data = NULL;
	}

	stream->streaming_ctrl->streaming_read = nop_streaming_read;
	stream->streaming_ctrl->streaming_seek = nop_streaming_seek;
	stream->streaming_ctrl->status = streaming_playing_e;
        stream->streaming = true;
	return 0;
}