FILETYPES http_index( HTTP_RECV_INFO* http_recv_info_p ) { char document_path[FILENAME_MAX]; char read_filename[FILENAME_MAX]; char file_extension[16]; //Path Normalize. strncpy(document_path, http_recv_info_p->send_filename, sizeof(document_path) ); if ( document_path[ strlen(document_path)-1 ] != DELIMITER[0] ){// 最後が'/'じゃなかったら、'/'を追加 strncat(document_path, DELIMITER, sizeof(document_path) -strlen(document_path) ); } // ---------------------------------------------- // document_root/index.* のフルパス生成 // ---------------------------------------------- snprintf(read_filename, sizeof( read_filename),"%sindex.html",document_path ); if( access( read_filename , 0 ) == 0 ){ strcat(http_recv_info_p->request_uri,"index.html"); strcpy(http_recv_info_p->send_filename,read_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); // 拡張子から、mime_typeを導く。 check_file_extension_to_mime_type(file_extension, http_recv_info_p->mime_type, sizeof(http_recv_info_p->mime_type)); return _FILE; } snprintf(read_filename, sizeof( read_filename),"%sindex.htm",document_path ); if( access( read_filename , 0 ) == 0 ){ strcat(http_recv_info_p->request_uri,"index.htm"); strcpy(http_recv_info_p->send_filename,read_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); // 拡張子から、mime_typeを導く。 check_file_extension_to_mime_type(file_extension, http_recv_info_p->mime_type, sizeof(http_recv_info_p->mime_type)); return _FILE; } snprintf(read_filename, sizeof( read_filename),"%sindex.php",document_path ); if( access( read_filename , 0 ) == 0 ){ strcat(http_recv_info_p->request_uri,"index.php"); strcpy(http_recv_info_p->send_filename,read_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); // 拡張子から、mime_typeを導く。 check_file_extension_to_mime_type(file_extension, http_recv_info_p->mime_type, sizeof(http_recv_info_p->mime_type)); return _CGI; } snprintf(read_filename, sizeof( read_filename),"%sindex.jss",document_path ); if( access( read_filename , 0 ) == 0 ){ strcat(http_recv_info_p->request_uri,"index.jss"); strcpy(http_recv_info_p->send_filename,read_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); // 拡張子から、mime_typeを導く。 check_file_extension_to_mime_type(file_extension, http_recv_info_p->mime_type, sizeof(http_recv_info_p->mime_type)); return _CGI; } return _DIR; }
// ************************************************************************** // 拡張子変更処理。追加用。 // extension_convert_listに従い、org → rename への変換を行う。 // // 例) "hogehoge.m2p" → "hogehoge.m2p.mpg" // ************************************************************************** void extension_add_rename(unsigned char *rename_filename_p, size_t rename_filename_size) { int i; unsigned char ext[WIZD_FILENAME_MAX]; if ( rename_filename_p == NULL ) return; filename_to_extension(rename_filename_p, ext, sizeof(ext)); if (strlen(ext) <= 0) return; for ( i=0; extension_convert_list[i].org_extension != NULL; i++ ) { debug_log_output("org='%s', rename='%s'" , extension_convert_list[i].org_extension , extension_convert_list[i].rename_extension); // 拡張子一致? if ( strcasecmp(ext, extension_convert_list[i].org_extension) == 0 ) { debug_log_output(" HIT!!!" ); // 拡張子を「追加」 strncat(rename_filename_p, "." , rename_filename_size - strlen(rename_filename_p)); strncat(rename_filename_p , extension_convert_list[i].rename_extension , rename_filename_size - strlen(rename_filename_p)); debug_log_output("rename_filename_p='%s'", rename_filename_p); break; } } return; }
// ************************************************************************** // リクエストされた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 ); }
// ************************************************************************** // リクエストされた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 ) ; } } }