1

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!

Sergei Voitovich
  • 2,804
  • 3
  • 25
  • 33

2 Answers2

1

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.

Zoe
  • 27,060
  • 21
  • 118
  • 148
Ry4an Brase
  • 78,112
  • 7
  • 148
  • 169
  • I already looked on the Command Server and JavaHg library and the only reason I didn't use it - it's dead. There are also really small amount of examples. Nothing except unit tests in their repository can show me how to deal with javahg. That's why I look on hgweb.cgi. But your answer confused me! I'm going to think one more time about these tools and make final decision. But you gave me feel that my work is not hopeless as I thought. I will have a rest for a few days and then tell about my decision. – Sergei Voitovich Aug 12 '15 at 19:05
  • Despite of your answer I decided to invoke mercurial as a separate process. It looks ok but I didn't test it with many of users. – Sergei Voitovich Aug 17 '15 at 08:40
  • Good deal, I'm glad you got it figured out. Someone else will probably want to do the same so it's nice when you can link to the key part of your solution. If you add it as a 2nd answer I'll vote for it. Do remember though, that invoking executables is a really easy way to let shell injection leak in, so be sure to sanitize those inputs! – Ry4an Brase Aug 17 '15 at 12:47
0

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.

Community
  • 1
  • 1
Sergei Voitovich
  • 2,804
  • 3
  • 25
  • 33