mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-15 17:56:17 +01:00
rebuild cgi stack
This commit is contained in:
@@ -44,8 +44,8 @@ import sonia.scm.repository.HgRepositoryHandler;
|
|||||||
import sonia.scm.repository.Repository;
|
import sonia.scm.repository.Repository;
|
||||||
import sonia.scm.repository.RepositoryManager;
|
import sonia.scm.repository.RepositoryManager;
|
||||||
import sonia.scm.util.AssertUtil;
|
import sonia.scm.util.AssertUtil;
|
||||||
import sonia.scm.web.cgi.AbstractCGIServlet;
|
import sonia.scm.web.cgi.CGIExecutor;
|
||||||
import sonia.scm.web.cgi.EnvList;
|
import sonia.scm.web.cgi.CGIExecutorFactory;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
@@ -56,14 +56,16 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class HgCGIServlet extends AbstractCGIServlet
|
public class HgCGIServlet extends HttpServlet
|
||||||
{
|
{
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
@@ -90,16 +92,20 @@ public class HgCGIServlet extends AbstractCGIServlet
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* @param cgiExecutorFactory
|
||||||
* @param configuration
|
* @param configuration
|
||||||
* @param repositoryManager
|
* @param repositoryManager
|
||||||
* @param handler
|
* @param handler
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
public HgCGIServlet(ScmConfiguration configuration,
|
public HgCGIServlet(CGIExecutorFactory cgiExecutorFactory,
|
||||||
|
ScmConfiguration configuration,
|
||||||
RepositoryManager repositoryManager,
|
RepositoryManager repositoryManager,
|
||||||
HgRepositoryHandler handler)
|
HgRepositoryHandler handler)
|
||||||
{
|
{
|
||||||
super(configuration);
|
this.cgiExecutorFactory = cgiExecutorFactory;
|
||||||
|
this.configuration = configuration;
|
||||||
this.repositoryManager = repositoryManager;
|
this.repositoryManager = repositoryManager;
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
}
|
}
|
||||||
@@ -124,18 +130,16 @@ public class HgCGIServlet extends AbstractCGIServlet
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param request
|
* @param request
|
||||||
* @param baseEnvironment
|
* @param response
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
*
|
||||||
|
* @throws IOException
|
||||||
* @throws ServletException
|
* @throws ServletException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected EnvList createRequestEnvironment(HttpServletRequest request,
|
protected void service(HttpServletRequest request,
|
||||||
EnvList baseEnvironment)
|
HttpServletResponse response)
|
||||||
throws ServletException
|
throws ServletException, IOException
|
||||||
{
|
{
|
||||||
EnvList list = new EnvList(baseEnvironment);
|
|
||||||
Repository repository = getRepository(request);
|
Repository repository = getRepository(request);
|
||||||
|
|
||||||
if (repository == null)
|
if (repository == null)
|
||||||
@@ -145,10 +149,6 @@ public class HgCGIServlet extends AbstractCGIServlet
|
|||||||
|
|
||||||
String name = repository.getName();
|
String name = repository.getName();
|
||||||
File directory = handler.getDirectory(repository);
|
File directory = handler.getDirectory(repository);
|
||||||
|
|
||||||
list.set(ENV_REPOSITORY_PATH, directory.getAbsolutePath());
|
|
||||||
list.set(ENV_REPOSITORY_NAME, name);
|
|
||||||
|
|
||||||
String pythonPath = "";
|
String pythonPath = "";
|
||||||
HgConfig config = handler.getConfig();
|
HgConfig config = handler.getConfig();
|
||||||
|
|
||||||
@@ -162,9 +162,22 @@ public class HgCGIServlet extends AbstractCGIServlet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list.set(ENV_PYTHON_PATH, pythonPath);
|
CGIExecutor executor = cgiExecutorFactory.createExecutor(configuration,
|
||||||
|
getServletContext(), request, response);
|
||||||
|
|
||||||
return list;
|
executor.getEnvironment().set(ENV_REPOSITORY_NAME, name);
|
||||||
|
executor.getEnvironment().set(ENV_REPOSITORY_PATH,
|
||||||
|
directory.getAbsolutePath());
|
||||||
|
executor.getEnvironment().set(ENV_PYTHON_PATH, pythonPath);
|
||||||
|
|
||||||
|
String interpreter = getInterpreter();
|
||||||
|
|
||||||
|
if (interpreter != null)
|
||||||
|
{
|
||||||
|
executor.setInterpreter(interpreter);
|
||||||
|
}
|
||||||
|
|
||||||
|
executor.execute(command.getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
//~--- get methods ----------------------------------------------------------
|
||||||
@@ -175,8 +188,7 @@ public class HgCGIServlet extends AbstractCGIServlet
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
private String getInterpreter()
|
||||||
protected String getCmdPrefix()
|
|
||||||
{
|
{
|
||||||
HgConfig config = handler.getConfig();
|
HgConfig config = handler.getConfig();
|
||||||
|
|
||||||
@@ -192,24 +204,6 @@ public class HgCGIServlet extends AbstractCGIServlet
|
|||||||
return python;
|
return python;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param req
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws ServletException
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected File getCommand(HttpServletRequest req)
|
|
||||||
throws ServletException, IOException
|
|
||||||
{
|
|
||||||
return command;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
@@ -218,7 +212,7 @@ public class HgCGIServlet extends AbstractCGIServlet
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected Repository getRepository(HttpServletRequest request)
|
private Repository getRepository(HttpServletRequest request)
|
||||||
{
|
{
|
||||||
Repository repository = null;
|
Repository repository = null;
|
||||||
String uri = request.getRequestURI();
|
String uri = request.getRequestURI();
|
||||||
@@ -252,9 +246,15 @@ public class HgCGIServlet extends AbstractCGIServlet
|
|||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private CGIExecutorFactory cgiExecutorFactory;
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
private File command;
|
private File command;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private ScmConfiguration configuration;
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
private HgRepositoryHandler handler;
|
private HgRepositoryHandler handler;
|
||||||
|
|
||||||
|
|||||||
@@ -118,12 +118,14 @@ public class IOUtil
|
|||||||
*
|
*
|
||||||
* @param reader
|
* @param reader
|
||||||
* @param writer
|
* @param writer
|
||||||
|
* @param bufferSize
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static void copy(Reader reader, Writer writer) throws IOException
|
public static void copy(Reader reader, Writer writer, int bufferSize)
|
||||||
|
throws IOException
|
||||||
{
|
{
|
||||||
char[] buffer = new char[0xFFFF];
|
char[] buffer = new char[bufferSize];
|
||||||
|
|
||||||
for (int len; (len = reader.read(buffer)) != -1; )
|
for (int len; (len = reader.read(buffer)) != -1; )
|
||||||
{
|
{
|
||||||
@@ -131,6 +133,20 @@ public class IOUtil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param reader
|
||||||
|
* @param writer
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static void copy(Reader reader, Writer writer) throws IOException
|
||||||
|
{
|
||||||
|
copy(reader, writer, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
@@ -142,12 +158,30 @@ public class IOUtil
|
|||||||
*/
|
*/
|
||||||
public static void copy(InputStream in, OutputStream out) throws IOException
|
public static void copy(InputStream in, OutputStream out) throws IOException
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[0xFFFF];
|
copy(in, out, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param in
|
||||||
|
* @param out
|
||||||
|
* @param bufferSize
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static void copy(InputStream in, OutputStream out, int bufferSize)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[bufferSize];
|
||||||
|
|
||||||
for (int len; (len = in.read(buffer)) != -1; )
|
for (int len; (len = in.read(buffer)) != -1; )
|
||||||
{
|
{
|
||||||
out.write(buffer, 0, len);
|
out.write(buffer, 0, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,158 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.web.cgi;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
public abstract class AbstractCGIExecutor implements CGIExecutor
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getBufferSize()
|
||||||
|
{
|
||||||
|
return bufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public EnvList getEnvironment()
|
||||||
|
{
|
||||||
|
return environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getInterpreter()
|
||||||
|
{
|
||||||
|
return interpreter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public File getWorkDirectory()
|
||||||
|
{
|
||||||
|
return workDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- set methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param bufferSize
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setBufferSize(int bufferSize)
|
||||||
|
{
|
||||||
|
this.bufferSize = bufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param environment
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setEnvironment(EnvList environment)
|
||||||
|
{
|
||||||
|
this.environment = environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param interpreter
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setInterpreter(String interpreter)
|
||||||
|
{
|
||||||
|
this.interpreter = interpreter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param workDirectory
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setWorkDirectory(File workDirectory)
|
||||||
|
{
|
||||||
|
this.workDirectory = workDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
protected int bufferSize;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
protected EnvList environment;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
protected String interpreter;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
protected File workDirectory;
|
||||||
|
}
|
||||||
@@ -53,7 +53,9 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
|
* @deprecated use {@link CGIExecutorFactory}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public abstract class AbstractCGIServlet extends HttpServlet
|
public abstract class AbstractCGIServlet extends HttpServlet
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
202
scm-core/src/main/java/sonia/scm/web/cgi/CGIExecutor.java
Normal file
202
scm-core/src/main/java/sonia/scm/web/cgi/CGIExecutor.java
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.web.cgi;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
public interface CGIExecutor
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_AUTH_TYPE = "AUTH_TYPE";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_CONTENT_LENGTH = "CONTENT_LENGTH";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_CONTENT_TYPE = "CONTENT_TYPE";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_GATEWAY_INTERFACE = "GATEWAY_INTERFACE";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_HTTPS = "HTTPS";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_HTTPS_VALUE_OFF = "OFF";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_HTTPS_VALUE_ON = "ON";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_HTTP_HEADER_PREFIX = "HTTP_";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_PATH_INFO = "PATH_INFO";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_PATH_TRANSLATED = "PATH_TRANSLATED";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_QUERY_STRING = "QUERY_STRING";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_REMOTE_ADDR = "REMOTE_ADDR";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_REMOTE_HOST = "REMOTE_HOST";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_REMOTE_USER = "REMOTE_USER";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_REQUEST_METHOD = "REQUEST_METHOD";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_SCRIPT_FILENAME = "SCRIPT_FILENAME";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_SCRIPT_NAME = "SCRIPT_NAME";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_SERVER_NAME = "SERVER_NAME";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_SERVER_PORT = "SERVER_PORT";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_SERVER_PROTOCOL = "SERVER_PROTOCOL";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_SERVER_SOFTWARE = "SERVER_SOFTWARE";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String RESPONSE_HEADER_HTTP_PREFIX = "HTTP";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String RESPONSE_HEADER_LOCATION = "Location";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String RESPONSE_HEADER_STATUS = "Status";
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param cmd
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* @throws ServletException
|
||||||
|
*/
|
||||||
|
public void execute(String cmd) throws IOException, ServletException;
|
||||||
|
|
||||||
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getBufferSize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public EnvList getEnvironment();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getInterpreter();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public File getWorkDirectory();
|
||||||
|
|
||||||
|
//~--- set methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param bufferSize
|
||||||
|
*/
|
||||||
|
public void setBufferSize(int bufferSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param environment
|
||||||
|
*/
|
||||||
|
public void setEnvironment(EnvList environment);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param interpreter
|
||||||
|
*/
|
||||||
|
public void setInterpreter(String interpreter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param workDirectory
|
||||||
|
*/
|
||||||
|
public void setWorkDirectory(File workDirectory);
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.web.cgi;
|
||||||
|
|
||||||
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import sonia.scm.config.ScmConfiguration;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
public interface CGIExecutorFactory
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param configuration
|
||||||
|
* @param context
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public CGIExecutor createExecutor(ScmConfiguration configuration,
|
||||||
|
ServletContext context,
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response);
|
||||||
|
}
|
||||||
@@ -59,8 +59,9 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
* Based on org.eclipse.jetty.servlets.CGI
|
* Based on org.eclipse.jetty.servlets.CGI
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
*
|
* @deprecated use {@link CGIExecutorFactory}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class CGIRunner
|
public class CGIRunner
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -334,12 +335,8 @@ public class CGIRunner
|
|||||||
logger.debug("CGI: interrupted!");
|
logger.debug("CGI: interrupted!");
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
|
||||||
if (os != null)
|
|
||||||
{
|
{
|
||||||
IOUtil.close(os);
|
IOUtil.close(os);
|
||||||
}
|
|
||||||
|
|
||||||
os = null;
|
os = null;
|
||||||
p.destroy();
|
p.destroy();
|
||||||
|
|
||||||
|
|||||||
@@ -278,7 +278,7 @@
|
|||||||
<aether.version>1.11</aether.version>
|
<aether.version>1.11</aether.version>
|
||||||
<wagon.version>1.0-beta-7</wagon.version>
|
<wagon.version>1.0-beta-7</wagon.version>
|
||||||
<maven.version>3.0.3</maven.version>
|
<maven.version>3.0.3</maven.version>
|
||||||
<netbeans.hint.deploy.server>Tomcat60</netbeans.hint.deploy.server>
|
<netbeans.hint.deploy.server>gfv3ee6</netbeans.hint.deploy.server>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ import sonia.scm.template.TemplateServlet;
|
|||||||
import sonia.scm.user.UserManager;
|
import sonia.scm.user.UserManager;
|
||||||
import sonia.scm.user.xml.XmlUserManager;
|
import sonia.scm.user.xml.XmlUserManager;
|
||||||
import sonia.scm.util.DebugServlet;
|
import sonia.scm.util.DebugServlet;
|
||||||
|
import sonia.scm.web.cgi.CGIExecutorFactory;
|
||||||
|
import sonia.scm.web.cgi.DefaultCGIExecutorFactory;
|
||||||
import sonia.scm.web.security.AuthenticationManager;
|
import sonia.scm.web.security.AuthenticationManager;
|
||||||
import sonia.scm.web.security.BasicSecurityContext;
|
import sonia.scm.web.security.BasicSecurityContext;
|
||||||
import sonia.scm.web.security.ChainAuthenticatonManager;
|
import sonia.scm.web.security.ChainAuthenticatonManager;
|
||||||
@@ -215,8 +217,9 @@ public class ScmServletModule extends ServletModule
|
|||||||
bind(RepositoryManager.class).to(XmlRepositoryManager.class);
|
bind(RepositoryManager.class).to(XmlRepositoryManager.class);
|
||||||
bind(UserManager.class).to(XmlUserManager.class);
|
bind(UserManager.class).to(XmlUserManager.class);
|
||||||
bind(GroupManager.class).to(XmlGroupManager.class);
|
bind(GroupManager.class).to(XmlGroupManager.class);
|
||||||
|
bind(CGIExecutorFactory.class).to(DefaultCGIExecutorFactory.class);
|
||||||
|
|
||||||
// filter(PATTERN_RESTAPI).through(LoggingFilter.class);
|
// filter("/hg/*").through(LoggingFilter.class);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* filter(PATTERN_PAGE,
|
* filter(PATTERN_PAGE,
|
||||||
|
|||||||
@@ -0,0 +1,487 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.web.cgi;
|
||||||
|
|
||||||
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import sonia.scm.SCMContext;
|
||||||
|
import sonia.scm.config.ScmConfiguration;
|
||||||
|
import sonia.scm.util.HttpUtil;
|
||||||
|
import sonia.scm.util.IOUtil;
|
||||||
|
import sonia.scm.util.Util;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import java.util.Enumeration;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletInputStream;
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
public class DefaultCGIExecutor extends AbstractCGIExecutor
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String CGI_VERSION = "CGI/1.1";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final int DEFAULT_BUFFER_SIZE = 16264;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private static final String SERVER_SOFTWARE_PREFIX = "scm-manager/";
|
||||||
|
|
||||||
|
/** the logger for DefaultCGIExecutor */
|
||||||
|
private static final Logger logger =
|
||||||
|
LoggerFactory.getLogger(DefaultCGIExecutor.class);
|
||||||
|
|
||||||
|
//~--- constructors ---------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs ...
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param configuration
|
||||||
|
* @param context
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
*/
|
||||||
|
public DefaultCGIExecutor(ScmConfiguration configuration,
|
||||||
|
ServletContext context, HttpServletRequest request,
|
||||||
|
HttpServletResponse response)
|
||||||
|
{
|
||||||
|
this.configuration = configuration;
|
||||||
|
this.context = context;
|
||||||
|
this.request = request;
|
||||||
|
this.response = response;
|
||||||
|
|
||||||
|
// set default values
|
||||||
|
this.bufferSize = DEFAULT_BUFFER_SIZE;
|
||||||
|
this.environment = createEnvironment();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param cmd
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void execute(String cmd) throws IOException
|
||||||
|
{
|
||||||
|
File command = new File(cmd);
|
||||||
|
EnvList env = new EnvList(environment);
|
||||||
|
|
||||||
|
if (workDirectory == null)
|
||||||
|
{
|
||||||
|
workDirectory = command.getParentFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
String path = command.getAbsolutePath();
|
||||||
|
String pathTranslated = request.getPathTranslated();
|
||||||
|
|
||||||
|
if (Util.isEmpty(pathTranslated))
|
||||||
|
{
|
||||||
|
pathTranslated = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
env.set(ENV_PATH_TRANSLATED, pathTranslated);
|
||||||
|
|
||||||
|
String execCmd = path;
|
||||||
|
|
||||||
|
if ((execCmd.charAt(0) != '"') && (execCmd.indexOf(" ") >= 0))
|
||||||
|
{
|
||||||
|
execCmd = "\"" + execCmd + "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interpreter != null)
|
||||||
|
{
|
||||||
|
execCmd = interpreter + " " + execCmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("execute cgi: {}", execCmd);
|
||||||
|
|
||||||
|
if (logger.isTraceEnabled())
|
||||||
|
{
|
||||||
|
logger.trace(environment.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process p = Runtime.getRuntime().exec(execCmd, environment.getEnvArray(),
|
||||||
|
workDirectory);
|
||||||
|
|
||||||
|
execute(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private EnvList createEnvironment()
|
||||||
|
{
|
||||||
|
String pathInfo = request.getPathInfo();
|
||||||
|
int serverPort = HttpUtil.getServerPort(configuration, request);
|
||||||
|
String scriptName = request.getRequestURI().substring(0,
|
||||||
|
request.getRequestURI().length() - pathInfo.length());
|
||||||
|
String scriptPath = context.getRealPath(scriptName);
|
||||||
|
int len = request.getContentLength();
|
||||||
|
|
||||||
|
if (len < 0)
|
||||||
|
{
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnvList env = new EnvList();
|
||||||
|
|
||||||
|
env.set(ENV_AUTH_TYPE, request.getAuthType());
|
||||||
|
env.set(ENV_CONTENT_LENGTH, Integer.toString(len));
|
||||||
|
env.set(ENV_CONTENT_TYPE, request.getContentType());
|
||||||
|
env.set(ENV_GATEWAY_INTERFACE, CGI_VERSION);
|
||||||
|
env.set(ENV_PATH_INFO, pathInfo);
|
||||||
|
env.set(ENV_QUERY_STRING, request.getQueryString());
|
||||||
|
env.set(ENV_REMOTE_ADDR, request.getRemoteAddr());
|
||||||
|
env.set(ENV_REMOTE_HOST, request.getRemoteHost());
|
||||||
|
|
||||||
|
// The identity information reported about the connection by a
|
||||||
|
// RFC 1413 [11] request to the remote agent, if
|
||||||
|
// available. Servers MAY choose not to support this feature, or
|
||||||
|
// not to request the data for efficiency reasons.
|
||||||
|
// "REMOTE_IDENT" => "NYI"
|
||||||
|
env.set(ENV_REMOTE_USER, request.getRemoteUser());
|
||||||
|
env.set(ENV_REQUEST_METHOD, request.getMethod());
|
||||||
|
env.set(ENV_SCRIPT_NAME, scriptName);
|
||||||
|
env.set(ENV_SCRIPT_FILENAME, scriptPath);
|
||||||
|
env.set(ENV_SERVER_NAME, request.getServerName());
|
||||||
|
env.set(ENV_SERVER_PORT, Integer.toString(serverPort));
|
||||||
|
env.set(ENV_SERVER_PROTOCOL, request.getProtocol());
|
||||||
|
env.set(
|
||||||
|
ENV_SERVER_SOFTWARE,
|
||||||
|
SERVER_SOFTWARE_PREFIX.concat(SCMContext.getContext().getVersion()));
|
||||||
|
|
||||||
|
Enumeration enm = request.getHeaderNames();
|
||||||
|
|
||||||
|
while (enm.hasMoreElements())
|
||||||
|
{
|
||||||
|
String name = (String) enm.nextElement();
|
||||||
|
String value = request.getHeader(name);
|
||||||
|
|
||||||
|
env.set(ENV_HTTP_HEADER_PREFIX + name.toUpperCase().replace('-', '_'),
|
||||||
|
value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// these extra ones were from printenv on www.dev.nomura.co.uk
|
||||||
|
env.set(ENV_HTTPS, (request.isSecure()
|
||||||
|
? ENV_HTTPS_VALUE_ON
|
||||||
|
: ENV_HTTPS_VALUE_OFF));
|
||||||
|
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param process
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void execute(Process process) throws IOException
|
||||||
|
{
|
||||||
|
InputStream processIS = null;
|
||||||
|
InputStream processES = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
processIS = process.getInputStream();
|
||||||
|
processES = process.getErrorStream();
|
||||||
|
processServletInput(process);
|
||||||
|
processProcessInputStream(processIS);
|
||||||
|
processErrorStream(processES);
|
||||||
|
waitForFinish(process);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IOUtil.close(processIS);
|
||||||
|
IOUtil.close(processES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param is
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void parseHeaders(InputStream is) throws IOException
|
||||||
|
{
|
||||||
|
String line = null;
|
||||||
|
|
||||||
|
while ((line = getTextLineFromStream(is)).length() > 0)
|
||||||
|
{
|
||||||
|
if (logger.isTraceEnabled())
|
||||||
|
{
|
||||||
|
logger.trace(" ".concat(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!line.startsWith(RESPONSE_HEADER_HTTP_PREFIX))
|
||||||
|
{
|
||||||
|
int k = line.indexOf(':');
|
||||||
|
|
||||||
|
if (k > 0)
|
||||||
|
{
|
||||||
|
String key = line.substring(0, k).trim();
|
||||||
|
String value = line.substring(k + 1).trim();
|
||||||
|
|
||||||
|
if (RESPONSE_HEADER_LOCATION.equals(key))
|
||||||
|
{
|
||||||
|
response.sendRedirect(response.encodeRedirectURL(value));
|
||||||
|
}
|
||||||
|
else if (RESPONSE_HEADER_STATUS.equals(key))
|
||||||
|
{
|
||||||
|
String[] token = value.split(" ");
|
||||||
|
int status = Integer.parseInt(token[0]);
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("CGI returned with status {}", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status < 304)
|
||||||
|
{
|
||||||
|
response.setStatus(status);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response.sendError(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
// add remaining header items to our response header
|
||||||
|
response.addHeader(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param in
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void processErrorStream(InputStream in) throws IOException
|
||||||
|
{
|
||||||
|
BufferedReader reader = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
reader = new BufferedReader(new InputStreamReader(in));
|
||||||
|
|
||||||
|
StringBuilder error = new StringBuilder();
|
||||||
|
String s = System.getProperty("line.separator");
|
||||||
|
String line = reader.readLine();
|
||||||
|
|
||||||
|
while (line != null)
|
||||||
|
{
|
||||||
|
error.append(line);
|
||||||
|
line = reader.readLine();
|
||||||
|
|
||||||
|
if (line != null)
|
||||||
|
{
|
||||||
|
error.append(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logger.isWarnEnabled())
|
||||||
|
{
|
||||||
|
logger.warn(error.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IOUtil.close(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param is
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void processProcessInputStream(InputStream is) throws IOException
|
||||||
|
{
|
||||||
|
parseHeaders(is);
|
||||||
|
|
||||||
|
ServletOutputStream servletOS = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
servletOS = response.getOutputStream();
|
||||||
|
IOUtil.copy(is, servletOS, bufferSize);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IOUtil.close(servletOS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param process
|
||||||
|
*/
|
||||||
|
private void processServletInput(Process process)
|
||||||
|
{
|
||||||
|
OutputStream processOS = null;
|
||||||
|
ServletInputStream servletIS = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
processOS = process.getOutputStream();
|
||||||
|
servletIS = request.getInputStream();
|
||||||
|
IOUtil.copy(servletIS, processOS, bufferSize);
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
logger.error(
|
||||||
|
"could not read from ServletInputStream and write to ProcessOutputStream",
|
||||||
|
ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IOUtil.close(processOS);
|
||||||
|
IOUtil.close(servletIS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param process
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void waitForFinish(Process process)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int exitCode = process.waitFor();
|
||||||
|
|
||||||
|
if (exitCode != 0)
|
||||||
|
{
|
||||||
|
logger.warn("process ends with exit code {}", exitCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (InterruptedException ex)
|
||||||
|
{
|
||||||
|
logger.error("process interrupted", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param is
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private String getTextLineFromStream(InputStream is) throws IOException
|
||||||
|
{
|
||||||
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
int b;
|
||||||
|
|
||||||
|
while ((b = is.read()) != -1 && (b != (int) '\n'))
|
||||||
|
{
|
||||||
|
buffer.append((char) b);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.toString().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private ScmConfiguration configuration;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private ServletContext context;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private HttpServletRequest request;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private HttpServletResponse response;
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.web.cgi;
|
||||||
|
|
||||||
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import sonia.scm.config.ScmConfiguration;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
public class DefaultCGIExecutorFactory implements CGIExecutorFactory
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param configuration
|
||||||
|
* @param context
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CGIExecutor createExecutor(ScmConfiguration configuration,
|
||||||
|
ServletContext context,
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response)
|
||||||
|
{
|
||||||
|
return new DefaultCGIExecutor(configuration, context, request, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user