// ************************************************************************** // リクエストされた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 ); }
// ************************************************************************** // * サーバ 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; }
// ************************************************************************** // リクエストされた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 ) ; } } }