improve GitCGIServlet

This commit is contained in:
Sebastian Sdorra
2010-10-12 14:56:29 +02:00
parent 030b2e8db0
commit 9396e9e86a
6 changed files with 144 additions and 72 deletions

View File

@@ -30,6 +30,17 @@ public class GitConfig extends SimpleRepositoryConfig
return gitBinary; return gitBinary;
} }
/**
* Method description
*
*
* @return
*/
public String getGitHttpBackend()
{
return gitHttpBackend;
}
//~--- set methods ---------------------------------------------------------- //~--- set methods ----------------------------------------------------------
/** /**
@@ -43,8 +54,22 @@ public class GitConfig extends SimpleRepositoryConfig
this.gitBinary = gitBinary; this.gitBinary = gitBinary;
} }
/**
* Method description
*
*
* @param gitHttpBackend
*/
public void setGitHttpBackend(String gitHttpBackend)
{
this.gitHttpBackend = gitHttpBackend;
}
//~--- fields --------------------------------------------------------------- //~--- fields ---------------------------------------------------------------
/** Field description */ /** Field description */
private String gitBinary = "git"; private String gitBinary = "git";
/** Field description */
private String gitHttpBackend = "git-http-backend";
} }

View File

@@ -9,8 +9,11 @@ package sonia.scm.web;
//~--- non-JDK imports -------------------------------------------------------- //~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import sonia.scm.repository.GitConfig;
import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.web.cgi.AbstractCGIServlet; import sonia.scm.web.cgi.AbstractCGIServlet;
import sonia.scm.web.cgi.EnvList; import sonia.scm.web.cgi.EnvList;
@@ -46,18 +49,47 @@ public class GitCGIServlet extends AbstractCGIServlet
* *
* *
* @return * @return
*
* @throws ServletException
*/ */
@Override @Override
protected EnvList createEnvironment() protected EnvList createBaseEnvironment() throws ServletException
{ {
EnvList list = super.createEnvironment(); EnvList list = super.createBaseEnvironment();
list.set(ENV_PROJECT_ROOT, "/tmp/git");
list.set(ENV_HTTP_EXPORT_ALL, ""); list.set(ENV_HTTP_EXPORT_ALL, "");
return list; return list;
} }
/**
* Method description
*
*
* @param baseEnvironment
*
* @return
*
* @throws ServletException
*/
@Override
protected EnvList createRequestEnvironment(EnvList baseEnvironment)
throws ServletException
{
GitConfig config = repositoryHandler.getConfig();
if (config == null)
{
throw new ServletException("git is not configured");
}
EnvList env = new EnvList(baseEnvironment);
env.set(ENV_PROJECT_ROOT, config.getRepositoryDirectory().getPath());
return env;
}
//~--- get methods ---------------------------------------------------------- //~--- get methods ----------------------------------------------------------
/** /**
@@ -75,6 +107,19 @@ public class GitCGIServlet extends AbstractCGIServlet
protected File getCommand(HttpServletRequest req) protected File getCommand(HttpServletRequest req)
throws ServletException, IOException throws ServletException, IOException
{ {
return new File("/opt/local/libexec/git-core/git-http-backend/"); GitConfig config = repositoryHandler.getConfig();
if (config == null)
{
throw new ServletException("git is not configured");
}
return new File(config.getGitHttpBackend());
} }
//~--- fields ---------------------------------------------------------------
/** Field description */
@Inject
private GitRepositoryHandler repositoryHandler;
} }

View File

