cgiservlet.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 622 行 · 第 1/2 页

JAVA
622
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.servlets;import com.caucho.log.Log;import com.caucho.util.Alarm;import com.caucho.util.AlarmListener;import com.caucho.util.CharBuffer;import com.caucho.util.L10N;import com.caucho.vfs.Path;import com.caucho.vfs.ReadStream;import com.caucho.vfs.TempBuffer;import com.caucho.vfs.Vfs;import javax.servlet.GenericServlet;import javax.servlet.ServletException;import javax.servlet.ServletInputStream;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.ArrayList;import java.util.Enumeration;import java.util.logging.Level;import java.util.logging.Logger;/** * CGI */public class CGIServlet extends GenericServlet {  static protected final Logger log = Log.open(CGIServlet.class);  static final L10N L = new L10N(CGIServlet.class);  private static String REQUEST_URI = "javax.servlet.include.request_uri";  private static String CONTEXT_PATH = "javax.servlet.include.context_path";  private static String SERVLET_PATH = "javax.servlet.include.servlet_path";  private static String PATH_INFO = "javax.servlet.include.path_info";  private static String QUERY_STRING = "javax.servlet.include.query_string";  private String _executable;  private boolean _stderrIsException = true;  private boolean _ignoreExitCode = false;  /**   * Sets an executable to run the script.   */  public void setExecutable(String executable)  {    _executable = executable;  }  public void setStderrIsException(boolean isException)  {    _stderrIsException = isException;  }  /**   * If true, do not treat a non-zero exit code as an error, default false.   */  public void setIgnoreExitCode(boolean ignoreExitCode)  {    _ignoreExitCode = ignoreExitCode;  }  /**   * Handle the request.   */  public void service(ServletRequest request, ServletResponse response)    throws ServletException, IOException  {    HttpServletRequest req = (HttpServletRequest) request;    HttpServletResponse res = (HttpServletResponse) response;    String requestURI;    String contextPath;    String servletPath;    String servletPathInfo;    String queryString;    requestURI = (String) req.getAttribute(REQUEST_URI);    if (requestURI != null) {      contextPath = (String) req.getAttribute(CONTEXT_PATH);      servletPath = (String) req.getAttribute(SERVLET_PATH);      servletPathInfo = (String) req.getAttribute(PATH_INFO);      queryString = (String) req.getAttribute(QUERY_STRING);    }    else {      requestURI = req.getRequestURI();      contextPath = req.getContextPath();      servletPath = req.getServletPath();      servletPathInfo = req.getPathInfo();      queryString = req.getQueryString();    }    String scriptPath;    String pathInfo;    if (servletPathInfo == null) {      scriptPath = servletPath;      pathInfo = null;    }    else {      String fullPath = servletPath + servletPathInfo;      int i = findScriptPathIndex(req, fullPath);      if (i < 0) {        if (log.isLoggable(Level.FINE))          log.fine(L.l("no script path index for `{0}'", fullPath));        res.sendError(res.SC_NOT_FOUND);        return;      }      scriptPath = fullPath.substring(0, i);      pathInfo = fullPath.substring(i);      if ("".equals(pathInfo))	pathInfo = null;    }    String realPath = req.getRealPath(scriptPath);    Path vfsPath = Vfs.lookup(realPath);    if (! vfsPath.canRead() || vfsPath.isDirectory()) {      if (log.isLoggable(Level.FINE))        log.fine(L.l("script `{0}' is unreadable", vfsPath));      res.sendError(res.SC_NOT_FOUND);      return;    }    String []env = createEnvironment(req, requestURI, contextPath,                                     scriptPath, pathInfo, queryString);    String []args = getArgs(realPath);    if (log.isLoggable(Level.FINER)) {      if (args.length > 1)	log.finer("[cgi] exec " + args[0] + " " + args[1]);      else if (args.length > 0)	log.finer("[cgi] exec " + args[0]);    }    Runtime runtime = Runtime.getRuntime();    Process process = null;    Alarm alarm = null;    try {      File dir = new File(Vfs.lookup(realPath).getParent().getNativePath());      if (log.isLoggable(Level.FINE)) {        CharBuffer argsBuf = new CharBuffer();        argsBuf.append('[');        for (String arg : args) {          if (argsBuf.length() > 1)            argsBuf.append(", ");          argsBuf.append('"');          argsBuf.append(arg);          argsBuf.append('"');        }        argsBuf.append(']');        log.fine(L.l("exec {0} (pwd={1})", argsBuf, dir));        if (log.isLoggable(Level.FINEST)) {          for (String envElement : env)            log.finest(envElement);        }      }      process = runtime.exec(args, env, dir);      InputStream inputStream = process.getInputStream();      InputStream errorStream = process.getErrorStream();      TimeoutAlarm timeout;      timeout = new TimeoutAlarm(requestURI, process, inputStream);      alarm = new Alarm(timeout, 360 * 1000);      OutputStream outputStream = process.getOutputStream();      TempBuffer tempBuf = TempBuffer.allocate();      byte []buf = tempBuf.getBuffer();            try {	ServletInputStream sis = req.getInputStream();	int len;	while ((len = sis.read(buf, 0, buf.length)) > 0) {	  outputStream.write(buf, 0, len);	}	outputStream.flush();      } catch (IOException e) {	log.log(Level.FINER, e.toString(), e);      } finally {	outputStream.close();      }            TempBuffer.free(tempBuf);      tempBuf = null;      ReadStream rs = Vfs.openRead(inputStream);      boolean hasStatus = false;      try {	hasStatus = parseHeaders(req, res, rs);	OutputStream out = res.getOutputStream();	rs.writeToStream(out);      } finally {	try {	  rs.close();	} catch (Throwable e) {	  log.log(Level.FINER, e.toString(), e);	}	inputStream.close();      }      StringBuilder error = new StringBuilder();      boolean hasContent = false;      int ch;      while (errorStream.available() > 0 && (ch = errorStream.read()) > 0) {	error.append((char) ch);	if (! Character.isWhitespace((char) ch))	  hasContent = true;      }      errorStream.close();      if (hasContent) {	String errorString = error.toString();	log.warning(errorString);	if (! hasStatus && _stderrIsException)	  throw new ServletException(errorString);      }      int exitCode = process.waitFor();      if (exitCode != 0) {        if (hasStatus) {          if (log.isLoggable(Level.FINER))            log.finer(L.l("exit code {0} (ignored, hasStatus)", exitCode));        }        else if (_ignoreExitCode) {          if (log.isLoggable(Level.FINER))            log.finer(L.l("exit code {0} (ignored)", exitCode));        }        else	  throw new ServletException(L.l("CGI execution failed.  Exit code {0}",				         exitCode));      }    } catch (IOException e) {      throw e;    } catch (ServletException e) {      throw e;    } catch (Exception e) {      throw new ServletException(e);    } finally {      if (alarm != null)	alarm.dequeue();      try {	process.destroy();      } catch (Throwable e) {      }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?