// ************************************************************************** // * サーバ 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; }
// ************************************************************************** // * サーバ HTTP処理部 // ************************************************************************** void server_http_process(int accept_socket) { FILETYPES result; HTTP_RECV_INFO http_recv_info; //HTTP受信情報保存構造体 int flag_allow_user_agent_check; int ret; memset(&http_recv_info, 0, sizeof(http_recv_info)); // ---------------------------------------- // HTTP リクエストヘッダ受信 // ---------------------------------------- debug_log_output("HTTP Header receive start!\n"); ret = http_header_receive(accept_socket, &http_recv_info); if ( ret != 0 ){ // エラーチェック // エラーメッセージ debug_log_output("http_header_receive() Error. result=%d\n", ret); // ソケットクローズ sClose(accept_socket); return; } 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=%d\n", http_recv_info.range_start_pos); debug_log_output("range_end_pos=%d\n", http_recv_info.range_end_pos); // ========================== // = 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 チェック実行 //TODO iはかきつぶしちゃいけないよ。 for ( int 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; } } } // User-Agentチェック NGならば、ソケットクローズ。終了。 if ( flag_allow_user_agent_check == 0 ){ debug_log_output("allow_user_agent check. Deny. Socket close."); // ソケットクローズ sClose(accept_socket); return; } //PROXY判定 if (!strncmp(http_recv_info.recv_uri, "/-.-", 4)) { // proxy if (http_proxy_response(accept_socket, &http_recv_info) < 0){ debug_log_output("error close not found"); http_not_found_response(accept_socket, &http_recv_info); } // ソケットクローズ sClose(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); sClose(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); // ============================ // ファイルチェック // 種類に応じて分岐 // ============================ result = http_file_check(&http_recv_info); if (result == _OPENDIR){ // ディレクトリだが終端が '/' ではない char buffer[FILENAME_MAX]; sprintf(buffer, "%s/", http_recv_info.recv_uri); http_redirect_response(accept_socket, &http_recv_info, buffer); }else if ( result < _FILE ){ // ファイルが見つからない http_not_found_response(accept_socket, &http_recv_info); }else if ( result == _FILE ){ // ファイル実体ならば、実体転送。 // 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が指示されている? 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"); }else{ // アクションに指定無し。 // ---------------------------------------- // ファイルの実体 // HTTPリクエストヘッダに従ってデータを返信。 // ---------------------------------------- debug_log_output("HTTP response start!\n"); http_file_response(accept_socket, &http_recv_info); debug_log_output("HTTP response end!\n"); return; } }else if ( result == _PLW ){ // --------------------------------------------- // 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 == _CGI ){ // --------------------------------------------- // 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"); return; }else{ // ---------------------------------------- // ディレクトリ 内にindex.html or index.htm or index.cgi があったら、そちらを表示する。 // ---------------------------------------- //request_uriの最後が?なら強制的にmenu.jssを起動。それ以外は通常のファイル処理 //request_uriの設定 //?以降のパラメータがあるなら付け替える。なければsend_filenameをつける wString tmp(http_recv_info.request_uri); int pos=tmp.Pos("?"); if( pos >= 0 ){ strcpy(http_recv_info.recv_uri,"/menu.jss"); tmp = tmp.substr(pos+1,tmp.Length()-pos-1); if(tmp.Length()){ sprintf(http_recv_info.request_uri,"/menu.jss?%s", tmp.c_str()); }else{ sprintf(http_recv_info.request_uri,"/menu.jss?root=%s", http_recv_info.send_filename); } //send file nameの設定 sprintf(http_recv_info.send_filename,"%s%smenu.jss", global_param.skin_root,global_param.skin_name); http_cgi_response(accept_socket, &http_recv_info); debug_log_output("HTTP file menu end.\n"); return; //通常の処理 }else{ result = http_index( &http_recv_info ); if( result == _FILE ){ // ---------------------------------------- // ファイルの実体 // HTTPリクエストヘッダに従ってデータを返信。 // ---------------------------------------- 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 == _CGI ){ debug_log_output("HTTP CGI response start! %d\n",accept_socket); http_cgi_response(accept_socket, &http_recv_info); debug_log_output("HTTP CGI response end!\n"); return; }else{ debug_log_output("BAD REQUEST!"); http_not_found_response(accept_socket, &http_recv_info); } } } sClose(accept_socket); return; }