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(); }