00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 package Acme.Serve;
00030
00031 import java.io.*;
00032 import java.util.*;
00033 import javax.servlet.*;
00034 import javax.servlet.http.*;
00035
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 public class CgiServlet extends HttpServlet
00050 {
00051
00053
00054 public String getServletInfo() {
00055 return "runs CGI programs";
00056 }
00057
00059
00060
00061
00062 public void service( HttpServletRequest req, HttpServletResponse res ) throws ServletException, IOException {
00063 if ( ! ( req.getMethod().equalsIgnoreCase( "get" ) ||
00064 req.getMethod().equalsIgnoreCase( "post" ) ) ) {
00065 res.sendError( HttpServletResponse.SC_NOT_IMPLEMENTED );
00066 return;
00067 }
00068 dispatchPathname( req, res,
00069 getServletContext().getRealPath(req.getServletPath() + req.getPathInfo()));
00070 }
00071
00072
00073 private void dispatchPathname( HttpServletRequest req, HttpServletResponse res, String path ) throws IOException {
00074 if ( new File( path ).exists() )
00075 serveFile( req, res, path );
00076 else
00077 res.sendError( HttpServletResponse.SC_NOT_FOUND );
00078 }
00079
00080
00081 private void serveFile( HttpServletRequest req, HttpServletResponse res, String path ) throws IOException
00082 {
00083 String queryString = req.getQueryString();
00084 int contentLength = req.getContentLength();
00085 int c;
00086
00087 log( "running " + path );
00088
00089
00090 Vector argVec = new Vector();
00091 argVec.addElement( path );
00092 if ( queryString != null && queryString.indexOf( "=" ) == -1 )
00093 {
00094 Enumeration enums = new StringTokenizer( queryString, "+" );
00095 while ( enums.hasMoreElements() )
00096 argVec.addElement( (String) enums.nextElement() );
00097 }
00098 String argList[] = makeList( argVec );
00099
00100
00101 Vector envVec = new Vector();
00102 envVec.addElement( makeEnv(
00103 "PATH", "/usr/local/bin:/usr/ucb:/bin:/usr/bin" ) );
00104 envVec.addElement( makeEnv( "GATEWAY_INTERFACE", "CGI/1.1" ) );
00105 envVec.addElement( makeEnv(
00106 "SERVER_SOFTWARE", getServletContext().getServerInfo() ) );
00107 envVec.addElement( makeEnv( "SERVER_NAME", req.getServerName() ) );
00108 envVec.addElement( makeEnv(
00109 "SERVER_PORT", Integer.toString( req.getServerPort() ) ) );
00110 envVec.addElement( makeEnv( "REMOTE_ADDR", req.getRemoteAddr() ) );
00111 envVec.addElement( makeEnv( "REMOTE_HOST", req.getRemoteHost() ) );
00112 envVec.addElement( makeEnv( "REQUEST_METHOD", req.getMethod() ) );
00113 if ( contentLength != -1 )
00114 envVec.addElement( makeEnv(
00115 "CONTENT_LENGTH", Integer.toString( contentLength ) ) );
00116 if ( req.getContentType() != null )
00117 envVec.addElement( makeEnv(
00118 "CONTENT_TYPE", req.getContentType() ) );
00119 envVec.addElement( makeEnv( "SCRIPT_NAME", req.getServletPath() ) );
00120 if ( req.getPathInfo() != null )
00121 envVec.addElement( makeEnv( "PATH_INFO", req.getPathInfo() ) );
00122 if ( req.getPathTranslated() != null )
00123 envVec.addElement( makeEnv(
00124 "PATH_TRANSLATED", req.getPathTranslated() ) );
00125 if ( queryString != null )
00126 envVec.addElement( makeEnv( "QUERY_STRING", queryString ) );
00127 envVec.addElement( makeEnv( "SERVER_PROTOCOL", req.getProtocol() ) );
00128 if ( req.getRemoteUser() != null )
00129 envVec.addElement( makeEnv( "REMOTE_USER", req.getRemoteUser() ) );
00130 if ( req.getAuthType() != null )
00131 envVec.addElement( makeEnv( "AUTH_TYPE", req.getAuthType() ) );
00132 Enumeration enums = req.getHeaderNames();
00133 while ( enums.hasMoreElements() )
00134 {
00135 String name = (String) enums.nextElement();
00136 String value = req.getHeader( name );
00137 if ( value == null )
00138 value = "";
00139 envVec.addElement( makeEnv(
00140 "HTTP_" + name.toUpperCase().replace( '-', '_' ), value ) );
00141 }
00142 String envList[] = makeList( envVec );
00143
00144
00145 Process proc = Runtime.getRuntime().exec( argList, envList );
00146
00147 try
00148 {
00149
00150 if ( req.getMethod().equalsIgnoreCase( "post" ) )
00151 {
00152 InputStream reqIn = req.getInputStream();
00153 OutputStream procOut = proc.getOutputStream();
00154 for ( int i = 0; i < contentLength; ++i )
00155 {
00156 c = reqIn.read();
00157 if ( c == -1 )
00158 break;
00159 procOut.write( c );
00160 }
00161 procOut.close();
00162 }
00163
00164
00165 BufferedReader procIn = new BufferedReader( new InputStreamReader(
00166 proc.getInputStream() ) );
00167 OutputStream resOut = res.getOutputStream();
00168
00169 boolean firstLine = true;
00170 while ( true )
00171 {
00172 String line = procIn.readLine();
00173 if ( line == null )
00174 break;
00175 line = line.trim();
00176 if ( line.equals( "" ) )
00177 break;
00178 int colon = line.indexOf( ":" );
00179 if ( colon == -1 )
00180 {
00181
00182 if ( firstLine )
00183 {
00184 StringTokenizer tok = new StringTokenizer( line, " " );
00185 try
00186 {
00187 switch( tok.countTokens() )
00188 {
00189 case 2:
00190 tok.nextToken();
00191 res.setStatus(
00192 Integer.parseInt( tok.nextToken() ) );
00193 break;
00194 case 3:
00195 tok.nextToken();
00196 res.setStatus(
00197 Integer.parseInt( tok.nextToken() ),
00198 tok.nextToken() );
00199 break;
00200 }
00201 }
00202 catch ( NumberFormatException ignore ) {}
00203 }
00204 else
00205 {
00206
00207 }
00208 }
00209 else
00210 {
00211
00212 String name = line.substring( 0, colon );
00213 String value = line.substring( colon + 1 ).trim();
00214 if ( name.equalsIgnoreCase( "Status" ) )
00215 {
00216 StringTokenizer tok = new StringTokenizer( value, " " );
00217 try
00218 {
00219 switch( tok.countTokens() )
00220 {
00221 case 1:
00222 res.setStatus(
00223 Integer.parseInt( tok.nextToken() ) );
00224 break;
00225 case 2:
00226 res.setStatus(
00227 Integer.parseInt( tok.nextToken() ),
00228 tok.nextToken() );
00229 break;
00230 }
00231 }
00232 catch ( NumberFormatException ignore ) {}
00233 }
00234 else if ( name.equalsIgnoreCase( "Content-type" ) )
00235 {
00236 res.setContentType( value );
00237 }
00238 else if ( name.equalsIgnoreCase( "Content-length" ) )
00239 {
00240 try
00241 {
00242 res.setContentLength( Integer.parseInt( value ) );
00243 }
00244 catch ( NumberFormatException ignore ) {}
00245 }
00246 else if ( name.equalsIgnoreCase( "Location" ) )
00247 {
00248 res.setStatus(
00249 HttpServletResponse.SC_MOVED_TEMPORARILY );
00250 res.setHeader( name, value );
00251 }
00252 else
00253 {
00254
00255 res.setHeader( name, value );
00256 }
00257 }
00258 }
00259
00260 Acme.Utils.copyStream( procIn, resOut );
00261 procIn.close();
00262 resOut.close();
00263 }
00264 catch ( IOException e )
00265 {
00266
00267
00268
00269 }
00270 }
00271
00272
00273 private static String makeEnv( String name, String value )
00274 {
00275 return name + "=" + value;
00276 }
00277
00278
00279 private static String[] makeList( Vector vec )
00280 {
00281 String list[] = new String[vec.size()];
00282 for ( int i = 0; i < vec.size(); ++i )
00283 list[i] = (String) vec.elementAt( i );
00284 return list;
00285 }
00286
00287 }