001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.hayabusa.servlet; 017 018import java.io.FileInputStream; 019import java.io.IOException; 020import java.io.PrintWriter; 021import java.io.UnsupportedEncodingException; 022import java.util.Enumeration; 023import java.util.HashMap; 024 025import java.util.regex.Pattern; // 7.2.9.4 (2020/11/20) 026import java.util.regex.Matcher; // 7.2.9.4 (2020/11/20) 027 028import jakarta.servlet.ServletException; 029import jakarta.servlet.ServletConfig; // 7.2.9.4 (2020/11/20) 030import jakarta.servlet.ServletOutputStream; 031import jakarta.servlet.http.HttpServlet; 032import jakarta.servlet.http.HttpServletRequest; 033import jakarta.servlet.http.HttpServletResponse; 034 035import org.opengion.fukurou.system.Closer; 036import org.opengion.hayabusa.common.HybsSystem; 037import org.opengion.hayabusa.common.HybsSystemException; 038import org.opengion.hayabusa.remote.RemoteControllable; 039 040// import jakarta.servlet.annotation.WebInitParam; // 7.3.0.0 (2021/01/06) 041// import jakarta.servlet.annotation.WebServlet; // 7.3.0.0 (2021/01/06) 042 043/** 044 * 外部からキーと値を投げて処理をさせるサーブレットです。 045 * Post,Get両方に対応しています。 046 * classキーが必須です。(値はhayabusa/remote/内のクラス名) 047 * 048 * @og.rev 4.1.0.0 (2007/12/20) 新規作成 049 * @version 4.1 050 * @author Masakazu Takahashi 051 * @since JDK6.0, 052 * 053 */ 054/* 055@WebServlet( 056 urlPatterns = "/servlet/remoteControl" , 057 initParams = { 058 @WebInitParam(name="filePattern", value=".*opengionV8.*|c:[/\\]temp[/\\].*") 059 } 060) 061*/ 062public class RemoteControlServlet extends HttpServlet { 063 private static final long serialVersionUID = 542020111201L ; 064 private static final String REMOTE_PKG = "org.opengion.hayabusa.remote."; 065 066 private Pattern filePattern ; // 7.2.9.4 (2020/11/20) ファイルアクセスの制約(指定がない場合は、処理しない)。 067 068 /** 069 * デフォルトコンストラクター 070 * 071 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 072 */ 073 public RemoteControlServlet() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 074 075 /** 076 * Postメソッドで与えられたrequestをcallClassメソッドに渡します。 077 * callClassメソッドではclassパラメータの値を利用してクラスをロードし、処理を行います。 078 * 具体的な処理はcallClassメソッドをご覧下さい。 079 * 080 * @param request HttpServletRequestリクエスト 081 * @param response HttpServletResponseレスポンス 082 * @throws ServletException サーブレット関係のエラーが発生した場合、throw されます。 083 * @throws IOException 入出力エラーが発生したとき 084 */ 085 @Override 086 public void doPost( final HttpServletRequest request, final HttpServletResponse response ) throws ServletException, IOException { 087 callClass( request, response ); 088 } 089 090 /** 091 * Getメソッドで与えられたrequestをcallClassメソッドに渡します。 092 * callClassメソッドではclassパラメータの値を利用してクラスをロードし、処理を行います。 093 * 具体的な処理はcallClassメソッドをご覧下さい。 094 * 095 * @param request HttpServletRequestリクエスト 096 * @param response HttpServletResponseレスポンス 097 * @throws ServletException サーブレット関係のエラーが発生した場合、throw されます。 098 * @throws IOException 入出力エラーが発生したとき 099 */ 100 @Override 101 public void doGet( final HttpServletRequest request, final HttpServletResponse response ) throws ServletException, IOException { 102 callClass( request, response ); 103 } 104 105 /** 106 * Servlet の 初期値設定を行います。 107 * 108 * WEB-INF/web.xml ファイルで、<servlet> タグ内で初期値設定を行います。 109 * <init-param> 110 * <param-name>filePattern</param-name> 111 * <param-value>c:/opengionV8|c:/temp</param-value> 112 * </init-param> 113 * 114 * @og.rev 7.2.9.4 (2020/11/20) ファイルアクセスの制約(指定がない場合は、処理しない)。 115 * 116 * @param config ServletConfigオブジェクト 117 */ 118 @Override 119 public void init( final ServletConfig config ) throws ServletException { 120 super.init( config ); 121 122 final String filePtn = config.getInitParameter("filePattern"); 123 if( filePtn != null && !filePtn.isEmpty() ) { 124 filePattern = Pattern.compile( filePtn ); 125 } 126 } 127 128 /** 129 * POSTとGETに対する実際の処理です 130 * 必須パラメータclassで与えられたクラス名でorg.opengion.hayabusa.remoteから 131 * クラスをロードし、MAPに格納したrequestパラメータをそのクラスに対して渡します。 132 * ロードするクラスはRemoteControllableを実装している必要があります。 133 * ロードしたクラスの処理が終了すると、返されたStringをresponseに出力して終了します。 134 * なお、classパラメータがnullの場合は何もせずに終了します。 135 * 136 * @og.rev 5.4.2.0 (2011/12/01) フォワード対応 137 * @og.rev 7.2.9.4 (2020/11/20) ファイルアクセスの制約(指定がない場合は、処理しない)。 138 * 139 * @param request リクエスト 140 * @param response レスポンス 141 * @throws ServletException サーブレット関係のエラーが発生した場合、throw されます。 142 * @throws IOException 入出力エラーが発生したとき 143 */ 144 private void callClass( final HttpServletRequest request, final HttpServletResponse response ) throws ServletException, IOException { 145 // 5.4.2.0 (2011/12/01) リクエストのエンコードを指定 146 try { 147 request.setCharacterEncoding( "UTF-8" ); 148 } 149 catch( final UnsupportedEncodingException ex ) { 150 throw new HybsSystemException( ex ); 151 } 152 153 // 5.4.2.0 (2011/12/01) フォワード対応 154 // 7.2.9.4 (2020/11/20) ファイルアクセスの制約(指定がない場合は、処理しない)。 155 final String file = request.getParameter( "file" ); 156// if( file != null && file.length() > 0 ) { 157 if( file != null && !file.isEmpty() && filePattern != null ) { // 7.2.9.4 (2020/11/20) 158 final Matcher match = filePattern.matcher( file ); // 7.2.9.4 (2020/11/20) 159 if( match.matches() ) { // 7.2.9.4 (2020/11/20) 160 response.setContentType( "application/octet-stream" ); 161 // ファイル内容の出力 162 FileInputStream fin = null; 163 ServletOutputStream out = null; 164 try { 165 // 対応済み:spotbugs:サーブレットの絶対パストラバーサル 166 fin = new FileInputStream( file ); 167 out = response.getOutputStream(); 168 169 // ファイル読み込み用バッファ 170 final byte buffer[] = new byte[4096]; 171 int size; 172 while((size = fin.read(buffer))!=-1) { 173 out.write(buffer,0, size); 174 out.flush(); 175 } 176 } 177 finally { 178 Closer.ioClose( fin ); 179 Closer.ioClose( out ); 180 } 181 } 182 } 183 else { 184 final String clazz = request.getParameter( "class" ); // パラメータ"class"だけは必ず必要 185 186 if( clazz == null ) { 187 return; // 暫定処理 188 } 189 190 final Enumeration<?> paramEnm = request.getParameterNames(); // 4.3.3.6 (2008/11/15) Generics警告対応 191 final HashMap<String,String> paramMap = new HashMap<>(); 192 while( paramEnm.hasMoreElements() ) { 193 final String key = ( String )( paramEnm.nextElement() ); 194 paramMap.put( key, request.getParameter( key ) ); 195 } 196 197 final RemoteControllable rmtC = HybsSystem.newInstance( REMOTE_PKG + clazz ); 198 final String rtnString = rmtC.remoteControl( paramMap ); 199 response.setContentType( "text/xml; charset=UTF-8" ); 200 final PrintWriter out = response.getWriter(); 201 out.println( rtnString ); 202 out.flush(); 203 out.close(); 204 } 205 } 206}