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

📄 http.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
字号:
/*  * HTTP Helper * by Bertrand Baudet <bertrand_baudet@yahoo.com> * (C) 2001, MPlayer team. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "http.h"#include "url.h"#include "mp_msg.h"HTTP_header_t *http_new_header() {	HTTP_header_t *http_hdr;	http_hdr = (HTTP_header_t*)malloc(sizeof(HTTP_header_t));	if( http_hdr==NULL ) return NULL;	memset( http_hdr, 0, sizeof(HTTP_header_t) );	return http_hdr;}voidhttp_free( HTTP_header_t *http_hdr ) {	HTTP_field_t *field, *field2free;	if( http_hdr==NULL ) return;	if( http_hdr->protocol!=NULL ) free( http_hdr->protocol );	if( http_hdr->uri!=NULL ) free( http_hdr->uri );	if( http_hdr->reason_phrase!=NULL ) free( http_hdr->reason_phrase );	if( http_hdr->field_search!=NULL ) free( http_hdr->field_search );	if( http_hdr->method!=NULL ) free( http_hdr->method );	if( http_hdr->buffer!=NULL ) free( http_hdr->buffer );	field = http_hdr->first_field;	while( field!=NULL ) {		field2free = field;		if (field->field_name)		  free(field->field_name);		field = field->next;		free( field2free );	}	free( http_hdr );	http_hdr = NULL;}inthttp_response_append( HTTP_header_t *http_hdr, char *response, int length ) {	if( http_hdr==NULL || response==NULL || length<0 ) return -1;	http_hdr->buffer = (char*)realloc( http_hdr->buffer, http_hdr->buffer_size+length+1 );	if( http_hdr->buffer==NULL ) {		mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory (re)allocation failed\n");		return -1;	}	memcpy( http_hdr->buffer+http_hdr->buffer_size, response, length );	http_hdr->buffer_size += length;	http_hdr->buffer[http_hdr->buffer_size]=0; // close the string!	return http_hdr->buffer_size;}inthttp_is_header_entire( HTTP_header_t *http_hdr ) {	if( http_hdr==NULL ) return -1;	if( http_hdr->buffer==NULL ) return 0; // empty		if( strstr(http_hdr->buffer, "\r\n\r\n")==NULL &&	    strstr(http_hdr->buffer, "\n\n")==NULL ) return 0;	return 1;}inthttp_response_parse( HTTP_header_t *http_hdr ) {	char *hdr_ptr, *ptr;	char *field=NULL;	int pos_hdr_sep, hdr_sep_len, len;	if( http_hdr==NULL ) return -1;	if( http_hdr->is_parsed ) return 0;	// Get the protocol	hdr_ptr = strstr( http_hdr->buffer, " " );	if( hdr_ptr==NULL ) {		mp_msg(MSGT_NETWORK,MSGL_ERR,"Malformed answer. No space separator found.\n");		return -1;	}	len = hdr_ptr-http_hdr->buffer;	http_hdr->protocol = (char*)malloc(len+1);	if( http_hdr->protocol==NULL ) {		mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");		return -1;	}	strncpy( http_hdr->protocol, http_hdr->buffer, len );	http_hdr->protocol[len]='\0';	if( !strncasecmp( http_hdr->protocol, "HTTP", 4) ) {		if( sscanf( http_hdr->protocol+5,"1.%d", &(http_hdr->http_minor_version) )!=1 ) {			mp_msg(MSGT_NETWORK,MSGL_ERR,"Malformed answer. Unable to get HTTP minor version.\n");			return -1;		}	}	// Get the status code	if( sscanf( ++hdr_ptr, "%d", &(http_hdr->status_code) )!=1 ) {		mp_msg(MSGT_NETWORK,MSGL_ERR,"Malformed answer. Unable to get status code.\n");		return -1;	}	hdr_ptr += 4;	// Get the reason phrase	ptr = strstr( hdr_ptr, "\n" );	if( hdr_ptr==NULL ) {		mp_msg(MSGT_NETWORK,MSGL_ERR,"Malformed answer. Unable to get the reason phrase.\n");		return -1;	}	len = ptr-hdr_ptr;	http_hdr->reason_phrase = (char*)malloc(len+1);	if( http_hdr->reason_phrase==NULL ) {		mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");		return -1;	}	strncpy( http_hdr->reason_phrase, hdr_ptr, len );	if( http_hdr->reason_phrase[len-1]=='\r' ) {		len--;	}	http_hdr->reason_phrase[len]='\0';	// Set the position of the header separator: \r\n\r\n	hdr_sep_len = 4;	ptr = strstr( http_hdr->buffer, "\r\n\r\n" );	if( ptr==NULL ) {		ptr = strstr( http_hdr->buffer, "\n\n" );		if( ptr==NULL ) {			mp_msg(MSGT_NETWORK,MSGL_ERR,"Header may be incomplete. No CRLF CRLF found.\n");			return -1;		}		hdr_sep_len = 2;	}	pos_hdr_sep = ptr-http_hdr->buffer;	// Point to the first line after the method line.	hdr_ptr = strstr( http_hdr->buffer, "\n" )+1;	do {		ptr = hdr_ptr;		while( *ptr!='\r' && *ptr!='\n' ) ptr++;		len = ptr-hdr_ptr;		if( len==0 ) break;		field = (char*)realloc(field, len+1);		if( field==NULL ) {			mp_msg(MSGT_NETWORK,MSGL_ERR,"Memory allocation failed\n");			return -1;		}		strncpy( field, hdr_ptr, len );		field[len]='\0';		http_set_field( http_hdr, field );		hdr_ptr = ptr+((*ptr=='\r')?2:1);	} while( hdr_ptr<(http_hdr->buffer+pos_hdr_sep) );		if( field!=NULL ) free( field );	if( pos_hdr_sep+hdr_sep_len<http_hdr->buffer_size ) {		// Response has data!		http_hdr->body = http_hdr->buffer+pos_hdr_sep+hdr_sep_len;		http_hdr->body_size = http_hdr->buffer_size-(pos_hdr_sep+hdr_sep_len);	}	http_hdr->is_parsed = 1;	return 0;}char *http_build_request( HTTP_header_t *http_hdr ) {	char *ptr, *uri=NULL;	int len;	HTTP_field_t *field;	if( http_hdr==NULL ) return NULL;	if( http_hdr->method==NULL ) http_set_method( http_hdr, "GET");	if( http_hdr->uri==NULL ) http_set_uri( http_hdr, "/");	else {		uri = (char*)malloc(strlen(http_hdr->uri) + 1);		if( uri==NULL ) {			mp_msg(MSGT_NETWORK,MSGL_ERR,"Memory allocation failed\n");			return NULL;		}		strcpy(uri,http_hdr->uri);	}	//**** Compute the request length	// Add the Method line	len = strlen(http_hdr->method)+strlen(uri)+12;	// Add the fields	field = http_hdr->first_field; 	while( field!=NULL ) {		len += strlen(field->field_name)+2;		field = field->next;	}	// Add the CRLF	len += 2;	// Add the body	if( http_hdr->body!=NULL ) {		len += http_hdr->body_size;	}	// Free the buffer if it was previously used	if( http_hdr->buffer!=NULL ) {		free( http_hdr->buffer );		http_hdr->buffer = NULL;	}	http_hdr->buffer = (char*)malloc(len+1);	if( http_hdr->buffer==NULL ) {		mp_msg(MSGT_NETWORK,MSGL_ERR,"Memory allocation failed\n");		return NULL;	}	http_hdr->buffer_size = len;	//*** Building the request	ptr = http_hdr->buffer;	// Add the method line	ptr += sprintf( ptr, "%s %s HTTP/1.%d\r\n", http_hdr->method, uri, http_hdr->http_minor_version );	field = http_hdr->first_field;	// Add the field	while( field!=NULL ) {		ptr += sprintf( ptr, "%s\r\n", field->field_name );		field = field->next;	}	ptr += sprintf( ptr, "\r\n" );	// Add the body	if( http_hdr->body!=NULL ) {		memcpy( ptr, http_hdr->body, http_hdr->body_size );	}	if( uri ) free( uri );	return http_hdr->buffer;	}char *http_get_field( HTTP_header_t *http_hdr, const char *field_name ) {	if( http_hdr==NULL || field_name==NULL ) return NULL;	http_hdr->field_search_pos = http_hdr->first_field;	http_hdr->field_search = (char*)realloc( http_hdr->field_search, strlen(field_name)+1 );	if( http_hdr->field_search==NULL ) {		mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");		return NULL;	}	strcpy( http_hdr->field_search, field_name );	return http_get_next_field( http_hdr );}char *http_get_next_field( HTTP_header_t *http_hdr ) {	char *ptr;	HTTP_field_t *field;	if( http_hdr==NULL ) return NULL;	field = http_hdr->field_search_pos;	while( field!=NULL ) { 		ptr = strstr( field->field_name, ":" );		if( ptr==NULL ) return NULL;		if( !strncasecmp( field->field_name, http_hdr->field_search, ptr-(field->field_name) ) ) {			ptr++;	// Skip the column			while( ptr[0]==' ' ) ptr++; // Skip the spaces if there is some			http_hdr->field_search_pos = field->next;			return ptr;	// return the value without the field name		}		field = field->next;	}	return NULL;}voidhttp_set_field( HTTP_header_t *http_hdr, const char *field_name ) {	HTTP_field_t *new_field;	if( http_hdr==NULL || field_name==NULL ) return;	new_field = (HTTP_field_t*)malloc(sizeof(HTTP_field_t));	if( new_field==NULL ) {		mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");		return;	}	new_field->next = NULL;	new_field->field_name = (char*)malloc(strlen(field_name)+1);	if( new_field->field_name==NULL ) {		mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");		return;	}	strcpy( new_field->field_name, field_name );	if( http_hdr->last_field==NULL ) {		http_hdr->first_field = new_field;	} else {		http_hdr->last_field->next = new_field;	}	http_hdr->last_field = new_field;	http_hdr->field_nb++;}voidhttp_set_method( HTTP_header_t *http_hdr, const char *method ) {	if( http_hdr==NULL || method==NULL ) return;	http_hdr->method = (char*)malloc(strlen(method)+1);	if( http_hdr->method==NULL ) {		mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");		return;	}	strcpy( http_hdr->method, method );}voidhttp_set_uri( HTTP_header_t *http_hdr, const char *uri ) {	if( http_hdr==NULL || uri==NULL ) return;	http_hdr->uri = (char*)malloc(strlen(uri)+1);	if( http_hdr->uri==NULL ) {		mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");		return;	}	strcpy( http_hdr->uri, uri );}inthttp_add_basic_authentication( HTTP_header_t *http_hdr, const char *username, const char *password ) {	char *auth, *usr_pass, *b64_usr_pass;	int encoded_len, pass_len=0, out_len;	if( http_hdr==NULL || username==NULL ) return -1;	if( password!=NULL ) {		pass_len = strlen(password);	}		usr_pass = (char*)malloc(strlen(username)+pass_len+2);	if( usr_pass==NULL ) {		mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");		return -1;	}	sprintf( usr_pass, "%s:%s", username, (password==NULL)?"":password );	// Base 64 encode with at least 33% more data than the original size	encoded_len = strlen(usr_pass)*2;	b64_usr_pass = (char*)malloc(encoded_len);	if( b64_usr_pass==NULL ) {		mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");		return -1;	}	out_len = base64_encode( usr_pass, strlen(usr_pass), b64_usr_pass, encoded_len);	if( out_len<0 ) {		mp_msg(MSGT_NETWORK,MSGL_FATAL,"Base64 out overflow\n");		return -1;	}	b64_usr_pass[out_len]='\0';		auth = (char*)malloc(encoded_len+22);	if( auth==NULL ) {		mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory allocation failed\n");		return -1;	}		sprintf( auth, "Authorization: Basic %s", b64_usr_pass);	http_set_field( http_hdr, auth );		free( usr_pass );	free( b64_usr_pass );	free( auth );		return 0;}voidhttp_debug_hdr( HTTP_header_t *http_hdr ) {	HTTP_field_t *field;	int i = 0;	if( http_hdr==NULL ) return;	mp_msg(MSGT_NETWORK,MSGL_V,"--- HTTP DEBUG HEADER --- START ---\n");	mp_msg(MSGT_NETWORK,MSGL_V,"protocol:           [%s]\n", http_hdr->protocol );	mp_msg(MSGT_NETWORK,MSGL_V,"http minor version: [%d]\n", http_hdr->http_minor_version );	mp_msg(MSGT_NETWORK,MSGL_V,"uri:                [%s]\n", http_hdr->uri );	mp_msg(MSGT_NETWORK,MSGL_V,"method:             [%s]\n", http_hdr->method );	mp_msg(MSGT_NETWORK,MSGL_V,"status code:        [%d]\n", http_hdr->status_code );	mp_msg(MSGT_NETWORK,MSGL_V,"reason phrase:      [%s]\n", http_hdr->reason_phrase );	mp_msg(MSGT_NETWORK,MSGL_V,"body size:          [%d]\n", http_hdr->body_size );	mp_msg(MSGT_NETWORK,MSGL_V,"Fields:\n");	field = http_hdr->first_field;	while( field!=NULL ) {		mp_msg(MSGT_NETWORK,MSGL_V," %d - %s\n", i++, field->field_name );		field = field->next;	}	mp_msg(MSGT_NETWORK,MSGL_V,"--- HTTP DEBUG HEADER --- END ---\n");}int base64_encode(const void *enc, int encLen, char *out, int outMax) {	static const char	b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";	unsigned char		*encBuf;	int			outLen;	unsigned int		bits;	unsigned int		shift;	encBuf = (unsigned char*)enc;	outLen = 0;	bits = 0;	shift = 0;	while( outLen<outMax ) {		if( encLen>0 ) {			// Shift in byte			bits <<= 8;			bits |= *encBuf;			shift += 8;			// Next byte			encBuf++;			encLen--;		} else if( shift>0 ) {			// Pad last bits to 6 bits - will end next loop			bits <<= 6 - shift;			shift = 6;		} else {			// Terminate with Mime style '='			*out = '=';			outLen++;			return outLen;		}		// Encode 6 bit segments		while( shift>=6 ) {			shift -= 6;			*out = b64[ (bits >> shift) & 0x3F ];			out++;			outLen++;		}	}	// Output overflow	return -1;}

⌨️ 快捷键说明

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