Execute hgweb.cgi from Java

352 Views Asked by At

I have Jetty web server from which I want to run hgweb.cgi:

ProcessBuilder builder = new ProcessBuilder("/MyPath/hgweb.cgi");

Then I create Process process = builder.start(); and feed Input stream from request to process forming server response. But there's a problem: some kind of python error I can't understand

File "<stdin>", line 1, in <module>
  File "mercurial/hgweb/wsgicgi.py", line 76, in launch
    content = application(environ, start_response)
  File "mercurial/hgweb/hgweb_mod.py", line 168, in __call__
    return self.run_wsgi(req)
  File "mercurial/hgweb/hgweb_mod.py", line 177, in run_wsgi
    req.url = req.env['SCRIPT_NAME']
KeyError: 'SCRIPT_NAME

That doesn't work from command line neither. I tried to add a header (SCRIPT_NAME, "") to formed request for hgweb.cgi but continue see that message.

In every example of using hgweb people use apache / lighttpd / nginx servers to run hgweb.cgi and I can't understand why nodody did what I want to do.

If anybody could help me with configuring hgweb.cgi or told me a proper way to call .cgi script from java I would be really happy!

2

There are 2 best solutions below

3
Ry4an Brase On BEST ANSWER

I think the reason you can't find any examples is that invoking a Python executable from Java for each request isn't really something anyone recommends. It's slow and insecure. Consider communicating through a pipe with the Command Server which reuses a single Python process and was designed for exactly this sort of thing. There are even Java client libraries.

If you really want to try invoking mercurial as a separate process from Java you needn't be calling the .cgi (or the wsgi which what it looks like you're getting). Just call the main Python executable directly providing the command line arguments and stdin.

0
Sergei Voitovich On

To invoke cgi from java you don't need to call hgweb.cgi (there's one more thing I figured out : .cgi is no more than just a sign that tells you about purpose of the program. There is no special language for cgi or function signature you must take care of). I made a script hgweb.py:

import os
from mercurial import demandimport
from mercurial.hgweb import hgweb, wsgicgi

repositoryPath = os.environ['REPOSITORY_PATH']

application = hgweb(repositoryPath) 
wsgicgi.launch(application)

Few lines of code invoke that script:

ProcessBuilder process = new ProcessBuilder("python", "hgweb.py");

//pass all necessary environment variables
Map<String, String> env = process.environment();
env.put("variable", "value");
..
//then pick a directory where your process will run
process.directory(yourDirectory);
process.start();
/* then set up 
 * inputStream from request
 * outputStream for response
 * errorStream that is very useful if something went wrong
 * (you may forget to add an environment variable or something like that)
 */

I think that is exactly what I needed. If I find any problems - I would write about them here. Thanks to Ry4an for helping.