@@ -20,6 +20,11 @@ registerConfigPanel({
name: 'baseUrl', name: 'baseUrl',
fieldLabel: 'Base URL', fieldLabel: 'Base URL',
allowBlank : false allowBlank : false
},{
xtype : 'textfield',
fieldLabel : 'Git-Http-Backend',
name : 'gitHttpBackend',
allowBlank : false
}], }],
onSubmit: function(values){ onSubmit: function(values){

View File

@@ -56,8 +56,9 @@ public abstract class AbstractCGIServlet extends HttpServlet
@Override @Override
public void init() throws ServletException public void init() throws ServletException
{ {
cgiRunner = new CGIRunner(getServletContext(), createEnvironment(), cgiRunner = new CGIRunner(getServletContext(), getCmdPrefix(),
getCmdPrefix(), isExitStateIgnored()); isExitStateIgnored());
baseEnvironment = createBaseEnvironment();
} }
/** /**
@@ -65,8 +66,10 @@ public abstract class AbstractCGIServlet extends HttpServlet
* *
* *
* @return * @return
*
* @throws ServletException
*/ */
protected EnvList createEnvironment() protected EnvList createBaseEnvironment() throws ServletException
{ {
EnvList env = new EnvList(); EnvList env = new EnvList();
Enumeration e = getInitParameterNames(); Enumeration e = getInitParameterNames();
@@ -94,6 +97,22 @@ public abstract class AbstractCGIServlet extends HttpServlet
return env; return env;
} }
/**
* Method description
*
*
* @param baseEnvironment
*
* @return
*
* @throws ServletException
*/
protected EnvList createRequestEnvironment(EnvList baseEnvironment)
throws ServletException
{
return new EnvList(baseEnvironment);
}
/** /**
* Method description * Method description
* *
@@ -108,7 +127,8 @@ public abstract class AbstractCGIServlet extends HttpServlet
protected void service(HttpServletRequest req, HttpServletResponse resp) protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException throws ServletException, IOException
{ {
cgiRunner.exec(getCommand(req), req.getPathInfo(), req, resp); cgiRunner.exec(createRequestEnvironment(baseEnvironment), getCommand(req),
req.getPathInfo(), req, resp);
} }
//~--- get methods ---------------------------------------------------------- //~--- get methods ----------------------------------------------------------
@@ -124,10 +144,6 @@ public abstract class AbstractCGIServlet extends HttpServlet
return null; return null;
} }
;
//~--- get methods ----------------------------------------------------------
/** /**
* Method description * Method description
* *
@@ -139,10 +155,11 @@ public abstract class AbstractCGIServlet extends HttpServlet
return false; return false;
} }
;
//~--- fields --------------------------------------------------------------- //~--- fields ---------------------------------------------------------------
/** Field description */
private EnvList baseEnvironment;
/** Field description */ /** Field description */
private CGIRunner cgiRunner; private CGIRunner cgiRunner;
} }

View File

