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

📄 http.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  * HTTP Helper * by Bertrand Baudet <bertrand_baudet@yahoo.com> * (C) 2001, MPlayer team. */#include "config.h"#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#ifndef HAVE_WINSOCK2#define closesocket close#else#include <winsock2.h>#include <ws2tcpip.h>#endif#include "http.h"#include "url.h"#include "mp_msg.h"#include "stream.h"#include "libmpdemux/demuxer.h"#include "network.h"#include "help_mp.h"#undef memcpy#define memcpy uc_memcpyextern mime_struct_t mime_type_table[];extern int stream_cache_size;extern int network_bandwidth;extern int http_seek(stream_t *stream, off_t pos);typedef struct {  unsigned metaint;  unsigned metapos;  int is_ultravox;} scast_data_t;/** * \brief first read any data from sc->buffer then from fd * \param fd file descriptor to read data from * \param buffer buffer to read into * \param len how many bytes to read * \param sc streaming control containing buffer to read from first * \return len unless there is a read error or eof */static unsigned my_read(int fd, char *buffer, int len, streaming_ctrl_t *sc) {  unsigned pos = 0;  unsigned cp_len = sc->buffer_size - sc->buffer_pos;  if (cp_len > len)    cp_len = len;  memcpy(buffer, &sc->buffer[sc->buffer_pos], cp_len);  sc->buffer_pos += cp_len;  pos += cp_len;  while (pos < len) {    int ret = recv(fd, &buffer[pos], len - pos, 0);    if (ret <= 0)      break;    pos += ret;  }  return pos;}/** * \brief read and process (i.e. discard *g*) a block of ultravox metadata * \param fd file descriptor to read from * \param sc streaming_ctrl_t whose buffer is consumed before reading from fd * \return number of real data before next metadata block starts or 0 on error */static unsigned uvox_meta_read(int fd, streaming_ctrl_t *sc) {  unsigned metaint;  unsigned char info[6] = {0, 0, 0, 0, 0, 0};  int info_read;  do {    info_read = my_read(fd, info, 1, sc);    if (info[0] == 0x00)      info_read = my_read(fd, info, 6, sc);    else      info_read += my_read(fd, &info[1], 5, sc);    if (info_read != 6) // read error or eof      return 0;    // sync byte and reserved flags    if (info[0] != 0x5a || (info[1] & 0xfc) != 0x00) {      mp_msg(MSGT_DEMUXER, MSGL_ERR, "Invalid or unknown uvox metadata\n");      return 0;    }    if (info[1] & 0x01)      mp_msg(MSGT_DEMUXER, MSGL_WARN, "Encrypted ultravox data\n");    metaint = info[4] << 8 | info[5];    if ((info[3] & 0xf) < 0x07) { // discard any metadata nonsense      char *metabuf = malloc(metaint);      my_read(fd, metabuf, metaint, sc);      free(metabuf);    }  } while ((info[3] & 0xf) < 0x07);  return metaint;}/** * \brief read one scast meta data entry and print it * \param fd file descriptor to read from * \param sc streaming_ctrl_t whose buffer is consumed before reading from fd */static void scast_meta_read(int fd, streaming_ctrl_t *sc) {  unsigned char tmp = 0;  unsigned metalen;  my_read(fd, &tmp, 1, sc);  metalen = tmp * 16;  if (metalen > 0) {    char *info = malloc(metalen + 1);    unsigned nlen = my_read(fd, info, metalen, sc);    info[nlen] = 0;    mp_msg(MSGT_DEMUXER, MSGL_INFO, "\nICY Info: %s\n", info);    free(info);  }}/** * \brief read data from scast/ultravox stream without any metadata * \param fd file descriptor to read from * \param buffer buffer to read data into * \param size number of bytes to read * \param sc streaming_ctrl_t whose buffer is consumed before reading from fd */static int scast_streaming_read(int fd, char *buffer, int size,                                streaming_ctrl_t *sc) {  scast_data_t *sd = (scast_data_t *)sc->data;  unsigned block, ret;  unsigned done = 0;  // first read remaining data up to next metadata  block = sd->metaint - sd->metapos;  if (block > size)    block = size;  ret = my_read(fd, buffer, block, sc);  sd->metapos += ret;  done += ret;  if (ret != block) // read problems or eof    size = done;  while (done < size) { // now comes the metadata    if (sd->is_ultravox)    {      sd->metaint = uvox_meta_read(fd, sc);      if (!sd->metaint)        size = done;    }    else      scast_meta_read(fd, sc); // read and display metadata    sd->metapos = 0;    block = size - done;    if (block > sd->metaint)      block = sd->metaint;    ret = my_read(fd, &buffer[done], block, sc);    sd->metapos += ret;    done += ret;    if (ret != block) // read problems or eof      size = done;  }  return done;}static int scast_streaming_start(stream_t *stream) {  int metaint;  scast_data_t *scast_data;  HTTP_header_t *http_hdr = stream->streaming_ctrl->data;  int is_ultravox = strcasecmp(stream->streaming_ctrl->url->protocol, "unsv") == 0;  if (!stream || stream->fd < 0 || !http_hdr)    return -1;  if (is_ultravox)    metaint = 0;  else {    metaint = atoi(http_get_field(http_hdr, "Icy-MetaInt"));    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->prebuffer_size = 64 * 1024; // 64 KBytes  stream->streaming_ctrl->buffering = 1;  stream->streaming_ctrl->status = streaming_playing_e;  return 0;}static int nop_streaming_start( stream_t *stream ) {	HTTP_header_t *http_hdr = NULL;	char *next_url=NULL;	URL_t *rd_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				ret=-1;				next_url = http_get_field( http_hdr, "Location" );				if (next_url != NULL)					rd_url=url_new(next_url);				if (next_url != NULL && rd_url != NULL) {					mp_msg(MSGT_NETWORK,MSGL_STATUS,"Redirected: Using this url instead %s\n",next_url);							stream->streaming_ctrl->url=check4proxies(rd_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->prebuffer_size = 64*1024; // 64 KBytes	stream->streaming_ctrl->buffering = 1;	stream->streaming_ctrl->status = streaming_playing_e;	return 0;}HTTP_header_t *http_new_header(void) {	HTTP_header_t *http_hdr;	http_hdr = 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;	if( (unsigned)length > SIZE_MAX - http_hdr->buffer_size - 1) {		mp_msg(MSGT_NETWORK,MSGL_FATAL,"Bad size in memory (re)allocation\n");		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;	size_t 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 = 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 = 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 = 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 = 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;

⌨️ 快捷键说明

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