Extract CGI configuration from GitWebConfig
GitWebConfig was used for two separate things: 1. Encapsulating the (type, GitWebConfig) pair that gets passed through the GerritConfig to the host page. 2. Describing the configuration for the built-in CGI servlet in the gitweb package. Separate these concerns, creating GitWebCgiConfig in the same config package as GitWebConfig. (Although it contains configuration for the httpd functionality, it needs to live in the server package so other server classes can check the configuration status.) Change-Id: I002beb892d415eb41a15829e6c5d540be253e390
This commit is contained in:
parent
1619197851
commit
1b2d47e7a2
@ -30,7 +30,7 @@ import com.google.gerrit.server.RemotePeer;
|
||||
import com.google.gerrit.server.config.AuthConfig;
|
||||
import com.google.gerrit.server.config.CanonicalWebUrl;
|
||||
import com.google.gerrit.server.config.GerritRequestModule;
|
||||
import com.google.gerrit.server.config.GitWebConfig;
|
||||
import com.google.gerrit.server.config.GitWebCgiConfig;
|
||||
import com.google.gerrit.server.git.AsyncReceiveCommits;
|
||||
import com.google.gerrit.server.util.GuiceRequestScopePropagator;
|
||||
import com.google.gerrit.server.util.RequestScopePropagator;
|
||||
@ -43,18 +43,18 @@ import java.net.SocketAddress;
|
||||
public class WebModule extends LifecycleModule {
|
||||
private final AuthConfig authConfig;
|
||||
private final boolean wantSSL;
|
||||
private final GitWebConfig gitWebConfig;
|
||||
private final GitWebCgiConfig gitWebCgiConfig;
|
||||
private final GerritOptions options;
|
||||
|
||||
@Inject
|
||||
WebModule(AuthConfig authConfig,
|
||||
@CanonicalWebUrl @Nullable String canonicalUrl,
|
||||
GerritOptions options,
|
||||
GitWebConfig gitWebConfig) {
|
||||
GitWebCgiConfig gitWebCgiConfig) {
|
||||
this.authConfig = authConfig;
|
||||
this.wantSSL = canonicalUrl != null && canonicalUrl.startsWith("https:");
|
||||
this.options = options;
|
||||
this.gitWebConfig = gitWebConfig;
|
||||
this.gitWebCgiConfig = gitWebCgiConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -75,7 +75,7 @@ public class WebModule extends LifecycleModule {
|
||||
install(new GerritRequestModule());
|
||||
install(new GitOverHttpServlet.Module(options.enableMasterFeatures()));
|
||||
|
||||
if (gitWebConfig.getGitwebCGI() != null) {
|
||||
if (gitWebCgiConfig.getGitwebCgi() != null) {
|
||||
install(new GitWebModule());
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ package com.google.gerrit.httpd.gitweb;
|
||||
import static com.google.gerrit.common.FileUtil.lastModified;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.gerrit.server.config.GitWebConfig;
|
||||
import com.google.gerrit.server.config.GitWebCgiConfig;
|
||||
import com.google.gwtexpui.server.CacheHeaders;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
@ -41,9 +41,9 @@ class GitLogoServlet extends HttpServlet {
|
||||
private final byte[] raw;
|
||||
|
||||
@Inject
|
||||
GitLogoServlet(GitWebConfig gitWebConfig) throws IOException {
|
||||
GitLogoServlet(GitWebCgiConfig cfg) throws IOException {
|
||||
byte[] png;
|
||||
Path src = gitWebConfig.getGitLogoPNG();
|
||||
Path src = cfg.getGitLogoPng();
|
||||
if (src != null) {
|
||||
try (InputStream in = Files.newInputStream(src)) {
|
||||
png = ByteStreams.toByteArray(in);
|
||||
|
@ -17,7 +17,7 @@ package com.google.gerrit.httpd.gitweb;
|
||||
import static com.google.gerrit.common.FileUtil.lastModified;
|
||||
|
||||
import com.google.gerrit.httpd.HtmlDomUtil;
|
||||
import com.google.gerrit.server.config.GitWebConfig;
|
||||
import com.google.gerrit.server.config.GitWebCgiConfig;
|
||||
import com.google.gerrit.server.config.SitePaths;
|
||||
import com.google.gwtexpui.server.CacheHeaders;
|
||||
import com.google.gwtjsonrpc.server.RPCServletUtils;
|
||||
@ -46,8 +46,8 @@ abstract class GitWebCssServlet extends HttpServlet {
|
||||
@Singleton
|
||||
static class Default extends GitWebCssServlet {
|
||||
@Inject
|
||||
Default(GitWebConfig gwc) throws IOException {
|
||||
super(gwc.getGitwebCSS());
|
||||
Default(GitWebCgiConfig gwcc) throws IOException {
|
||||
super(gwcc.getGitwebCss());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ package com.google.gerrit.httpd.gitweb;
|
||||
import static com.google.gerrit.common.FileUtil.lastModified;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.gerrit.server.config.GitWebConfig;
|
||||
import com.google.gerrit.server.config.GitWebCgiConfig;
|
||||
import com.google.gwtexpui.server.CacheHeaders;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
@ -41,9 +41,9 @@ class GitWebJavaScriptServlet extends HttpServlet {
|
||||
private final byte[] raw;
|
||||
|
||||
@Inject
|
||||
GitWebJavaScriptServlet(final GitWebConfig gitWebConfig) throws IOException {
|
||||
GitWebJavaScriptServlet(GitWebCgiConfig gitWebCgiConfig) throws IOException {
|
||||
byte[] png;
|
||||
Path src = gitWebConfig.getGitwebJS();
|
||||
Path src = gitWebCgiConfig.getGitwebJs();
|
||||
if (src != null) {
|
||||
try (InputStream in = Files.newInputStream(src)) {
|
||||
png = ByteStreams.toByteArray(in);
|
||||
|
@ -38,6 +38,7 @@ import com.google.gerrit.server.AnonymousUser;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.config.GerritServerConfig;
|
||||
import com.google.gerrit.server.config.GitWebCgiConfig;
|
||||
import com.google.gerrit.server.config.GitWebConfig;
|
||||
import com.google.gerrit.server.config.SitePaths;
|
||||
import com.google.gerrit.server.git.LocalDiskRepositoryManager;
|
||||
@ -105,13 +106,14 @@ class GitWebServlet extends HttpServlet {
|
||||
SitePaths site,
|
||||
@GerritServerConfig Config cfg,
|
||||
SshInfo sshInfo,
|
||||
GitWebConfig gitWebConfig)
|
||||
GitWebConfig gitWebConfig,
|
||||
GitWebCgiConfig gitWebCgiConfig)
|
||||
throws IOException {
|
||||
this.repoManager = repoManager;
|
||||
this.projectControl = projectControl;
|
||||
this.anonymousUserProvider = anonymousUserProvider;
|
||||
this.userProvider = userProvider;
|
||||
this.gitwebCgi = gitWebConfig.getGitwebCGI();
|
||||
this.gitwebCgi = gitWebCgiConfig.getGitwebCgi();
|
||||
this.deniedActions = new HashSet<>();
|
||||
|
||||
final String url = gitWebConfig.getUrl();
|
||||
|
@ -0,0 +1,137 @@
|
||||
// Copyright (C) 2015 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.config;
|
||||
|
||||
import static java.nio.file.Files.isExecutable;
|
||||
import static java.nio.file.Files.isRegularFile;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
@Singleton
|
||||
public class GitWebCgiConfig {
|
||||
private static final Logger log =
|
||||
LoggerFactory.getLogger(GitWebCgiConfig.class);
|
||||
|
||||
public GitWebCgiConfig disabled() {
|
||||
return new GitWebCgiConfig();
|
||||
}
|
||||
|
||||
private final Path cgi;
|
||||
private final Path css;
|
||||
private final Path js;
|
||||
private final Path logoPng;
|
||||
|
||||
@Inject
|
||||
GitWebCgiConfig(SitePaths sitePaths, @GerritServerConfig Config cfg) {
|
||||
if (GitWebConfig.isDisabled(cfg)) {
|
||||
cgi = null;
|
||||
css = null;
|
||||
js = null;
|
||||
logoPng = null;
|
||||
return;
|
||||
}
|
||||
|
||||
String cfgCgi = cfg.getString("gitweb", null, "cgi");
|
||||
Path pkgCgi = Paths.get("/usr/lib/cgi-bin/gitweb.cgi");
|
||||
String[] resourcePaths = {"/usr/share/gitweb/static", "/usr/share/gitweb",
|
||||
"/var/www/static", "/var/www"};
|
||||
Path cgi;
|
||||
|
||||
if (cfgCgi != null) {
|
||||
// Use the CGI script configured by the administrator, failing if it
|
||||
// cannot be used as specified.
|
||||
//
|
||||
cgi = sitePaths.resolve(cfgCgi);
|
||||
if (!isRegularFile(cgi)) {
|
||||
throw new IllegalStateException("Cannot find gitweb.cgi: " + cgi);
|
||||
}
|
||||
if (!isExecutable(cgi)) {
|
||||
throw new IllegalStateException("Cannot execute gitweb.cgi: " + cgi);
|
||||
}
|
||||
|
||||
if (!cgi.equals(pkgCgi)) {
|
||||
// Assume the administrator pointed us to the distribution,
|
||||
// which also has the corresponding CSS and logo file.
|
||||
//
|
||||
String absPath = cgi.getParent().toAbsolutePath().toString();
|
||||
resourcePaths = new String[] {absPath + "/static", absPath};
|
||||
}
|
||||
|
||||
} else if (isRegularFile(pkgCgi) && isExecutable(pkgCgi)) {
|
||||
// Use the OS packaged CGI.
|
||||
//
|
||||
log.debug("Assuming gitweb at " + pkgCgi);
|
||||
cgi = pkgCgi;
|
||||
|
||||
} else {
|
||||
log.warn("gitweb not installed (no " + pkgCgi + " found)");
|
||||
cgi = null;
|
||||
resourcePaths = new String[] {};
|
||||
}
|
||||
|
||||
Path css = null;
|
||||
Path js = null;
|
||||
Path logo = null;
|
||||
for (String path : resourcePaths) {
|
||||
Path dir = Paths.get(path);
|
||||
css = dir.resolve("gitweb.css");
|
||||
js = dir.resolve("gitweb.js");
|
||||
logo = dir.resolve("git-logo.png");
|
||||
if (isRegularFile(css) && isRegularFile(logo)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.cgi = cgi;
|
||||
this.css = css;
|
||||
this.js = js;
|
||||
this.logoPng = logo;
|
||||
}
|
||||
|
||||
private GitWebCgiConfig() {
|
||||
this.cgi = null;
|
||||
this.css = null;
|
||||
this.js = null;
|
||||
this.logoPng = null;
|
||||
}
|
||||
|
||||
/** @return local path to the CGI executable; null if we shouldn't execute. */
|
||||
public Path getGitwebCgi() {
|
||||
return cgi;
|
||||
}
|
||||
|
||||
/** @return local path of the {@code gitweb.css} matching the CGI. */
|
||||
public Path getGitwebCss() {
|
||||
return css;
|
||||
}
|
||||
|
||||
/** @return local path of the {@code gitweb.js} for the CGI. */
|
||||
public Path getGitwebJs() {
|
||||
return js;
|
||||
}
|
||||
|
||||
/** @return local path of the {@code git-logo.png} for the CGI. */
|
||||
public Path getGitLogoPng() {
|
||||
return logoPng;
|
||||
}
|
||||
}
|
@ -14,8 +14,7 @@
|
||||
|
||||
package com.google.gerrit.server.config;
|
||||
|
||||
import static java.nio.file.Files.isExecutable;
|
||||
import static java.nio.file.Files.isRegularFile;
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gerrit.common.data.GitWebType;
|
||||
@ -25,12 +24,14 @@ import org.eclipse.jgit.lib.Config;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class GitWebConfig {
|
||||
private static final Logger log = LoggerFactory.getLogger(GitWebConfig.class);
|
||||
|
||||
public static boolean isDisabled(Config cfg) {
|
||||
return isEmptyString(cfg, "gitweb", null, "url")
|
||||
|| isEmptyString(cfg, "gitweb", null, "cgi");
|
||||
}
|
||||
|
||||
private static boolean isEmptyString(Config cfg, String section,
|
||||
String subsection, String name) {
|
||||
// This is currently the only way to check for the empty string in a JGit
|
||||
@ -40,27 +41,29 @@ public class GitWebConfig {
|
||||
}
|
||||
|
||||
private final String url;
|
||||
private final Path gitweb_cgi;
|
||||
private final Path gitweb_css;
|
||||
private final Path gitweb_js;
|
||||
private final Path git_logo_png;
|
||||
private GitWebType type;
|
||||
private final GitWebType type;
|
||||
|
||||
@Inject
|
||||
GitWebConfig(final SitePaths sitePaths, @GerritServerConfig final Config cfg) {
|
||||
final String cfgUrl = cfg.getString("gitweb", null, "url");
|
||||
final String cfgCgi = cfg.getString("gitweb", null, "cgi");
|
||||
|
||||
type = GitWebType.fromName(cfg.getString("gitweb", null, "type"));
|
||||
if (type == null) {
|
||||
GitWebConfig(GitWebCgiConfig cgiConfig, @GerritServerConfig Config cfg) {
|
||||
if (isDisabled(cfg)) {
|
||||
type = null;
|
||||
url = null;
|
||||
gitweb_cgi = null;
|
||||
gitweb_css = null;
|
||||
gitweb_js = null;
|
||||
git_logo_png = null;
|
||||
return;
|
||||
}
|
||||
|
||||
String cfgUrl = cfg.getString("gitweb", null, "url");
|
||||
GitWebType type = GitWebType.fromName(cfg.getString("gitweb", null, "type"));
|
||||
if (type == null) {
|
||||
this.type = null;
|
||||
url = null;
|
||||
return;
|
||||
} else if (cgiConfig.getGitwebCgi() == null) {
|
||||
// Use an externally managed gitweb instance, and not an internal one.
|
||||
url = cfgUrl;
|
||||
} else {
|
||||
url = firstNonNull(cfgUrl, "gitweb");
|
||||
}
|
||||
|
||||
type.setLinkName(cfg.getString("gitweb", null, "linkname"));
|
||||
type.setBranch(cfg.getString("gitweb", null, "branch"));
|
||||
type.setProject(cfg.getString("gitweb", null, "project"));
|
||||
@ -86,107 +89,25 @@ public class GitWebConfig {
|
||||
|
||||
if (type.getBranch() == null) {
|
||||
log.warn("No Pattern specified for gitweb.branch, disabling.");
|
||||
type = null;
|
||||
this.type = null;
|
||||
} else if (type.getProject() == null) {
|
||||
log.warn("No Pattern specified for gitweb.project, disabling.");
|
||||
type = null;
|
||||
this.type = null;
|
||||
} else if (type.getRevision() == null) {
|
||||
log.warn("No Pattern specified for gitweb.revision, disabling.");
|
||||
type = null;
|
||||
this.type = null;
|
||||
} else if (type.getRootTree() == null) {
|
||||
log.warn("No Pattern specified for gitweb.roottree, disabling.");
|
||||
type = null;
|
||||
this.type = null;
|
||||
} else if (type.getFile() == null) {
|
||||
log.warn("No Pattern specified for gitweb.file, disabling.");
|
||||
type = null;
|
||||
this.type = null;
|
||||
} else if (type.getFileHistory() == null) {
|
||||
log.warn("No Pattern specified for gitweb.filehistory, disabling.");
|
||||
type = null;
|
||||
}
|
||||
|
||||
if (isEmptyString(cfg, "gitweb", null, "url")
|
||||
|| isEmptyString(cfg, "gitweb", null, "cgi")) {
|
||||
// Either setting was explicitly set to the empty string disabling
|
||||
// gitweb for this server. Disable the configuration.
|
||||
//
|
||||
url = null;
|
||||
gitweb_cgi = null;
|
||||
gitweb_css = null;
|
||||
gitweb_js = null;
|
||||
git_logo_png = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((cfgUrl != null) && (cfgCgi == null || cfgCgi.isEmpty())) {
|
||||
// Use an externally managed gitweb instance, and not an internal one.
|
||||
//
|
||||
url = cfgUrl;
|
||||
gitweb_cgi = null;
|
||||
gitweb_css = null;
|
||||
gitweb_js = null;
|
||||
git_logo_png = null;
|
||||
return;
|
||||
}
|
||||
|
||||
final Path pkgCgi = Paths.get("/usr/lib/cgi-bin/gitweb.cgi");
|
||||
String[] resourcePaths = {"/usr/share/gitweb/static", "/usr/share/gitweb",
|
||||
"/var/www/static", "/var/www"};
|
||||
Path cgi;
|
||||
|
||||
if (cfgCgi != null) {
|
||||
// Use the CGI script configured by the administrator, failing if it
|
||||
// cannot be used as specified.
|
||||
//
|
||||
cgi = sitePaths.resolve(cfgCgi);
|
||||
if (!isRegularFile(cgi)) {
|
||||
throw new IllegalStateException("Cannot find gitweb.cgi: " + cgi);
|
||||
}
|
||||
if (!isExecutable(cgi)) {
|
||||
throw new IllegalStateException("Cannot execute gitweb.cgi: " + cgi);
|
||||
}
|
||||
|
||||
if (!cgi.equals(pkgCgi)) {
|
||||
// Assume the administrator pointed us to the distribution,
|
||||
// which also has the corresponding CSS and logo file.
|
||||
//
|
||||
String absPath = cgi.getParent().toAbsolutePath().toString();
|
||||
resourcePaths = new String[] {absPath + "/static", absPath};
|
||||
}
|
||||
|
||||
} else if (isRegularFile(pkgCgi) && isExecutable(pkgCgi)) {
|
||||
// Use the OS packaged CGI.
|
||||
//
|
||||
log.debug("Assuming gitweb at " + pkgCgi);
|
||||
cgi = pkgCgi;
|
||||
|
||||
this.type = null;
|
||||
} else {
|
||||
log.warn("gitweb not installed (no " + pkgCgi + " found)");
|
||||
cgi = null;
|
||||
resourcePaths = new String[] {};
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
Path css = null;
|
||||
Path js = null;
|
||||
Path logo = null;
|
||||
for (String path : resourcePaths) {
|
||||
Path dir = Paths.get(path);
|
||||
css = dir.resolve("gitweb.css");
|
||||
js = dir.resolve("gitweb.js");
|
||||
logo = dir.resolve("git-logo.png");
|
||||
if (isRegularFile(css) && isRegularFile(logo)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
git_logo_png = logo;
|
||||
}
|
||||
|
||||
/** @return GitWebType for gitweb viewer. */
|
||||
@ -203,26 +124,6 @@ public class GitWebConfig {
|
||||
return url;
|
||||
}
|
||||
|
||||
/** @return local path to the CGI executable; null if we shouldn't execute. */
|
||||
public Path getGitwebCGI() {
|
||||
return gitweb_cgi;
|
||||
}
|
||||
|
||||
/** @return local path of the {@code gitweb.css} matching the CGI. */
|
||||
public Path getGitwebCSS() {
|
||||
return gitweb_css;
|
||||
}
|
||||
|
||||
/** @return local path of the {@code gitweb.js} for the CGI. */
|
||||
public Path getGitwebJS() {
|
||||
return gitweb_js;
|
||||
}
|
||||
|
||||
/** @return local path of the {@code git-logo.png} for the CGI. */
|
||||
public Path getGitLogoPNG() {
|
||||
return git_logo_png;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a given character can be used unencoded in an URL as a
|
||||
* replacement for the path separator '/'.
|
||||
|
Loading…
Reference in New Issue
Block a user