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 + -
显示快捷键?