From 6a9d47edb1be5fa513a9b58d975e97fe9d60a265 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Sun, 27 Feb 2011 21:22:32 +0000 Subject: [PATCH] Add alternative URL for Gerrit's managed Gitweb. This patch allows configuration of alternative base URL for: - "(gitweb)" links in Gerrit, - all links in Gerrit's managed Gitweb. Please note that this changes only URL of the links and not real URL under which Gerrit's managed Gitweb is served ("/gitweb"). This means that this feature is useful only in setups with front-end web servers. To enable this feature, set both: gitweb.cgi and gitweb.url. Change-Id: I869e2c0e151deb0e0248ed86b9611e1e5ac7e431 Signed-off-by: Piotr Sikora --- Documentation/config-gitweb.txt | 13 +++++ .../com/google/gerrit/httpd/GitWebConfig.java | 8 ++- .../gerrit/httpd/gitweb/GitWebServlet.java | 52 +++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/Documentation/config-gitweb.txt b/Documentation/config-gitweb.txt index eb43733471..a08eb873b8 100644 --- a/Documentation/config-gitweb.txt +++ b/Documentation/config-gitweb.txt @@ -21,6 +21,18 @@ Linux distributions. ==== git config --file $site_path/etc/gerrit.config gitweb.cgi /usr/lib/cgi-bin/gitweb.cgi + git config --file $site_path/etc/gerrit.config --unset gitweb.url +==== + +Alternatively, if Gerrit is served behind reverse proxy, it can +generate different URLs for gitweb's links (they need to be +rewritten to `/gitweb?args` on the web server). This allows +for serving gitweb under different URL than the Gerrit instance. +To enable this feature, set both: `gitweb.cgi` and `gitweb.url`. + +==== + git config --file $site_path/etc/gerrit.config gitweb.cgi /usr/lib/cgi-bin/gitweb.cgi + git config --file $site_path/etc/gerrit.config gitweb.url /pretty/path/to/gitweb ==== After updating `'$site_path'/etc/gerrit.config`, the Gerrit server must @@ -69,6 +81,7 @@ namespace is available. ==== git config --file $site_path/etc/gerrit.config gitweb.url http://example.com/gitweb.cgi + git config --file $site_path/etc/gerrit.config --unset gitweb.cgi ==== After updating `'$site_path'/etc/gerrit.config`, the Gerrit server must diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GitWebConfig.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GitWebConfig.java index 57a4b90362..b35fe6ee49 100644 --- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GitWebConfig.java +++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GitWebConfig.java @@ -69,7 +69,7 @@ public class GitWebConfig { return; } - if (cfgUrl != null) { + if ((cfgUrl != null) && (cfgCgi == null || cfgCgi.isEmpty())) { // Use an externally managed gitweb instance, and not an internal one. // url = cfgUrl; @@ -126,7 +126,11 @@ public class GitWebConfig { } } - url = cgi != null ? "gitweb" : null; + if (cfgUrl == null || cfgUrl.isEmpty()) { + url = cgi != null ? "gitweb" : null; + } else { + url = cgi != null ? cfgUrl : null; + } gitweb_cgi = cgi; gitweb_css = css; gitweb_js = js; diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/gitweb/GitWebServlet.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/gitweb/GitWebServlet.java index 2d7ed09362..d2adaf7004 100644 --- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/gitweb/GitWebServlet.java +++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/gitweb/GitWebServlet.java @@ -57,6 +57,8 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URLDecoder; import java.util.Enumeration; import java.util.HashMap; @@ -78,6 +80,7 @@ class GitWebServlet extends HttpServlet { private final Set deniedActions; private final int bufferSize = 8192; private final File gitwebCgi; + private final URI gitwebUrl; private final LocalDiskRepositoryManager repoManager; private final ProjectControl.Factory projectControl; private final EnvList _env; @@ -92,6 +95,19 @@ class GitWebServlet extends HttpServlet { this.gitwebCgi = gitWebConfig.getGitwebCGI(); this.deniedActions = new HashSet(); + final String url = gitWebConfig.getUrl(); + if ((url != null) && (!url.equals("gitweb"))) { + URI uri = null; + try { + uri = new URI(url); + } catch (URISyntaxException e) { + log.error("Invalid gitweb.url: " + url); + } + gitwebUrl = uri; + } else { + gitwebUrl = null; + } + deniedActions.add("forks"); deniedActions.add("opml"); deniedActions.add("project_list"); @@ -487,6 +503,42 @@ class GitWebServlet extends HttpServlet { } env.set("REMOTE_USER", remoteUser); + // Override CGI settings using alternative URI provided by gitweb.url. + // This is required to trick Gitweb into thinking that it's served under + // different URL. Setting just $my_uri on the perl's side isn't enough, + // because few actions (atom, blobdiff_plain, commitdiff_plain) rely on + // URL returned by $cgi->self_url(). + // + if (gitwebUrl != null) { + int schemePort = -1; + + if (gitwebUrl.getScheme() != null) { + if (gitwebUrl.getScheme().equals("http")) { + env.set("HTTPS", "OFF"); + schemePort = 80; + } else { + env.set("HTTPS", "ON"); + schemePort = 443; + } + } + + if (gitwebUrl.getHost() != null) { + env.set("SERVER_NAME", gitwebUrl.getHost()); + env.set("HTTP_HOST", gitwebUrl.getHost()); + } + + if (gitwebUrl.getPort() != -1) { + env.set("SERVER_PORT", Integer.toString(gitwebUrl.getPort())); + } else if (schemePort != -1) { + env.set("SERVER_PORT", Integer.toString(schemePort)); + } + + if (gitwebUrl.getPath() != null) { + env.set("SCRIPT_NAME", gitwebUrl.getPath().isEmpty() + ? "/" : gitwebUrl.getPath()); + } + } + return env.getEnvArray(); }