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

📄 downloader.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
		u32 size;		Bool has_accept, has_connection, has_range, has_agent;		/*setup authentification*/		strcpy(pass_buf, "");		if (sess->user) {			if (!sess->passwd) {				char szUSR[50], szPASS[50];				strcpy(szUSR, sess->user);				strcpy(szPASS, "");				/*failed getting pass*/				if (!sess->dm->GetUserPassword || !sess->dm->GetUserPassword(sess->dm->usr_cbk, sess->server_name, szUSR, szPASS)) {					sess->status = GF_NETIO_STATE_ERROR;					return;				}				sess->passwd = strdup(szPASS);			}			sprintf(pass_buf, "%s:%s", sess->user, sess->passwd);			size = gf_base64_encode(pass_buf, strlen(pass_buf), range_buf, 1024);			range_buf[size] = 0;			sprintf(pass_buf, "Authorization: Basic %s", range_buf);		}		/*MIX2005 KMS project*/#if 0		if (strstr(sess->remote_path, "getKey.php?")) {			char *sLogin, *sPass;			sLogin = gf_cfg_get_key(sess->dm->cfg, "General", "KMS_User");			sPass = gf_cfg_get_key(sess->dm->cfg, "General", "KMS_Password");			if (!sLogin) sLogin = "mix";			if (!sPass) sPass = "mix";			sprintf(https_get_buffer, "%s&login=%s&password=%s", sess->remote_path, sLogin, sPass);		}#endif			user_agent = gf_cfg_get_key(sess->dm->cfg, "Downloader", "UserAgent");		if (!user_agent) user_agent = GF_DOWNLOAD_AGENT_NAME;		par.error = 0;		par.msg_type = GF_NETIO_GET_METHOD;		par.name = NULL;		gf_dm_sess_user_io(sess, &par);		if (par.name) {			if (!strcmp(par.name, "GET")) sess->http_read_type = 0;			else if (!strcmp(par.name, "HEAD")) sess->http_read_type = 1;			else sess->http_read_type = 2;		} else {			sess->http_read_type = 0;		}		sprintf(sHTTP, "%s %s HTTP/1.0\r\nHost: %s\r\n" ,			par.name ? par.name : "GET", sess->remote_path, sess->server_name);		/*signal we support title streaming*/		if (!strcmp(sess->remote_path, "/")) strcat(sHTTP, "icy-metadata:1\r\n");		/*get all headers*/		has_agent = has_accept = has_connection = has_range = 0;		while (1) {			par.msg_type = GF_NETIO_GET_HEADER;			par.name = NULL;			par.value = NULL;			gf_dm_sess_user_io(sess, &par);			if (!par.name) break;			strcat(sHTTP, par.name);			strcat(sHTTP, ": ");			strcat(sHTTP, par.value);			strcat(sHTTP, "\r\n");			if (!strcmp(par.name, "Accept")) has_accept = 1;			else if (!strcmp(par.name, "Connection")) has_connection = 1;			else if (!strcmp(par.name, "Range")) has_range = 1;			else if (!strcmp(par.name, "User-Agent")) has_agent = 1;		}		if (!has_agent) {			strcat(sHTTP, "User-Agent: ");			strcat(sHTTP, user_agent);			strcat(sHTTP, "\r\n");		}		if (!has_accept) strcat(sHTTP, "Accept: */*\r\n");		if (!has_connection) strcat(sHTTP, "Connection: Keep-Alive\r\n");		if (!has_range && sess->cache_start_size) {			sprintf(range_buf, "Range: bytes=%d-\r\n", sess->cache_start_size);			strcat(sHTTP, range_buf);		}		if (strlen(pass_buf)) {			strcat(sHTTP, pass_buf);			strcat(sHTTP, "\r\n");		}		if (sess->flags & GF_DOWNLOAD_IS_ICY) strcat(sHTTP, "Icy-Metadata: 1\r\n");				par.msg_type = GF_NETIO_GET_CONTENT;		par.data = NULL;		par.size = 0;		gf_dm_sess_user_io(sess, &par);		if (par.data && par.size) {			sprintf(range_buf, "Content-Length: %d\r\n", par.size);			strcat(sHTTP, range_buf);		}		strcat(sHTTP, "\r\n");#ifdef GPAC_HAS_SSL		if (sess->ssl) {			e = GF_IP_NETWORK_FAILURE;			if (!SSL_write(sess->ssl, sHTTP, strlen(sHTTP))) e = GF_OK;		} else #endif			e = gf_sk_send(sess->sock, sHTTP, strlen(sHTTP));		GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[HTTP] %s\n\n", sHTTP));		if (e) {			sess->status = GF_NETIO_STATE_ERROR;			sess->last_error = e;			gf_dm_sess_notify_state(sess, GF_NETIO_STATE_ERROR, e);			return;		}		if (par.size && par.data) {			u32 done = 0;			while (done<par.size) {			#ifdef GPAC_HAS_SSL				if (sess->ssl) {					e = GF_IP_NETWORK_FAILURE;					if (!SSL_write(sess->ssl, par.data+done, par.size-done)) e = GF_OK;				} else #endif					e = gf_sk_send(sess->sock, par.data+done, par.size-done);				if (e) {					sess->status = GF_NETIO_STATE_ERROR;					sess->last_error = e;					gf_dm_sess_notify_state(sess, GF_NETIO_STATE_ERROR, e);					return;				}			}		}		sess->status = GF_NETIO_WAIT_FOR_REPLY;		gf_dm_sess_notify_state(sess, GF_NETIO_WAIT_FOR_REPLY, GF_OK);		return;	}	/*process HTTP request*/	if (sess->status == GF_NETIO_WAIT_FOR_REPLY) {		bytesRead = res = 0;		new_location = NULL;		while (1) {			e = gf_dm_read_data(sess, sHTTP + bytesRead, GF_DOWNLOAD_BUFFER_SIZE - bytesRead, &res);				switch (e) {			case GF_IP_NETWORK_EMPTY:				if (!bytesRead) return;				continue;			/*socket has been closed while configuring, retry (not sure if the server got the GET)*/			case GF_IP_CONNECTION_CLOSED:				gf_dm_disconnect(sess);				if (sess->num_retry)					sess->status = GF_NETIO_SETUP;				else {					sess->last_error = e;					sess->status = GF_NETIO_STATE_ERROR;				}				return;			case GF_OK:				if (!res) return;				break;			default:				goto exit;			}			bytesRead += res;			/*locate body start*/			BodyStart = gf_token_find(sHTTP, 0, bytesRead, "\r\n\r\n");			if (BodyStart <= 0) {				BodyStart=0;				continue;			}			BodyStart += 4;			break;		}		if (bytesRead < 0) {			e = GF_REMOTE_SERVICE_ERROR;			goto exit;		}		if (!BodyStart) 			BodyStart = bytesRead;		sHTTP[BodyStart-1] = 0;		GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[HTTP] %s\n\n", sHTTP));		LinePos = gf_token_get_line(sHTTP, 0, bytesRead, buf, 1024);		Pos = gf_token_get(buf, 0, " \t\r\n", comp, 400);		if (sess->mime_type) free(sess->mime_type);		sess->mime_type = NULL;		is_ice = 0;		if (!strncmp("ICY", comp, 4)) {			is_ice = 1;			/*be prepared not to recieve any mime type from ShoutCast servers*/			sess->mime_type = strdup("audio/mpeg");		} else if ((strncmp("HTTP", comp, 4) != 0)) {			e = GF_REMOTE_SERVICE_ERROR;			goto exit;		}		Pos = gf_token_get(buf, Pos, " ", comp, 400);		if (Pos <= 0) {			e = GF_REMOTE_SERVICE_ERROR;			goto exit;		}		rsp_code = (u32) atoi(comp);		Pos = gf_token_get(buf, Pos, " \r\n", comp, 400);		no_range = range = ContentLength = first_byte = last_byte = total_size = 0;		//parse header		while (1) {			char *sep, *hdr_sep;			if ( (u32) LinePos + 4 > BodyStart) break;			LinePos = gf_token_get_line(sHTTP, LinePos , bytesRead, buf, 1024);			if (LinePos < 0) break;			hdr_sep = NULL;			hdr_val = NULL;			hdr = buf;			sep = strchr(buf, ':');			if (sep) {				sep[0]=0;				hdr_val = sep+1;				while (hdr_val[0]==' ') hdr_val++;				hdr_sep = strrchr(hdr_val, '\r');				if (hdr_sep) hdr_sep[0] = 0;			}			par.error = 0;			par.msg_type = GF_NETIO_PARSE_HEADER;			par.name = hdr;			par.value = hdr_val;			gf_dm_sess_user_io(sess, &par);			if (!stricmp(hdr, "Content-Length") ) ContentLength = (u32) atoi(hdr_val);			else if (!stricmp(hdr, "Content-Type")) {							if (sess->mime_type) free(sess->mime_type);				sess->mime_type = strdup(hdr_val);				while (1) {					u32 len = strlen(sess->mime_type);					char c = len ? sess->mime_type[len-1] : 0;					if ((c=='\r') || (c=='\n')) {						sess->mime_type[len-1] = 0;					} else {						break;					}				}				hdr = strchr(sess->mime_type, ';');				if (hdr) hdr[0] = 0;			}			else if (!stricmp(hdr, "Content-Range")) {							range = 1;				if (!strncmp(hdr_val, "bytes", 5)) {					hdr_val += 5;					if (hdr_val[0] == ':') hdr_val += 1;					hdr_val += http_skip_space(hdr_val);					if (hdr_val[0] == '*') {						sscanf(hdr_val, "*/%d", &total_size);					} else {						sscanf(hdr_val, "%d-%d/%d", &first_byte, &last_byte, &total_size);					}				}			}			else if (!stricmp(hdr, "Accept-Ranges")) {				if (strstr(hdr_val, "none")) no_range = 1;			}			else if (!stricmp(hdr, "Location")) 				new_location = strdup(hdr_val);			else if (!stricmp(hdr, "icy-metaint")) 				sess->icy_metaint = atoi(hdr_val);			else if (!stricmp(hdr, "ice") || !stricmp(hdr, "icy") ) 				is_ice = 1;			if (sep) sep[0]=':';			if (hdr_sep) hdr_sep[0] = '\r';		}		if (no_range) first_byte = 0;		if (sess->cache_start_size) {			if (total_size && (sess->cache_start_size >= total_size) ) {				rsp_code = 200;				ContentLength = total_size;			}			if (ContentLength && (sess->cache_start_size == ContentLength) ) rsp_code = 200;		}			par.msg_type = GF_NETIO_PARSE_REPLY;		par.error = GF_OK;		par.reply = rsp_code;		par.value = comp;		switch (rsp_code) {		case 200:		case 201:		case 202:		case 206:			gf_dm_sess_user_io(sess, &par);			e = GF_OK;			break;		/*redirection: extract the new location*/		case 301:		case 302:			if (!new_location || !strlen(new_location) ) {				gf_dm_sess_user_io(sess, &par);				e = GF_URL_ERROR;				goto exit;			}			while (				(new_location[strlen(new_location)-1] == '\n') 				|| (new_location[strlen(new_location)-1] == '\r')  )				new_location[strlen(new_location)-1] = 0;			/*reset and reconnect*/			gf_dm_disconnect(sess);			sess->status = GF_NETIO_SETUP;			e = gf_dm_setup_from_url(sess, new_location);			if (e) {				sess->status = GF_NETIO_STATE_ERROR;				sess->last_error = e;				gf_dm_sess_notify_state(sess, sess->status, e);				return;			}			return;		case 404:		case 416:			/*try without cache (some servers screw up when content-length is specified)*/			if (sess->cache_start_size) {				gf_dm_disconnect(sess);				sess->status = GF_NETIO_SETUP;				return;			} else if (is_ice && !(sess->flags & GF_DOWNLOAD_IS_ICY)) {				gf_dm_disconnect(sess);				sess->status = GF_NETIO_SETUP;				sess->flags |= GF_DOWNLOAD_IS_ICY;				return;			}			gf_dm_sess_user_io(sess, &par);			e = GF_URL_ERROR;			goto exit;		case 503:		default:			gf_dm_sess_user_io(sess, &par);			e = GF_REMOTE_SERVICE_ERROR;			goto exit;		}		/*head*/		if (sess->http_read_type==1) {			gf_dm_disconnect(sess);			gf_dm_sess_notify_state(sess, GF_NETIO_DATA_TRANSFERED, GF_OK);			sess->status = GF_NETIO_DISCONNECTED;			sess->http_read_type = 0;			return;		}		if (!ContentLength && sess->mime_type && strstr(sess->mime_type, "ogg")) is_ice = 1;		/*some servers may reply without content length, but we MUST have it*///		if (!is_ice && !ContentLength) e = GF_REMOTE_SERVICE_ERROR;		if (e) goto exit;		/*force disabling cache (no content length)*/		if (is_ice) {			sess->flags |= GF_NETIO_SESSION_NOT_CACHED;			if (sess->mime_type && !stricmp(sess->mime_type, "video/nsv")) {				free(sess->mime_type);				sess->mime_type = strdup("audio/aac");			}		}		/*done*/		if (sess->cache_start_size 			&& ( (total_size && sess->cache_start_size >= total_size) || (sess->cache_start_size == ContentLength)) ) {			sess->total_size = sess->bytes_done = sess->cache_start_size;			/*disconnect*/			gf_dm_disconnect(sess);			BodyStart = bytesRead;			gf_dm_sess_notify_state(sess, GF_NETIO_DATA_TRANSFERED, GF_OK);		}		else if (sess->flags & GF_DOWNLOAD_IS_ICY) {			sess->icy_bytes = 0;			sess->status = GF_NETIO_DATA_EXCHANGE;		}		/*we don't expect anything*/		else if (!ContentLength && sess->http_read_type) {			gf_dm_disconnect(sess);			gf_dm_sess_notify_state(sess, GF_NETIO_DATA_TRANSFERED, GF_OK);			sess->status = GF_NETIO_DISCONNECTED;			sess->http_read_type = 0;		}		/*no range header, Accep-Ranges deny or dumb server : restart*/		else if (!range || !first_byte || (first_byte != sess->cache_start_size) ) {			sess->cache_start_size = sess->bytes_done = 0;			sess->total_size = ContentLength;			if (! (sess->flags & GF_NETIO_SESSION_NOT_CACHED) ) {				sess->cache = fopen(sess->cache_name, "wb");				if (!sess->cache) {					e = GF_IO_ERR;					goto exit;				}			}			sess->status = GF_NETIO_DATA_EXCHANGE;		}		/*resume*/		else {			sess->total_size = ContentLength + sess->cache_start_size;			if (! (sess->flags & GF_NETIO_SESSION_NOT_CACHED) ) {				sess->cache = fopen(sess->cache_name, "ab");				if (!sess->cache) {					e = GF_IO_ERR;					goto exit;				}			}			sess->status = GF_NETIO_DATA_EXCHANGE;			sess->bytes_done = sess->cache_start_size;		}		sess->window_start = sess->start_time = gf_sys_clock();		sess->bytes_in_wnd = 0;		//we may have existing data in this buffer ...		if (!e && (BodyStart < (u32) bytesRead)) {			gf_dm_data_recieved(sess, sHTTP + BodyStart, bytesRead - BodyStart);			/*store data if no callbacks or cache*/			if (sess->flags & GF_NETIO_SESSION_NOT_CACHED) {				if (sess->init_data) free(sess->init_data);				sess->init_data_size = bytesRead - BodyStart;				sess->init_data = (char *) malloc(sizeof(char) * sess->init_data_size);				memcpy(sess->init_data, sHTTP+BodyStart, sess->init_data_size);			}		}exit:		if (e) {			gf_dm_disconnect(sess);			sess->status = GF_NETIO_STATE_ERROR;			sess->last_error = e;			gf_dm_sess_notify_state(sess, sess->status, e);		}		return;	}	/*fetch data*/	while (1) {		u32 size;#if 1		if (sess->limit_data_rate && sess->bytes_per_sec) {			if (sess->bytes_per_sec>sess->limit_data_rate) {				/*update state*/				u32 runtime = gf_sys_clock() - sess->window_start;				sess->bytes_per_sec = (1000 * (sess->bytes_in_wnd)) / runtime;				if (sess->bytes_per_sec > sess->limit_data_rate) return;			}		}#endif		e = gf_dm_read_data(sess, sHTTP, GF_DOWNLOAD_BUFFER_SIZE, &size);		if (!size || e == GF_IP_NETWORK_EMPTY) {					if (!sess->total_size && (gf_sys_clock() - sess->window_start > 1000)) {				sess->total_size = sess->bytes_done;				gf_dm_sess_notify_state(sess, GF_NETIO_DATA_TRANSFERED, GF_OK);			}			return;		}		if (e) {			gf_dm_disconnect(sess);			sess->last_error = e;			gf_dm_sess_notify_state(sess, sess->status, e);			return;		}		gf_dm_data_recieved(sess, sHTTP, size);		/*socket empty*/		if (size < GF_DOWNLOAD_BUFFER_SIZE) return;	}}

⌨️ 快捷键说明

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