Beispiel #1
0
// **************************************************************************
// リクエストされたURIのファイルをチェック
// documet_rootと、skin置き場をセットで探す。
//
// Sets http_recv_info_p->file_type to one of the following:
//			-2: Directory without the slash
//			-1: File not found
//			 0: Normal file
//			 1: Directory
//			 2: SVI
//			 3: plw/upl
//			 4: tsv
//			 5: VOB video file
//			 6: CGI script
//			 7: ISO DVD image
// **************************************************************************
static int http_file_check( HTTP_RECV_INFO *http_recv_info_p)
{
	struct stat send_filestat;
	int result;
	int len;

	unsigned char	file_extension[16];

	debug_log_output("http_file_check() start.");

	// ---------------
	// 作業用変数初期化
	// ---------------
	memset(http_recv_info_p->send_filename, '\0', sizeof(http_recv_info_p->send_filename));
	memset(file_extension, '\0', sizeof(file_extension));

	// -------------------------
	// ファイルチェック
	// -------------------------

	// 要求パスのフルパス生成。
	strncpy(http_recv_info_p->send_filename, global_param.document_root, sizeof(http_recv_info_p->send_filename));
	strncat(http_recv_info_p->send_filename, http_recv_info_p->recv_uri, sizeof(http_recv_info_p->send_filename));

	// Check if the URI is an alias
	// printf("uri1 is %s\n", http_recv_info_p->recv_uri);
	// printf("send_filename1 %s\n", http_recv_info_p->send_filename);
	if(global_param.num_aliases && (http_recv_info_p->recv_uri[0] == '/')) {
		int i,j,len, skip_stat;
		char *p;
		
		for(i=0; i<global_param.num_aliases; i++) {
			len = strlen(global_param.alias_name[i]);
			if ((strncmp(http_recv_info_p->recv_uri + 1, global_param.alias_name[i], len) == 0)
			   && (http_recv_info_p->recv_uri[len+1] == '/') ) {
			   // see code in set_thumb_file in wizd_menu.c
				p = strrchr(http_recv_info_p->recv_uri, '.');
				if (p && isdigit(p[1]) && isdigit(p[2]) && !p[3]) {
					p[0] = 0;
					p++;
					j = atoi(p);
					skip_stat = 1;
				} else {
					j = i;
					skip_stat = 0;
				}

				debug_log_output("substituting alias path '%s' for '%s'\n",
								  global_param.alias_path[j],
								  global_param.alias_name[j]);

				// The name matches an alias - substitute the alias path
				strncpy(http_recv_info_p->send_filename, global_param.alias_path[j], sizeof(http_recv_info_p->send_filename));
				strncat(http_recv_info_p->send_filename, http_recv_info_p->recv_uri+len+1, sizeof(http_recv_info_p->send_filename)-strlen(http_recv_info_p->send_filename));

				if (!skip_stat && stat(http_recv_info_p->send_filename, &send_filestat) != 0)
					continue;

				// Set the default allplay type, if it was not specified in the http request
				if(http_recv_info_p->default_file_type == TYPE_UNKNOWN) {
					http_recv_info_p->default_file_type = global_param.alias_default_file_type[j];
					debug_log_output("Setting default file type to %d\n",http_recv_info_p->default_file_type);
				} else {
					debug_log_output("Leaving default file type set at %d\n",http_recv_info_p->default_file_type);
				}
				break;
			}
		}
	}

	// fix up shortcuts
# ifdef HAVE_W32API
	len = strlen(http_recv_info_p->recv_uri);
	if (len > 4 && strcmp(&http_recv_info_p->recv_uri[len - 4], ".lnk") == 0) {
		char retPath1[256];
		char retPath2[256];
		char *p1, *p2;

		cygwin_conv_to_full_win32_path(http_recv_info_p->send_filename, retPath1);
		if (get_target(retPath1, retPath2) == 0) {
			cygwin_conv_to_full_posix_path(retPath2, http_recv_info_p->send_filename);

			p1 = strrchr(http_recv_info_p->recv_uri, '/');
			p1++;
			p2 = strrchr(http_recv_info_p->send_filename, '/');
			p2++;
			strcpy(p1, p2);
		}
	}
# endif

	// printf("send_filename2 %s\n", http_recv_info_p->send_filename);
	// printf("uri2 is %s\n\n", http_recv_info_p->recv_uri);

	// '/' が重なってるところの重複を排除。
	duplex_character_to_unique(http_recv_info_p->send_filename, '/');
	debug_log_output("http_recv_info_p->send_filename='%s'\n", http_recv_info_p->send_filename);


	// Return "File not found" unless we get a match
	http_recv_info_p->file_type = -1;

	// ------------------------------------------------------------
	// ファイルあるかチェック。
	// ------------------------------------------------------------
	result = stat(http_recv_info_p->send_filename, &send_filestat);
	debug_log_output("stat: result=%d, st_mode=0x%04X, S_ISREG=%d, S_ISDIR=%d size=%lld\n", 
		result, send_filestat.st_mode, S_ISREG(send_filestat.st_mode), S_ISDIR(send_filestat.st_mode), send_filestat.st_size );
	http_recv_info_p->file_size = send_filestat.st_size;

	if(result < 0)
	{
		debug_log_output("stat() error\n", result);

		// ----------------------------------------------------------------------------
		// もし、実体が存在しなかったら、skin置き場に変えてもう一度チェック
		// Skin置き場は実体ファイルのみ認める。
		// ----------------------------------------------------------------------------
		debug_log_output("DocumentRoot not found. SkinDir Check.");

		debug_log_output("global_param.skin_root='%s'", global_param.skin_root);
		debug_log_output("global_param.skin_name='%s'", global_param.skin_name);


		// skin置き場にあるモノとして、フルパス生成。
		strncpy(http_recv_info_p->send_filename, global_param.skin_root, sizeof(http_recv_info_p->send_filename));
		strncat(http_recv_info_p->send_filename, global_param.skin_name, sizeof(http_recv_info_p->send_filename));
		strncat(http_recv_info_p->send_filename, http_recv_info_p->recv_uri, sizeof(http_recv_info_p->send_filename));

		// '/' が重なってるところの重複を排除。
		duplex_character_to_unique(http_recv_info_p->send_filename, '/');
		debug_log_output("SkinDir:http_recv_info_p->send_filename='%s'\n", http_recv_info_p->send_filename);


		// ------------------------------------------------------------
		// Skin置き場にファイルあるかチェック。
		// ------------------------------------------------------------
		result = stat(http_recv_info_p->send_filename, &send_filestat);
		debug_log_output("stat: result=%d, st_mode=%04X, S_ISREG=%d\n", result, send_filestat.st_mode, S_ISREG(send_filestat.st_mode));

		if( result < 0 ) {
			// Strip off the path, and try just the filename in the skin directory
			unsigned char *ptr = strrchr(http_recv_info_p->recv_uri, '/');
			if((ptr != NULL) && (ptr != http_recv_info_p->recv_uri)) {
				strncpy(http_recv_info_p->send_filename, global_param.skin_root, sizeof(http_recv_info_p->send_filename));
				strncat(http_recv_info_p->send_filename, global_param.skin_name, sizeof(http_recv_info_p->send_filename)-strlen(http_recv_info_p->send_filename));
				strncat(http_recv_info_p->send_filename, ptr, sizeof(http_recv_info_p->send_filename)-strlen(http_recv_info_p->send_filename));
				duplex_character_to_unique(http_recv_info_p->send_filename, '/');
				debug_log_output("SkinDir:http_recv_info_p->send_filename='%s'\n", http_recv_info_p->send_filename);
				result = stat(http_recv_info_p->send_filename, &send_filestat);
				debug_log_output("stat: result=%d, st_mode=%04X, S_ISREG=%d\n", result, send_filestat.st_mode, S_ISREG(send_filestat.st_mode));
			}
		}

		// ファイル実体と検知。
		if ( ( result < 0 ) || !(S_ISREG(send_filestat.st_mode)) )
		{
			// -------------------------------------
			// File Not Found.
			// やっぱり、404にしよう。
			// -------------------------------------
			http_recv_info_p->file_type = -1; // Not found
			return(http_recv_info_p->file_type);
		}
	}


	// stat()の結果で分岐。
	if ( ( result == 0 ) && ( S_ISREG(send_filestat.st_mode) == 1 ) )
	{
		 // ファイル実体と検知
		debug_log_output("'%s' is File!!", http_recv_info_p->send_filename);
		debug_log_output("send_filestat.st_size= %lld\n", send_filestat.st_size);

		// Hack to overcome Linkplayer bug - it limits bookmark offset to (2^31)-1
		// so we remember the last bookmark served so we can recover the real offset
		if((http_recv_info_p->range_start_pos == 2147483647) && global_param.bookmark_threshold) {
			// Check for the real bookmark
			FILE *fp;
			off_t offset;
			char work_buf[WIZD_FILENAME_MAX];
			snprintf(work_buf, sizeof(work_buf), "%s.wizd.bookmark", 
				http_recv_info_p->send_filename);
			debug_log_output("Double-checking bookmark: '%s'", work_buf);
			fp = fopen(work_buf, "r");
			if(fp != NULL) {
				fgets(work_buf, sizeof(work_buf), fp);
				fclose(fp);
				offset = atoll(work_buf);
				if(offset > http_recv_info_p->range_start_pos) {
					debug_log_output("Detected LinkPlayer2 bookmark bug, replacing 'Range: %lld-' with 'Range: %lld-'",
						http_recv_info_p->range_start_pos, offset);
					http_recv_info_p->range_start_pos = offset;
				}
			}
		}


		// -------------------------------------------
		// ファイルの拡張子より、Content-type を決定
		// -------------------------------------------
		filename_to_extension(http_recv_info_p->send_filename, file_extension, sizeof(file_extension));
		debug_log_output("http_recv_info_p->send_filename='%s', file_extension='%s'\n", http_recv_info_p->send_filename, file_extension);

		// 拡張子から、mime_typeを導く。
		http_recv_info_p->menu_file_type = check_file_extension_to_mime_type(file_extension, http_recv_info_p->mime_type,  sizeof(http_recv_info_p->mime_type));

		// SVIファイルと実体ファイルで分岐
		if (( strcasecmp(file_extension, "svi") == 0 ) || ( strcasecmp(file_extension, "sv3") == 0 ))
		{
			http_recv_info_p->file_type = SVI_TYPE;	// sviファイル
		}
		else if (  ( http_recv_info_p->menu_file_type == TYPE_PLAYLIST )
				|| ( http_recv_info_p->menu_file_type == TYPE_MUSICLIST ))
			/*( strcasecmp(file_extension, "plw") == 0  ) ||
				 ( strcasecmp(file_extension, "pls") == 0  ) ||
				 ( strcasecmp(file_extension, "m3u") == 0  ) ||
				 ( strcasecmp(file_extension, "upl") == 0  ) )*/
		{
			http_recv_info_p->file_type = PLW_UPL_TYPE;	// plw/upl ファイル
		}
		else if (( strcasecmp(file_extension, "vob") == 0  )
			|| ( strcasecmp(file_extension, "ts") == 0  )
			|| ( strcasecmp(file_extension, "tp") == 0  ) )
		{
			// VOB_TYPE files combine files with increasing digits at the end of the filename
			// into one large virtual file
			http_recv_info_p->file_type = VOB_TYPE;	// vobファイル
		}
		else if ( strcasecmp(file_extension, "tsv") == 0  )
		{
			http_recv_info_p->file_type = TSV_TYPE;	// tsvファイル
		}
		else if ( strcasecmp(file_extension, "cgi") == 0  )
		{
			// CGIの実行が不許可なら、Not Found.
			http_recv_info_p->file_type = (global_param.flag_execute_cgi ? CGI_TYPE : -1 );	// cgiファイル
		}
		else if ( http_recv_info_p->menu_file_type == TYPE_ISO )
		{
			http_recv_info_p->file_type = ISO_TYPE;
		}
		else
		{
			http_recv_info_p->file_type = GENERAL_FILE_TYPE;	// File実体
		}
	}
	else if ( ( result == 0 ) && ( S_ISDIR(send_filestat.st_mode) == 1 ) ) // ディレクトリ
	{
		int len;
		len = strlen(http_recv_info_p->recv_uri);
		if (len > 0 && http_recv_info_p->recv_uri[len - 1] != '/') {
			// '/' で終端していないディレクトリ要求の場合...
			http_recv_info_p->file_type = -2;
		}
		// ディレクトリと検知
		debug_log_output("'%s' is Dir!!", http_recv_info_p->send_filename);

		http_recv_info_p->file_type = DIRECTORY_TYPE ;	// ディレクトリ
	}
	return( http_recv_info_p->file_type );
}
Beispiel #2
0
// **************************************************************************
// * サーバ HTTP処理部
// **************************************************************************
void 	server_http_process(int accept_socket)
{
	int					result;
	HTTP_RECV_INFO	http_recv_info;	//HTTP受信情報保存構造体
	int				i;
	int				flag_allow_user_agent_check;
	int				found;

	memset(&http_recv_info, 0, sizeof(http_recv_info));


	// ----------------------------------------
	// HTTP リクエストヘッダ受信
	// ----------------------------------------
	debug_log_output("HTTP Header receive start!\n");

	result = http_header_receive(accept_socket,  &http_recv_info);
	if ( result != 0 ) // エラーチェック
	{
		// エラーメッセージ
		debug_log_output("http_header_receive() Error. result=%d\n", result);
		// ソケットクローズ
		close(accept_socket);
		return;
	}
	debug_log_output("HTTP Header receive end!\n");

	debug_log_output("recv_uri:'%s'\n", http_recv_info.recv_uri);
	debug_log_output("user_agent:'%s'\n", http_recv_info.user_agent);

	debug_log_output("range_start_pos=%lld\n", http_recv_info.range_start_pos);
	debug_log_output("range_end_pos=%lld\n", http_recv_info.range_end_pos);

	if (http_recv_info.passwd[0]) {
		debug_log_output("http passwd:'%s'\n", http_recv_info.passwd);
	}

	// ==========================
	// = User-Agent チェック
	// ==========================

	flag_allow_user_agent_check = 0;

	if ( strlen(allow_user_agent[0].user_agent)  == 0 ) // User-Agnet指示が無し。
	{
		debug_log_output("user_agent: allow_user_agent No List. All Allow.");
		flag_allow_user_agent_check = 1; // OK
	}
	else
	{
		// User-Agent チェック実行
		for ( i=0; i<ALLOW_USER_AGENT_LIST_MAX; i++)
		{
			if ( strlen(allow_user_agent[i].user_agent)  == 0 )
			{
				break;
			}

			// 一致チェック
			debug_log_output("user_agent: Check[%d] '%s' in '%s'",i, allow_user_agent[i].user_agent, http_recv_info.user_agent);
			if ( strstr( http_recv_info.user_agent, allow_user_agent[i].user_agent ) != NULL )
			{
				debug_log_output("user_agent: '%s' OK.", allow_user_agent[i].user_agent );
				flag_allow_user_agent_check = 1; // 一致。OK
				break;
			}
		}
	}

	if (global_param.http_passwd[0] && !flag_allow_user_agent_check) {
		// パスワードが設定されて、正しければ、User-AgentチェックNGでもOK.
		char *pass, *p;

		pass = base64(global_param.http_passwd);
		if ((p = strchr(pass, '=')) != NULL) {
			*p = '\0';
		}
		if ((p = strchr(http_recv_info.passwd, '=')) != NULL) {
			*p = '\0';
		}

		if (!strcmp(pass, http_recv_info.passwd)) {
			// 一致
			flag_allow_user_agent_check = 1;
		} else {
			// 不一致
			// flag_allow_user_agent_check = 0;

			http_unauthorized_response(accept_socket, &http_recv_info);
			close(accept_socket);
			return ;
		}
	}

	// User-Agentチェック NGならば、ソケットクローズ。終了。
	if ( flag_allow_user_agent_check == 0 )
	{
		debug_log_output("allow_user_agent check. Deny. Socket close.");

		// ソケットクローズ
		close(accept_socket);
		return;
	}

	// クライアントがPCかどうか判断
	http_recv_info.flag_pc = (global_param.user_agent_pc[0]
		&& !strncmp(http_recv_info.user_agent, global_param.user_agent_pc
			, strlen(global_param.user_agent_pc))
	) ? 1 : 0;

	if(global_param.user_agent_pc[0]) {
		debug_log_output("Checking for PC user agent '%s'", global_param.user_agent_pc);
	}
	debug_log_output("flag_pc: %d", http_recv_info.flag_pc);

	// User-Agent
	// HD: 'Syabas/13-14-060414-04-IOD-234-000/04-IOD (uCOS-II v2.05;NOS;KA9Q; Res1280x720-HiColor; TV Res1920x1080; Browser Res1104x656-8bits; www.syabas.com mac_addr=00.a0.b0.65.51.31)'(186 byte)
	// SD: 'Syabas/13-14-060414-04-IOD-234-000/04-IOD (uCOS-II v2.05;NOS;KA9Q; Res624x416-HiColor; TV Res1920x1080; Browser Res624x416-8bits; www.syabas.com mac_addr=00.a0.b0.65.51.31)'

	http_recv_info.flag_hd = (strstr(http_recv_info.user_agent, "Res624x416") == NULL);

	if (!strncmp(http_recv_info.recv_uri, "/-.-", 4)) {
		// proxy
		if (http_proxy_response(accept_socket, &http_recv_info) < 0) {
			http_not_found_response(accept_socket, &http_recv_info);
		}

		// ソケットクローズ
		close(accept_socket);
		return;
	}

	if (path_sanitize(http_recv_info.recv_uri, sizeof(http_recv_info.recv_uri)) == NULL) {
		// BAD REQUEST!
		debug_log_output("BAD REQUEST!");
		http_not_found_response(accept_socket, &http_recv_info);
		close(accept_socket);
		return;
	}
	debug_log_output("sanitized recv_uri: %s", http_recv_info.recv_uri);

	// ----------------------------------------
	// 受け取ったURIの拡張子がrename対象ならばrename
	// ----------------------------------------
	extension_del_rename(http_recv_info.recv_uri, sizeof(http_recv_info.recv_uri));

	// ============================
	// ファイルチェック
	//  種類に応じて分岐
	// ============================
	result = http_file_check(&http_recv_info);
	debug_log_output("http_file_check returns %d\n", result);

	if (result != CGI_TYPE && !strcmp(http_recv_info.request_method, "POST")) {
		debug_log_output("BAD POST REQUEST.");
		http_not_found_response(accept_socket, &http_recv_info);
	}
	else if (result == -2) { // Directory without the trailing slash -> redirect
		char buffer[WIZD_FILENAME_MAX];
		sprintf(buffer, "%s/", http_recv_info.recv_uri);
		http_redirect_response(accept_socket, &http_recv_info, buffer);
	}
	else if ( result < 0 ) // File not found
	{
		http_not_found_response(accept_socket, &http_recv_info);
	}
	else if ( result == GENERAL_FILE_TYPE ) // ファイル実体ならば、実体転送。
	{
		if ( global_param.flag_allow_delete && (strcasecmp(http_recv_info.action, "delete" ) == 0) )
		{
			// ----------------------------------------
			// Delete file
			// ----------------------------------------
			char path[WIZD_FILENAME_MAX];

			debug_log_output("Delete file start!\n");
			debug_log_output("unlink(%s)", http_recv_info.send_filename);
			unlink(http_recv_info.send_filename);
			// Remove any associated bookmarks if they exist
			snprintf(path, sizeof(path), "%s.wizd.bookmark", http_recv_info.send_filename);
			unlink(path);

			// Redirect to directory
			strncpy(path, http_recv_info.recv_uri, sizeof(path));
			cut_after_last_character(path, '/');
			strcat(path, "/");
			http_redirect_response(accept_socket, &http_recv_info, path);
			debug_log_output("Delete file end!\n");
		} else
		// actionに、ImageViewerが指示されている?
		if ( strcasecmp(http_recv_info.action, "ImageView" ) == 0)
		{
			// ----------------------------------------
			// イメージファイルビューアー
			// ----------------------------------------
			debug_log_output("Image Viewer start!\n");
			http_image_viewer(accept_socket, &http_recv_info);
			debug_log_output("Image Viewer end!\n");
		}
		// actionに、SinglePlayが指示されている?
		else if ( strcasecmp(http_recv_info.action, "SinglePlay" ) == 0)
		{
			// ----------------------------------------
			// Musicファイル 単独プレイ
			// ----------------------------------------
			debug_log_output("Single Play start!\n");
			http_music_single_play(accept_socket, &http_recv_info);
			debug_log_output("Single Play end!\n");
		}
#ifdef RESIZE_JPEG
		// actionに、Resizeが指示されている?
		else if ( strcasecmp(http_recv_info.action, "Resize.jpg" ) == 0)
		{
			// ----------------------------------------
			// JPEG Resize
			// ----------------------------------------
			debug_log_output("JPEG Resize start!\n");
			if(http_send_resized_jpeg(accept_socket, &http_recv_info) == 0) {
				// Failed to resize - send the original file as-is
				// (this can happen if we have the wrong file extension)
				http_file_response(accept_socket, &http_recv_info);
			}
			debug_log_output("JPEG Resize end!\n");
		}
#endif
		else if (strcmp(http_recv_info.option, "aviinfo") == 0)
		{
			debug_log_output("got aviinfo option\n");
			http_menu(accept_socket, &http_recv_info);
		}
		else if (strcmp(http_recv_info.option, "mp3info") == 0)
		{
			http_menu(accept_socket, &http_recv_info);
		}
		else // アクションに指定無し。
		{
			// ----------------------------------------
			// ファイルの実体
			// HTTPリクエストヘッダに従ってデータを返信。
			// ----------------------------------------
			found = 0;
			if (global_param.flag_use_index && strstr(http_recv_info.recv_uri, "wizd") != 0 && strstr(http_recv_info.recv_uri, ".htm") != 0) {
				if (http_find_and_replace_html(accept_socket, &http_recv_info)) {
					found = 1;
				}
			}

			if (!found) {
				debug_log_output("HTTP response start!\n");
				http_file_response(accept_socket, &http_recv_info);
				debug_log_output("HTTP response end!\n");
			}
		}

	}
	else if ( result == SVI_TYPE )
	{
		// ----------------------------------------
		// SVIファイル(;´Д`)
		// SVIファイル処理してデータを返信
		// ----------------------------------------

		// actionに、SinglePlayが指示されている?
		if ( strcasecmp(http_recv_info.action, "SinglePlay" ) == 0)
		{
			// ----------------------------------------
			// Musicファイル 単独プレイ
			// ----------------------------------------
			debug_log_output("Single Play start!(SVI)\n");
			http_music_single_play(accept_socket, &http_recv_info);
			debug_log_output("Single Play end!(SVI)\n");
		}
		else // アクションに指定無し。
		{
			debug_log_output("HTTP joint file response start!\n");
			http_joint_file_response(accept_socket, &http_recv_info);
			debug_log_output("HTTP joint file response end!\n");
		}
	}
	else if ( result == PLW_UPL_TYPE )
	{
		// ---------------------------------------------
		// plw/uplファイル(`・ω・´)
		// リストファイルから、プレイリスト生成して返信
		// ---------------------------------------------
		debug_log_output("HTTP wizd play list create and response start!\n");
		http_listfile_to_playlist_create(accept_socket, &http_recv_info);
		debug_log_output("HTTP wizd play list create and response end!\n");
	}
	else if ( result == VOB_TYPE )
	{
		// ---------------------------------------------
		// vobファイル 連結
		// vobを連結して返信
		// ---------------------------------------------

		// actionに、SinglePlayが指示されている?
		if ( strcasecmp(http_recv_info.action, "SinglePlay" ) == 0)
		{
			// ----------------------------------------
			// Musicファイル 単独プレイ
			// ----------------------------------------
			debug_log_output("Single Play start!(VOB)\n");
			http_music_single_play(accept_socket, &http_recv_info);
			debug_log_output("Single Play end!(VOB)\n");
		}
		else // アクションに指定無し。
		{
			debug_log_output("HTTP vob file response start!\n");
			http_vob_file_response(accept_socket, &http_recv_info);
			debug_log_output("HTTP vob file response end!\n");
		}
	}
	else if ( result == CGI_TYPE )
	{
		// ---------------------------------------------
		// cgiファイル
		// cgiを実行して結果を返信
		// ---------------------------------------------
		debug_log_output("HTTP CGI response start!\n");
		http_cgi_response(accept_socket, &http_recv_info);
		debug_log_output("HTTP CGI response end!\n");
	}
	else if ( result == ISO_TYPE )
	{ // ISO file handling
		if ( (strcasecmp(http_recv_info.action, "IsoPlay" ) == 0) ||
			(strcasecmp(http_recv_info.action, "dvdplay" ) == 0) ||
			(strncmp(http_recv_info.action, "showchapters", 12 ) == 0))
		{
			debug_log_output("ISO playlist create start!\n");
			http_menu(accept_socket, &http_recv_info);
			debug_log_output("ISO playlist create end!\n");
		}
		else
		{
			// Start to stream the VOB
			debug_log_output("HTTP ISO file response start!\n");
			http_vob_file_response(accept_socket, &http_recv_info);
			debug_log_output("HTTP ISO file response end!\n");
		}
	}
	else
	{
		// ----------------------------------------
		// ディレクトリ
		// ----------------------------------------

		// actionに、OptionMenuが指示されている?
		if ( strcasecmp(http_recv_info.action, "OptionMenu" ) == 0)
		{
			debug_log_output("HTTP Option menu create.\n");
			http_option_menu(accept_socket, &http_recv_info);
			debug_log_output("HTTP Option menu end.\n");
		}
		else if ( strcasecmp(http_recv_info.action, "copy" ) == 0)
		{
			// --------------------------------------------
			// Copy the default playlist to this directory
			// --------------------------------------------
			char source[WIZD_FILENAME_MAX];
			char dest[WIZD_FILENAME_MAX];
			int fd_source, fd_dest;

			if(http_recv_info.default_file_type == TYPE_MUSICLIST) {
				snprintf(dest, sizeof(dest), "%s/%s", http_recv_info.send_filename, DEFAULT_MUSICLIST);
				snprintf(source, sizeof(source), "%s/%s/%s", global_param.skin_root, global_param.skin_name, DEFAULT_MUSICLIST);
			} else {
				snprintf(dest, sizeof(dest), "%s/%s", http_recv_info.send_filename, DEFAULT_PHOTOLIST);
				snprintf(source, sizeof(source), "%s/%s/%s", global_param.skin_root, global_param.skin_name, DEFAULT_PHOTOLIST);
			}
			duplex_character_to_unique(source, '/');
			duplex_character_to_unique(dest, '/');

			debug_log_output("Copying '%s' to '%s'", source, dest);

			// Copy the file
			fd_source = open(source, O_RDONLY);
			if(fd_source >= 0) {
				fd_dest = open(dest, O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | S_IWRITE);
				if(fd_dest >= 0) {
					while( (i = read(fd_source, source, sizeof(source))) > 0 ) {
						write(fd_dest, source, i);
					}
					close(fd_dest);
				} else {
					debug_log_output("Failed to open destination file");
				}
				close(fd_source);
			} else {
				debug_log_output("Failed to open source file");
			}
			
			// Redirect to the directory
			strncpy(dest, http_recv_info.recv_uri, sizeof(dest));
			cut_after_last_character(dest, '/');
			strcat(dest, "/");
			http_redirect_response(accept_socket, &http_recv_info, dest);
			debug_log_output("Copy playlist end!\n");
		}
		else	// DIRECTORY_TYPE or {wizd,index}.htm{l}
		{
			int	found = 0;

			if (global_param.flag_use_index) {
				if (http_find_and_replace(accept_socket, &http_recv_info))
					found = 1;
			}

			if (!found) {
				debug_log_output("HTTP file menu create.\n");
				http_menu(accept_socket, &http_recv_info);
				debug_log_output("HTTP file menu end.\n");
			}
		}
	}

	// Clean shutdown
	shutdown(accept_socket, SHUT_WR);
 
	for(i=0; i<1 && (read(accept_socket, &result, sizeof(result))>0); i++);



	// ソケットクローズ
	close(accept_socket);

	return;
}
Beispiel #3
0
// **************************************************************************
// リクエストされたURIのファイルをチェック
// documet_rootと、skin置き場をセットで探す。
//
// ret		 0:実体
//			 1:ディレクトリ
//			 3:plw/uplファイル(`・ω・´)
//			 4:tsvファイル(´・ω・`)
//			 5:VOBファイル
//			 6:CGIファイル
// **************************************************************************
static FILETYPES http_file_check( HTTP_RECV_INFO *http_recv_info_p)
{
    struct stat send_filestat={0};
    int result;
    char	file_extension[16];
    debug_log_output("http_file_check() start.");
    // ---------------
    // 作業用変数初期化
    // ---------------
    memset(http_recv_info_p->send_filename, '\0', sizeof(http_recv_info_p->send_filename));
    memset(file_extension, '\0', sizeof(file_extension));
    // -------------------------
    // ファイルチェック
    // -------------------------
    // 要求パスのフルパス生成。
    strncpy(http_recv_info_p->send_filename, global_param.document_root, sizeof(http_recv_info_p->send_filename));
    strncat(http_recv_info_p->send_filename, http_recv_info_p->recv_uri, sizeof(http_recv_info_p->send_filename));
    // '/' が重なってるところの重複を排除。
    duplex_character_to_unique(http_recv_info_p->send_filename, '/');
    debug_log_output("http_recv_info_p->send_filename='%s'\n", http_recv_info_p->send_filename);
    // ------------------------------------------------------------
    // ファイルあるかチェック。
    // ------------------------------------------------------------
    result = stat((char*)http_recv_info_p->send_filename, &send_filestat);
    debug_log_output("stat: result=%d, st_mode=0x%04X, S_ISREG=%d, S_ISDIR=%d\n",
    result, send_filestat.st_mode, S_ISREG(send_filestat.st_mode), S_ISDIR(send_filestat.st_mode) );
    // stat()の結果で分岐。
    if ( ( result == 0 ) && ( S_ISREG(send_filestat.st_mode) == 1 ) ){
        // ファイル実体と検知
        debug_log_output("'%s' is File!!", http_recv_info_p->send_filename);
        debug_log_output("send_filestat.st_size= %ld\n", send_filestat.st_size);//%lld?
        // -------------------------------------------
        // ファイルの拡張子より、Content-type を決定
        // -------------------------------------------
        filename_to_extension(http_recv_info_p->send_filename, file_extension, sizeof(file_extension));
        debug_log_output("http_recv_info_p->send_filename='%s', file_extension='%s'\n", http_recv_info_p->send_filename, file_extension);
        // 拡張子から、mime_typeを導く。
        check_file_extension_to_mime_type(file_extension, http_recv_info_p->mime_type,  sizeof(http_recv_info_p->mime_type));
        // 実体ファイルで分岐
        if (( strcasecmp(file_extension, "plw") == 0  ) ||
            ( strcasecmp(file_extension, "m3u") == 0  ) ||
            ( strcasecmp(file_extension, "upl") == 0  ) )
        {
            return ( _PLW );	// plw/upl ファイル
        }else if ( strcasecmp(file_extension, "cgi") == 0  ||
                   strcasecmp(file_extension, "jss") == 0  ||
                   strcasecmp(file_extension, "php") == 0  ||
                   strcasecmp(file_extension, "exe") == 0    ){
            // CGIの実行が不許可なら、Not Found.
            return ( global_param.flag_execute_cgi ? _CGI : _NOTFOUND );  // cgiファイ
        }else{
            return ( _FILE );	// File実体
        }
    }else if( wString::DirectoryExists( http_recv_info_p->send_filename ) ){    // パスが示すディレクトリが存在する
        //		int len;
        //		len = strlen(http_recv_info_p->recv_uri);
        //		if (len > 0 && http_recv_info_p->recv_uri[len - 1] != '/') {
        //			// '/' で終端していないディレクトリ要求の場合...
        //			return ( -2 );
        //		}
        // ディレクトリと検知
        debug_log_output("'%s' is Dir!!", http_recv_info_p->send_filename);
        return ( _DIR ) ;	// ディレクトリ
        //ファイルリストチェック
    }else{
        //		debug_log_output("stat() error\n", result);
        // ----------------------------------------------------------------------------
        // もし、実体が存在しなかったら、skin置き場に変えてもう一度チェック
        // Skin置き場は実体ファイルのみ認める。
        // ----------------------------------------------------------------------------
        debug_log_output("DocumentRoot not found. SkinDir Check.");
        debug_log_output("global_param.skin_root='%s'", global_param.skin_root);
        debug_log_output("global_param.skin_name='%s'", global_param.skin_name);
        // skin置き場にあるモノとして、フルパス生成。
        strncpy(http_recv_info_p->send_filename, global_param.skin_root, sizeof(http_recv_info_p->send_filename));
        strncat(http_recv_info_p->send_filename, global_param.skin_name, sizeof(http_recv_info_p->send_filename));
        strncat(http_recv_info_p->send_filename, http_recv_info_p->recv_uri, sizeof(http_recv_info_p->send_filename));
        // '/' が重なってるところの重複を排除。
        duplex_character_to_unique(http_recv_info_p->send_filename, '/');
        debug_log_output("SkinDir:http_recv_info_p->send_filename='%s'\n", http_recv_info_p->send_filename);
        // ------------------------------------------------------------
        // Skin置き場にファイルあるかチェック。
        // ------------------------------------------------------------
        result = stat((char*)http_recv_info_p->send_filename, &send_filestat);
        debug_log_output("stat: result=%d, st_mode=%04X, S_ISREG=%d\n", result, send_filestat.st_mode, S_ISREG(send_filestat.st_mode));
        // ファイル実体と検知。
        if ( ( result == 0 ) && (S_ISREG(send_filestat.st_mode) == 1 ) ){
            // ファイル実体と検知
            debug_log_output("'%s' is File!!", http_recv_info_p->send_filename);
            // -------------------------------------------
            // ファイルの拡張子より、Content-type を決定
            // -------------------------------------------
            filename_to_extension(http_recv_info_p->send_filename, file_extension, sizeof(file_extension));
            debug_log_output("http_recv_info_p->send_filename='%s', file_extension='%s'\n", http_recv_info_p->send_filename, file_extension);
            check_file_extension_to_mime_type(file_extension, http_recv_info_p->mime_type,  sizeof(http_recv_info_p->mime_type));
            if ( strcasecmp(file_extension, "cgi") == 0  ||
                 strcasecmp(file_extension, "jss") == 0  ||
                 strcasecmp(file_extension, "exe") == 0    ){
                // CGIの実行が不許可なら、Not Found.
                return ( global_param.flag_execute_cgi ? _CGI : _NOTFOUND );	// cgiファイル
            }else{
                return ( _FILE );	// File実体
            }
            //return ( 0 );	// File実体
        }else{
            // -------------------------------------
            // File Not Found.
            // やっぱり、404にしよう。
            // -------------------------------------
            return ( _NOTFOUND ) ;
        }
    }
}