@@ -55,11 +55,10 @@ public class CGIRunner
* @param cmdPrefix * @param cmdPrefix
* @param ignoreExitState * @param ignoreExitState
*/ */
public CGIRunner(ServletContext context, EnvList environment, public CGIRunner(ServletContext context,
String cmdPrefix, boolean ignoreExitState) String cmdPrefix, boolean ignoreExitState)
{ {
this.context = context; this.context = context;
this.environment = environment;
this.cmdPrefix = cmdPrefix; this.cmdPrefix = cmdPrefix;
this.ignoreExitState = ignoreExitState; this.ignoreExitState = ignoreExitState;
} }
@@ -77,7 +76,7 @@ public class CGIRunner
* *
* @throws IOException * @throws IOException
*/ */
public void exec(File command, String pathInfo, HttpServletRequest req, public void exec(EnvList environment, File command, String pathInfo, HttpServletRequest req,
HttpServletResponse res) HttpServletResponse res)
throws IOException throws IOException
{ {
@@ -99,39 +98,37 @@ public class CGIRunner
pathTranslated = path; pathTranslated = path;
} }
EnvList env = new EnvList(environment);
// these ones are from "The WWW Common Gateway Interface Version 1.1" // these ones are from "The WWW Common Gateway Interface Version 1.1"
// look at : // look at :
// http://Web.Golux.Com/coar/cgi/draft-coar-cgi-v11-03-clean.html#6.1.1 // http://Web.Golux.Com/coar/cgi/draft-coar-cgi-v11-03-clean.html#6.1.1
env.set("AUTH_TYPE", req.getAuthType()); environment.set("AUTH_TYPE", req.getAuthType());
env.set("CONTENT_LENGTH", Integer.toString(len)); environment.set("CONTENT_LENGTH", Integer.toString(len));
env.set("CONTENT_TYPE", req.getContentType()); environment.set("CONTENT_TYPE", req.getContentType());
env.set("GATEWAY_INTERFACE", "CGI/1.1"); environment.set("GATEWAY_INTERFACE", "CGI/1.1");
if ((pathInfo != null) && (pathInfo.length() > 0)) if ((pathInfo != null) && (pathInfo.length() > 0))
{ {
env.set("PATH_INFO", pathInfo); environment.set("PATH_INFO", pathInfo);
} }
env.set("PATH_TRANSLATED", pathTranslated); environment.set("PATH_TRANSLATED", pathTranslated);
env.set("QUERY_STRING", req.getQueryString()); environment.set("QUERY_STRING", req.getQueryString());
env.set("REMOTE_ADDR", req.getRemoteAddr()); environment.set("REMOTE_ADDR", req.getRemoteAddr());
env.set("REMOTE_HOST", req.getRemoteHost()); environment.set("REMOTE_HOST", req.getRemoteHost());
// The identity information reported about the connection by a // The identity information reported about the connection by a
// RFC 1413 [11] request to the remote agent, if // RFC 1413 [11] request to the remote agent, if
// available. Servers MAY choose not to support this feature, or // available. Servers MAY choose not to support this feature, or
// not to request the data for efficiency reasons. // not to request the data for efficiency reasons.
// "REMOTE_IDENT" => "NYI" // "REMOTE_IDENT" => "NYI"
env.set("REMOTE_USER", req.getRemoteUser()); environment.set("REMOTE_USER", req.getRemoteUser());
env.set("REQUEST_METHOD", req.getMethod()); environment.set("REQUEST_METHOD", req.getMethod());
env.set("SCRIPT_NAME", scriptName); environment.set("SCRIPT_NAME", scriptName);
env.set("SCRIPT_FILENAME", scriptPath); environment.set("SCRIPT_FILENAME", scriptPath);
env.set("SERVER_NAME", req.getServerName()); environment.set("SERVER_NAME", req.getServerName());
env.set("SERVER_PORT", Integer.toString(req.getServerPort())); environment.set("SERVER_PORT", Integer.toString(req.getServerPort()));
env.set("SERVER_PROTOCOL", req.getProtocol()); environment.set("SERVER_PROTOCOL", req.getProtocol());
env.set("SERVER_SOFTWARE", context.getServerInfo()); environment.set("SERVER_SOFTWARE", context.getServerInfo());
Enumeration enm = req.getHeaderNames(); Enumeration enm = req.getHeaderNames();
@@ -140,11 +137,11 @@ public class CGIRunner
String name = (String) enm.nextElement(); String name = (String) enm.nextElement();
String value = req.getHeader(name); String value = req.getHeader(name);
env.set("HTTP_" + name.toUpperCase().replace('-', '_'), value); environment.set("HTTP_" + name.toUpperCase().replace('-', '_'), value);
} }
// these extra ones were from printenv on www.dev.nomura.co.uk // these extra ones were from printenv on www.dev.nomura.co.uk
env.set("HTTPS", (req.isSecure() environment.set("HTTPS", (req.isSecure()
? "ON" ? "ON"
: "OFF")); : "OFF"));
@@ -172,8 +169,8 @@ public class CGIRunner
} }
Process p = (dir == null) Process p = (dir == null)
? Runtime.getRuntime().exec(execCmd, env.getEnvArray()) ? Runtime.getRuntime().exec(execCmd, environment.getEnvArray())
: Runtime.getRuntime().exec(execCmd, env.getEnvArray(), dir); : Runtime.getRuntime().exec(execCmd, environment.getEnvArray(), dir);
// hook processes input to browser's output (async) // hook processes input to browser's output (async)
final InputStream inFromReq = req.getInputStream(); final InputStream inFromReq = req.getInputStream();
@@ -327,17 +324,6 @@ public class CGIRunner
return context; return context;
} }
/**
* Method description
*
*
* @return
*/
public EnvList getEnvironment()
{
return environment;
}
/** /**
* Method description * Method description
* *
@@ -373,17 +359,6 @@ public class CGIRunner
this.context = context; this.context = context;
} }
/**
* Method description
*
*
* @param environment
*/
public void setEnvironment(EnvList environment)
{
this.environment = environment;
}
/** /**
* Method description * Method description
* *
@@ -481,9 +456,6 @@ public class CGIRunner
/** Field description */ /** Field description */
private ServletContext context; private ServletContext context;
/** Field description */
private EnvList environment;
/** Field description */ /** Field description */
private boolean ignoreExitState; private boolean ignoreExitState;
} }

View File

@@ -27,7 +27,7 @@ public class EnvList
* Constructs ... * Constructs ...
* *
*/ */
EnvList() public EnvList()
{ {
envMap = new HashMap<String, String>(); envMap = new HashMap<String, String>();
} }
@@ -38,13 +38,26 @@ public class EnvList
* *
* @param l * @param l
*/ */
EnvList(EnvList l) public EnvList(EnvList l)
{ {
envMap = new HashMap<String, String>(l.envMap); envMap = new HashMap<String, String>(l.envMap);
} }
//~--- methods -------------------------------------------------------------- //~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param key
*
* @return
*/
public boolean containsKey(String key)
{
return envMap.containsKey(key);
}
/** /**
* Method description * Method description
* *
@@ -57,11 +70,6 @@ public class EnvList
return envMap.toString(); return envMap.toString();
} }
public boolean containsKey( String key )
{
return envMap.containsKey(key);
}
//~--- get methods ---------------------------------------------------------- //~--- get methods ----------------------------------------------------------
/** /**