SitePaths: Convert static content related paths to Path
Change-Id: I4fa11a0043cdd1c001a27ab7b5da8163182728f1
This commit is contained in:
		| @@ -14,6 +14,9 @@ | |||||||
|  |  | ||||||
| package com.google.gerrit.httpd; | package com.google.gerrit.httpd; | ||||||
|  |  | ||||||
|  | import static java.nio.file.Files.isExecutable; | ||||||
|  | import static java.nio.file.Files.isRegularFile; | ||||||
|  |  | ||||||
| import com.google.gerrit.common.data.GitWebType; | import com.google.gerrit.common.data.GitWebType; | ||||||
| import com.google.gerrit.server.config.GerritServerConfig; | import com.google.gerrit.server.config.GerritServerConfig; | ||||||
| import com.google.gerrit.server.config.SitePaths; | import com.google.gerrit.server.config.SitePaths; | ||||||
| @@ -23,16 +26,17 @@ import org.eclipse.jgit.lib.Config; | |||||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.io.File; | import java.nio.file.Path; | ||||||
|  | import java.nio.file.Paths; | ||||||
|  |  | ||||||
| public class GitWebConfig { | public class GitWebConfig { | ||||||
|   private static final Logger log = LoggerFactory.getLogger(GitWebConfig.class); |   private static final Logger log = LoggerFactory.getLogger(GitWebConfig.class); | ||||||
|  |  | ||||||
|   private final String url; |   private final String url; | ||||||
|   private final File gitweb_cgi; |   private final Path gitweb_cgi; | ||||||
|   private final File gitweb_css; |   private final Path gitweb_css; | ||||||
|   private final File gitweb_js; |   private final Path gitweb_js; | ||||||
|   private final File git_logo_png; |   private final Path git_logo_png; | ||||||
|   private GitWebType type; |   private GitWebType type; | ||||||
|  |  | ||||||
|   @Inject |   @Inject | ||||||
| @@ -117,20 +121,20 @@ public class GitWebConfig { | |||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     final File pkgCgi = new File("/usr/lib/cgi-bin/gitweb.cgi"); |     final Path pkgCgi = Paths.get("/usr/lib/cgi-bin/gitweb.cgi"); | ||||||
|     String[] resourcePaths = {"/usr/share/gitweb/static", "/usr/share/gitweb", |     String[] resourcePaths = {"/usr/share/gitweb/static", "/usr/share/gitweb", | ||||||
|         "/var/www/static", "/var/www"}; |         "/var/www/static", "/var/www"}; | ||||||
|     File cgi; |     Path cgi; | ||||||
|  |  | ||||||
|     if (cfgCgi != null) { |     if (cfgCgi != null) { | ||||||
|       // Use the CGI script configured by the administrator, failing if it |       // Use the CGI script configured by the administrator, failing if it | ||||||
|       // cannot be used as specified. |       // cannot be used as specified. | ||||||
|       // |       // | ||||||
|       cgi = sitePaths.resolve(cfgCgi); |       cgi = sitePaths.resolve(cfgCgi).toPath(); | ||||||
|       if (!cgi.isFile()) { |       if (!isRegularFile(cgi)) { | ||||||
|         throw new IllegalStateException("Cannot find gitweb.cgi: " + cgi); |         throw new IllegalStateException("Cannot find gitweb.cgi: " + cgi); | ||||||
|       } |       } | ||||||
|       if (!cgi.canExecute()) { |       if (!isExecutable(cgi)) { | ||||||
|         throw new IllegalStateException("Cannot execute gitweb.cgi: " + cgi); |         throw new IllegalStateException("Cannot execute gitweb.cgi: " + cgi); | ||||||
|       } |       } | ||||||
|  |  | ||||||
| @@ -138,11 +142,11 @@ public class GitWebConfig { | |||||||
|         // Assume the administrator pointed us to the distribution, |         // Assume the administrator pointed us to the distribution, | ||||||
|         // which also has the corresponding CSS and logo file. |         // which also has the corresponding CSS and logo file. | ||||||
|         // |         // | ||||||
|         String absPath = cgi.getParentFile().getAbsolutePath(); |         String absPath = cgi.getParent().toAbsolutePath().toString(); | ||||||
|         resourcePaths = new String[] {absPath + "/static", absPath}; |         resourcePaths = new String[] {absPath + "/static", absPath}; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|     } else if (pkgCgi.isFile() && pkgCgi.canExecute()) { |     } else if (isRegularFile(pkgCgi) && isExecutable(pkgCgi)) { | ||||||
|       // Use the OS packaged CGI. |       // Use the OS packaged CGI. | ||||||
|       // |       // | ||||||
|       log.debug("Assuming gitweb at " + pkgCgi); |       log.debug("Assuming gitweb at " + pkgCgi); | ||||||
| @@ -154,13 +158,13 @@ public class GitWebConfig { | |||||||
|       resourcePaths = new String[] {}; |       resourcePaths = new String[] {}; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     File css = null, js = null, logo = null; |     Path css = null, js = null, logo = null; | ||||||
|     for (String path : resourcePaths) { |     for (String path : resourcePaths) { | ||||||
|       File dir = new File(path); |       Path dir = Paths.get(path); | ||||||
|       css = new File(dir, "gitweb.css"); |       css = dir.resolve("gitweb.css"); | ||||||
|       js = new File(dir, "gitweb.js"); |       js = dir.resolve("gitweb.js"); | ||||||
|       logo = new File(dir, "git-logo.png"); |       logo = dir.resolve("git-logo.png"); | ||||||
|       if (css.isFile() && logo.isFile()) { |       if (isRegularFile(css) && isRegularFile(logo)) { | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -191,22 +195,22 @@ public class GitWebConfig { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** @return local path to the CGI executable; null if we shouldn't execute. */ |   /** @return local path to the CGI executable; null if we shouldn't execute. */ | ||||||
|   public File getGitwebCGI() { |   public Path getGitwebCGI() { | ||||||
|     return gitweb_cgi; |     return gitweb_cgi; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** @return local path of the {@code gitweb.css} matching the CGI. */ |   /** @return local path of the {@code gitweb.css} matching the CGI. */ | ||||||
|   public File getGitwebCSS() { |   public Path getGitwebCSS() { | ||||||
|     return gitweb_css; |     return gitweb_css; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** @return local path of the {@code gitweb.js} for the CGI. */ |   /** @return local path of the {@code gitweb.js} for the CGI. */ | ||||||
|   public File getGitwebJS() { |   public Path getGitwebJS() { | ||||||
|     return gitweb_js; |     return gitweb_js; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** @return local path of the {@code git-logo.png} for the CGI. */ |   /** @return local path of the {@code git-logo.png} for the CGI. */ | ||||||
|   public File getGitLogoPNG() { |   public Path getGitLogoPNG() { | ||||||
|     return git_logo_png; |     return git_logo_png; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -23,14 +23,14 @@ import org.w3c.dom.NodeList; | |||||||
| import org.xml.sax.SAXException; | import org.xml.sax.SAXException; | ||||||
|  |  | ||||||
| import java.io.ByteArrayOutputStream; | import java.io.ByteArrayOutputStream; | ||||||
| import java.io.File; |  | ||||||
| import java.io.FileInputStream; |  | ||||||
| import java.io.FileNotFoundException; | import java.io.FileNotFoundException; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.io.InputStream; | import java.io.InputStream; | ||||||
| import java.io.StringWriter; | import java.io.StringWriter; | ||||||
| import java.nio.charset.Charset; | import java.nio.charset.Charset; | ||||||
| import java.nio.charset.StandardCharsets; | import java.nio.charset.StandardCharsets; | ||||||
|  | import java.nio.file.Files; | ||||||
|  | import java.nio.file.Path; | ||||||
| import java.util.zip.GZIPOutputStream; | import java.util.zip.GZIPOutputStream; | ||||||
|  |  | ||||||
| import javax.xml.parsers.DocumentBuilder; | import javax.xml.parsers.DocumentBuilder; | ||||||
| @@ -187,8 +187,8 @@ public class HtmlDomUtil { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** Parse an XHTML file from the local drive and return the instance. */ |   /** Parse an XHTML file from the local drive and return the instance. */ | ||||||
|   public static Document parseFile(File path) throws IOException { |   public static Document parseFile(Path path) throws IOException { | ||||||
|     try (InputStream in = new FileInputStream(path)) { |     try (InputStream in = Files.newInputStream(path)) { | ||||||
|       Document doc = newBuilder().parse(in); |       Document doc = newBuilder().parse(in); | ||||||
|       compact(doc); |       compact(doc); | ||||||
|       return doc; |       return doc; | ||||||
| @@ -200,13 +200,13 @@ public class HtmlDomUtil { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** Read a UTF-8 text file from the local drive. */ |   /** Read a UTF-8 text file from the local drive. */ | ||||||
|   public static String readFile(File parentDir, String name) |   public static String readFile(Path parentDir, String name) | ||||||
|       throws IOException { |       throws IOException { | ||||||
|     if (parentDir == null) { |     if (parentDir == null) { | ||||||
|       return null; |       return null; | ||||||
|     } |     } | ||||||
|     File path = new File(parentDir, name); |     Path path = parentDir.resolve(name); | ||||||
|     try (FileInputStream in = new FileInputStream(path)) { |     try (InputStream in = Files.newInputStream(path)) { | ||||||
|       return new String(ByteStreams.toByteArray(in), ENC); |       return new String(ByteStreams.toByteArray(in), ENC); | ||||||
|     } catch (FileNotFoundException e) { |     } catch (FileNotFoundException e) { | ||||||
|       return null; |       return null; | ||||||
|   | |||||||
| @@ -14,16 +14,17 @@ | |||||||
|  |  | ||||||
| package com.google.gerrit.httpd.gitweb; | package com.google.gerrit.httpd.gitweb; | ||||||
|  |  | ||||||
|  | import com.google.common.io.ByteStreams; | ||||||
| import com.google.gerrit.httpd.GitWebConfig; | import com.google.gerrit.httpd.GitWebConfig; | ||||||
| import com.google.gwtexpui.server.CacheHeaders; | import com.google.gwtexpui.server.CacheHeaders; | ||||||
| import com.google.inject.Inject; | import com.google.inject.Inject; | ||||||
| import com.google.inject.Singleton; | import com.google.inject.Singleton; | ||||||
|  |  | ||||||
| import org.eclipse.jgit.util.IO; |  | ||||||
|  |  | ||||||
| import java.io.File; |  | ||||||
| import java.io.FileNotFoundException; | import java.io.FileNotFoundException; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
|  | import java.io.InputStream; | ||||||
|  | import java.nio.file.Files; | ||||||
|  | import java.nio.file.Path; | ||||||
| import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||||
|  |  | ||||||
| import javax.servlet.ServletOutputStream; | import javax.servlet.ServletOutputStream; | ||||||
| @@ -38,16 +39,16 @@ class GitLogoServlet extends HttpServlet { | |||||||
|   private final byte[] raw; |   private final byte[] raw; | ||||||
|  |  | ||||||
|   @Inject |   @Inject | ||||||
|   GitLogoServlet(final GitWebConfig gitWebConfig) throws IOException { |   GitLogoServlet(GitWebConfig gitWebConfig) throws IOException { | ||||||
|     byte[] png; |     byte[] png; | ||||||
|     final File src = gitWebConfig.getGitLogoPNG(); |     Path src = gitWebConfig.getGitLogoPNG(); | ||||||
|     if (src != null) { |     if (src != null) { | ||||||
|       try { |       try (InputStream in = Files.newInputStream(src)) { | ||||||
|         png = IO.readFully(src); |         png = ByteStreams.toByteArray(in); | ||||||
|       } catch (FileNotFoundException e) { |       } catch (FileNotFoundException e) { | ||||||
|         png = null; |         png = null; | ||||||
|       } |       } | ||||||
|       modified = src.lastModified(); |       modified = Files.getLastModifiedTime(src).toMillis(); | ||||||
|     } else { |     } else { | ||||||
|       modified = -1; |       modified = -1; | ||||||
|       png = null; |       png = null; | ||||||
|   | |||||||
| @@ -22,8 +22,9 @@ import com.google.gwtjsonrpc.server.RPCServletUtils; | |||||||
| import com.google.inject.Inject; | import com.google.inject.Inject; | ||||||
| import com.google.inject.Singleton; | import com.google.inject.Singleton; | ||||||
|  |  | ||||||
| import java.io.File; |  | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
|  | import java.nio.file.Files; | ||||||
|  | import java.nio.file.Path; | ||||||
| import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||||
|  |  | ||||||
| import javax.servlet.ServletOutputStream; | import javax.servlet.ServletOutputStream; | ||||||
| @@ -55,14 +56,14 @@ abstract class GitWebCssServlet extends HttpServlet { | |||||||
|   private final byte[] raw_css; |   private final byte[] raw_css; | ||||||
|   private final byte[] gz_css; |   private final byte[] gz_css; | ||||||
|  |  | ||||||
|   GitWebCssServlet(final File src) |   GitWebCssServlet(final Path src) | ||||||
|       throws IOException { |       throws IOException { | ||||||
|     if (src != null) { |     if (src != null) { | ||||||
|       final File dir = src.getParentFile(); |       final Path dir = src.getParent(); | ||||||
|       final String name = src.getName(); |       final String name = src.getFileName().toString(); | ||||||
|       final String raw = HtmlDomUtil.readFile(dir, name); |       final String raw = HtmlDomUtil.readFile(dir, name); | ||||||
|       if (raw != null) { |       if (raw != null) { | ||||||
|         modified = src.lastModified(); |         modified = Files.getLastModifiedTime(src).toMillis(); | ||||||
|         raw_css = raw.getBytes(ENC); |         raw_css = raw.getBytes(ENC); | ||||||
|         gz_css = HtmlDomUtil.compress(raw_css); |         gz_css = HtmlDomUtil.compress(raw_css); | ||||||
|       } else { |       } else { | ||||||
|   | |||||||
| @@ -14,16 +14,17 @@ | |||||||
|  |  | ||||||
| package com.google.gerrit.httpd.gitweb; | package com.google.gerrit.httpd.gitweb; | ||||||
|  |  | ||||||
|  | import com.google.common.io.ByteStreams; | ||||||
| import com.google.gerrit.httpd.GitWebConfig; | import com.google.gerrit.httpd.GitWebConfig; | ||||||
| import com.google.gwtexpui.server.CacheHeaders; | import com.google.gwtexpui.server.CacheHeaders; | ||||||
| import com.google.inject.Inject; | import com.google.inject.Inject; | ||||||
| import com.google.inject.Singleton; | import com.google.inject.Singleton; | ||||||
|  |  | ||||||
| import org.eclipse.jgit.util.IO; |  | ||||||
|  |  | ||||||
| import java.io.File; |  | ||||||
| import java.io.FileNotFoundException; | import java.io.FileNotFoundException; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
|  | import java.io.InputStream; | ||||||
|  | import java.nio.file.Files; | ||||||
|  | import java.nio.file.Path; | ||||||
| import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||||
|  |  | ||||||
| import javax.servlet.ServletOutputStream; | import javax.servlet.ServletOutputStream; | ||||||
| @@ -40,14 +41,14 @@ class GitWebJavaScriptServlet extends HttpServlet { | |||||||
|   @Inject |   @Inject | ||||||
|   GitWebJavaScriptServlet(final GitWebConfig gitWebConfig) throws IOException { |   GitWebJavaScriptServlet(final GitWebConfig gitWebConfig) throws IOException { | ||||||
|     byte[] png; |     byte[] png; | ||||||
|     final File src = gitWebConfig.getGitwebJS(); |     Path src = gitWebConfig.getGitwebJS(); | ||||||
|     if (src != null) { |     if (src != null) { | ||||||
|       try { |       try (InputStream in = Files.newInputStream(src)) { | ||||||
|         png = IO.readFully(src); |         png = ByteStreams.toByteArray(in); | ||||||
|       } catch (FileNotFoundException e) { |       } catch (FileNotFoundException e) { | ||||||
|         png = null; |         png = null; | ||||||
|       } |       } | ||||||
|       modified = src.lastModified(); |       modified = Files.getLastModifiedTime(src).toMillis(); | ||||||
|     } else { |     } else { | ||||||
|       modified = -1; |       modified = -1; | ||||||
|       png = null; |       png = null; | ||||||
|   | |||||||
| @@ -29,6 +29,8 @@ | |||||||
|  |  | ||||||
| package com.google.gerrit.httpd.gitweb; | package com.google.gerrit.httpd.gitweb; | ||||||
|  |  | ||||||
|  | import static java.nio.charset.StandardCharsets.UTF_8; | ||||||
|  |  | ||||||
| import com.google.gerrit.common.data.GerritConfig; | import com.google.gerrit.common.data.GerritConfig; | ||||||
| import com.google.gerrit.extensions.restapi.Url; | import com.google.gerrit.extensions.restapi.Url; | ||||||
| import com.google.gerrit.httpd.GitWebConfig; | import com.google.gerrit.httpd.GitWebConfig; | ||||||
| @@ -54,7 +56,6 @@ import java.io.BufferedInputStream; | |||||||
| import java.io.BufferedReader; | import java.io.BufferedReader; | ||||||
| import java.io.EOFException; | import java.io.EOFException; | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.io.FileWriter; |  | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.io.InputStream; | import java.io.InputStream; | ||||||
| import java.io.InputStreamReader; | import java.io.InputStreamReader; | ||||||
| @@ -63,6 +64,7 @@ import java.io.PrintWriter; | |||||||
| import java.net.URI; | import java.net.URI; | ||||||
| import java.net.URISyntaxException; | import java.net.URISyntaxException; | ||||||
| import java.nio.file.Files; | import java.nio.file.Files; | ||||||
|  | import java.nio.file.Path; | ||||||
| import java.util.Enumeration; | import java.util.Enumeration; | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
| import java.util.HashSet; | import java.util.HashSet; | ||||||
| @@ -82,7 +84,7 @@ class GitWebServlet extends HttpServlet { | |||||||
|  |  | ||||||
|   private final Set<String> deniedActions; |   private final Set<String> deniedActions; | ||||||
|   private final int bufferSize = 8192; |   private final int bufferSize = 8192; | ||||||
|   private final File gitwebCgi; |   private final Path gitwebCgi; | ||||||
|   private final URI gitwebUrl; |   private final URI gitwebUrl; | ||||||
|   private final LocalDiskRepositoryManager repoManager; |   private final LocalDiskRepositoryManager repoManager; | ||||||
|   private final ProjectControl.Factory projectControl; |   private final ProjectControl.Factory projectControl; | ||||||
| @@ -147,24 +149,25 @@ class GitWebServlet extends HttpServlet { | |||||||
|     if (!Files.exists(site.tmp_dir)) { |     if (!Files.exists(site.tmp_dir)) { | ||||||
|       Files.createDirectories(site.tmp_dir); |       Files.createDirectories(site.tmp_dir); | ||||||
|     } |     } | ||||||
|     File myconf = Files.createTempFile(site.tmp_dir, "gitweb_config", ".perl") |     Path myconf = Files.createTempFile(site.tmp_dir, "gitweb_config", ".perl"); | ||||||
|         .toFile(); |  | ||||||
|  |  | ||||||
|     // To make our configuration file only readable or writable by us; |     // To make our configuration file only readable or writable by us; | ||||||
|     // this reduces the chances of someone tampering with the file. |     // this reduces the chances of someone tampering with the file. | ||||||
|     // |     // | ||||||
|     myconf.setWritable(false, false /* all */); |     // TODO(dborowitz): Is there a portable way to do this with NIO? | ||||||
|     myconf.setReadable(false, false /* all */); |     File myconfFile = myconf.toFile(); | ||||||
|     myconf.setExecutable(false, false /* all */); |     myconfFile.setWritable(false, false /* all */); | ||||||
|  |     myconfFile.setReadable(false, false /* all */); | ||||||
|  |     myconfFile.setExecutable(false, false /* all */); | ||||||
|  |  | ||||||
|     myconf.setWritable(true, true /* owner only */); |     myconfFile.setWritable(true, true /* owner only */); | ||||||
|     myconf.setReadable(true, true /* owner only */); |     myconfFile.setReadable(true, true /* owner only */); | ||||||
|  |  | ||||||
|     _env.set("GIT_DIR", "."); |     _env.set("GIT_DIR", "."); | ||||||
|     _env.set("GITWEB_CONFIG", myconf.getAbsolutePath()); |     _env.set("GITWEB_CONFIG", myconf.toAbsolutePath().toString()); | ||||||
|  |  | ||||||
|     final PrintWriter p = new PrintWriter(new FileWriter(myconf)); |     try (PrintWriter p = | ||||||
|     try { |         new PrintWriter(Files.newBufferedWriter(myconf, UTF_8))) { | ||||||
|       p.print("# Autogenerated by Gerrit Code Review \n"); |       p.print("# Autogenerated by Gerrit Code Review \n"); | ||||||
|       p.print("# DO NOT EDIT\n"); |       p.print("# DO NOT EDIT\n"); | ||||||
|       p.print("\n"); |       p.print("\n"); | ||||||
| @@ -172,12 +175,12 @@ class GitWebServlet extends HttpServlet { | |||||||
|       // We are mounted at the same level in the context as the main |       // We are mounted at the same level in the context as the main | ||||||
|       // UI, so we can include the same header and footer scheme. |       // UI, so we can include the same header and footer scheme. | ||||||
|       // |       // | ||||||
|       final File hdr = site.site_header; |       Path hdr = site.site_header; | ||||||
|       if (hdr.isFile()) { |       if (Files.isRegularFile(hdr)) { | ||||||
|         p.print("$site_header = " + quoteForPerl(hdr) + ";\n"); |         p.print("$site_header = " + quoteForPerl(hdr) + ";\n"); | ||||||
|       } |       } | ||||||
|       final File ftr = site.site_footer; |       Path ftr = site.site_footer; | ||||||
|       if (ftr.isFile()) { |       if (Files.isRegularFile(ftr)) { | ||||||
|         p.print("$site_footer = " + quoteForPerl(ftr) + ";\n"); |         p.print("$site_footer = " + quoteForPerl(ftr) + ";\n"); | ||||||
|       } |       } | ||||||
|  |  | ||||||
| @@ -190,8 +193,8 @@ class GitWebServlet extends HttpServlet { | |||||||
|       p.print("$logo = 'gitweb-logo.png';\n"); |       p.print("$logo = 'gitweb-logo.png';\n"); | ||||||
|       p.print("$javascript = 'gitweb.js';\n"); |       p.print("$javascript = 'gitweb.js';\n"); | ||||||
|       p.print("@stylesheets = ('gitweb-default.css');\n"); |       p.print("@stylesheets = ('gitweb-default.css');\n"); | ||||||
|       final File css = site.site_css; |       Path css = site.site_css; | ||||||
|       if (css.isFile()) { |       if (Files.isRegularFile(css)) { | ||||||
|         p.print("push @stylesheets, 'gitweb-site.css';\n"); |         p.print("push @stylesheets, 'gitweb-site.css';\n"); | ||||||
|       } |       } | ||||||
|  |  | ||||||
| @@ -292,15 +295,15 @@ class GitWebServlet extends HttpServlet { | |||||||
|       // If the administrator has created a site-specific gitweb_config, |       // If the administrator has created a site-specific gitweb_config, | ||||||
|       // load that before we perform any final overrides. |       // load that before we perform any final overrides. | ||||||
|       // |       // | ||||||
|       final File sitecfg = site.site_gitweb; |       Path sitecfg = site.site_gitweb; | ||||||
|       if (sitecfg.isFile()) { |       if (Files.isRegularFile(sitecfg)) { | ||||||
|         p.print("$GITWEB_CONFIG = " + quoteForPerl(sitecfg) + ";\n"); |         p.print("$GITWEB_CONFIG = " + quoteForPerl(sitecfg) + ";\n"); | ||||||
|         p.print("if (-e $GITWEB_CONFIG) {\n"); |         p.print("if (-e $GITWEB_CONFIG) {\n"); | ||||||
|         p.print("  do " + quoteForPerl(sitecfg) + ";\n"); |         p.print("  do " + quoteForPerl(sitecfg) + ";\n"); | ||||||
|         p.print("}\n"); |         p.print("}\n"); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       final File root = repoManager.getBasePath(); |       Path root = repoManager.getBasePath().toPath(); | ||||||
|       p.print("$projectroot = " + quoteForPerl(root) + ";\n"); |       p.print("$projectroot = " + quoteForPerl(root) + ";\n"); | ||||||
|  |  | ||||||
|       // Permit exporting only the project we were started for. |       // Permit exporting only the project we were started for. | ||||||
| @@ -324,18 +327,16 @@ class GitWebServlet extends HttpServlet { | |||||||
|       // |       // | ||||||
|       p.print("$feature{'forks'}{'override'} = 0;\n"); |       p.print("$feature{'forks'}{'override'} = 0;\n"); | ||||||
|       p.print("$feature{'forks'}{'default'} = [0];\n"); |       p.print("$feature{'forks'}{'default'} = [0];\n"); | ||||||
|     } finally { |  | ||||||
|       p.close(); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     myconf.setReadOnly(); |     myconfFile.setReadOnly(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private String quoteForPerl(File value) { |   private static String quoteForPerl(Path value) { | ||||||
|     return quoteForPerl(value.getAbsolutePath()); |     return quoteForPerl(value.toAbsolutePath().toString()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private String quoteForPerl(String value) { |   private static String quoteForPerl(String value) { | ||||||
|     if (value == null || value.isEmpty()) { |     if (value == null || value.isEmpty()) { | ||||||
|       return "''"; |       return "''"; | ||||||
|     } |     } | ||||||
| @@ -444,9 +445,10 @@ class GitWebServlet extends HttpServlet { | |||||||
|   private void exec(final HttpServletRequest req, |   private void exec(final HttpServletRequest req, | ||||||
|       final HttpServletResponse rsp, final ProjectControl project) throws IOException { |       final HttpServletResponse rsp, final ProjectControl project) throws IOException { | ||||||
|     final Process proc = |     final Process proc = | ||||||
|         Runtime.getRuntime().exec(new String[] {gitwebCgi.getAbsolutePath()}, |         Runtime.getRuntime().exec( | ||||||
|  |             new String[] {gitwebCgi.toAbsolutePath().toString()}, | ||||||
|             makeEnv(req, project), |             makeEnv(req, project), | ||||||
|             gitwebCgi.getAbsoluteFile().getParentFile()); |             gitwebCgi.toAbsolutePath().getParent().toFile()); | ||||||
|  |  | ||||||
|     copyStderrToLog(proc.getErrorStream()); |     copyStderrToLog(proc.getErrorStream()); | ||||||
|     if (0 < req.getContentLength()) { |     if (0 < req.getContentLength()) { | ||||||
| @@ -524,7 +526,7 @@ class GitWebServlet extends HttpServlet { | |||||||
|     // |     // | ||||||
|     env.set("REQUEST_METHOD", req.getMethod()); |     env.set("REQUEST_METHOD", req.getMethod()); | ||||||
|     env.set("SCRIPT_NAME", req.getContextPath() + req.getServletPath()); |     env.set("SCRIPT_NAME", req.getContextPath() + req.getServletPath()); | ||||||
|     env.set("SCRIPT_FILENAME", gitwebCgi.getAbsolutePath()); |     env.set("SCRIPT_FILENAME", gitwebCgi.toAbsolutePath().toString()); | ||||||
|     env.set("SERVER_NAME", req.getServerName()); |     env.set("SERVER_NAME", req.getServerName()); | ||||||
|     env.set("SERVER_PORT", Integer.toString(req.getServerPort())); |     env.set("SERVER_PORT", Integer.toString(req.getServerPort())); | ||||||
|     env.set("SERVER_PROTOCOL", req.getProtocol()); |     env.set("SERVER_PROTOCOL", req.getProtocol()); | ||||||
|   | |||||||
| @@ -14,6 +14,8 @@ | |||||||
|  |  | ||||||
| package com.google.gerrit.httpd.raw; | package com.google.gerrit.httpd.raw; | ||||||
|  |  | ||||||
|  | import static java.nio.file.Files.getLastModifiedTime; | ||||||
|  |  | ||||||
| import com.google.common.base.Strings; | import com.google.common.base.Strings; | ||||||
| import com.google.common.collect.Lists; | import com.google.common.collect.Lists; | ||||||
| import com.google.common.hash.Hasher; | import com.google.common.hash.Hasher; | ||||||
| @@ -47,12 +49,13 @@ import org.w3c.dom.Document; | |||||||
| import org.w3c.dom.Element; | import org.w3c.dom.Element; | ||||||
| import org.w3c.dom.Node; | import org.w3c.dom.Node; | ||||||
|  |  | ||||||
| import java.io.File; |  | ||||||
| import java.io.FileNotFoundException; | import java.io.FileNotFoundException; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.io.InputStream; | import java.io.InputStream; | ||||||
| import java.io.OutputStream; | import java.io.OutputStream; | ||||||
| import java.io.StringWriter; | import java.io.StringWriter; | ||||||
|  | import java.nio.file.Path; | ||||||
|  | import java.nio.file.attribute.FileTime; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| @@ -160,16 +163,13 @@ public class HostPageServlet extends HttpServlet { | |||||||
|  |  | ||||||
|   private Page get() { |   private Page get() { | ||||||
|     Page p = page; |     Page p = page; | ||||||
|     if (refreshHeaderFooter && p.isStale()) { |     try { | ||||||
|       final Page newPage; |       if (refreshHeaderFooter && p.isStale()) { | ||||||
|       try { |         p = new Page(); | ||||||
|         newPage = new Page(); |         page = p; | ||||||
|       } catch (IOException e) { |  | ||||||
|         log.error("Cannot refresh site header/footer", e); |  | ||||||
|         return p; |  | ||||||
|       } |       } | ||||||
|       p = newPage; |     } catch (IOException e) { | ||||||
|       page = p; |       log.error("Cannot refresh site header/footer", e); | ||||||
|     } |     } | ||||||
|     return p; |     return p; | ||||||
|   } |   } | ||||||
| @@ -288,16 +288,16 @@ public class HostPageServlet extends HttpServlet { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   private static class FileInfo { |   private static class FileInfo { | ||||||
|     private final File path; |     private final Path path; | ||||||
|     private final long time; |     private final FileTime time; | ||||||
|  |  | ||||||
|     FileInfo(final File p) { |     FileInfo(Path p) throws IOException { | ||||||
|       path = p; |       path = p; | ||||||
|       time = path.lastModified(); |       time = getLastModifiedTime(path); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     boolean isStale() { |     boolean isStale() throws IOException { | ||||||
|       return time != path.lastModified(); |       return !time.equals(getLastModifiedTime(path)); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -340,7 +340,7 @@ public class HostPageServlet extends HttpServlet { | |||||||
|       debug = new Content(hostDoc); |       debug = new Content(hostDoc); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     boolean isStale() { |     boolean isStale() throws IOException { | ||||||
|       return css.isStale() || header.isStale() || footer.isStale(); |       return css.isStale() || header.isStale() || footer.isStale(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -364,8 +364,8 @@ public class HostPageServlet extends HttpServlet { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private FileInfo injectCssFile(final Document hostDoc, final String id, |     private FileInfo injectCssFile(Document hostDoc, String id, Path src) | ||||||
|         final File src) throws IOException { |         throws IOException { | ||||||
|       final FileInfo info = new FileInfo(src); |       final FileInfo info = new FileInfo(src); | ||||||
|       final Element banner = HtmlDomUtil.find(hostDoc, id); |       final Element banner = HtmlDomUtil.find(hostDoc, id); | ||||||
|       if (banner == null) { |       if (banner == null) { | ||||||
| @@ -376,7 +376,8 @@ public class HostPageServlet extends HttpServlet { | |||||||
|         banner.removeChild(banner.getFirstChild()); |         banner.removeChild(banner.getFirstChild()); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       String css = HtmlDomUtil.readFile(src.getParentFile(), src.getName()); |       String css = | ||||||
|  |           HtmlDomUtil.readFile(src.getParent(), src.getFileName().toString()); | ||||||
|       if (css == null) { |       if (css == null) { | ||||||
|         return info; |         return info; | ||||||
|       } |       } | ||||||
| @@ -385,8 +386,8 @@ public class HostPageServlet extends HttpServlet { | |||||||
|       return info; |       return info; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private FileInfo injectXmlFile(final Document hostDoc, final String id, |     private FileInfo injectXmlFile(Document hostDoc, String id, Path src) | ||||||
|         final File src) throws IOException { |         throws IOException { | ||||||
|       final FileInfo info = new FileInfo(src); |       final FileInfo info = new FileInfo(src); | ||||||
|       final Element banner = HtmlDomUtil.find(hostDoc, id); |       final Element banner = HtmlDomUtil.find(hostDoc, id); | ||||||
|       if (banner == null) { |       if (banner == null) { | ||||||
|   | |||||||
| @@ -27,8 +27,10 @@ import org.slf4j.LoggerFactory; | |||||||
| import org.w3c.dom.Document; | import org.w3c.dom.Document; | ||||||
| import org.w3c.dom.Element; | import org.w3c.dom.Element; | ||||||
|  |  | ||||||
| import java.io.File; |  | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
|  | import java.nio.file.Files; | ||||||
|  | import java.nio.file.Path; | ||||||
|  | import java.nio.file.attribute.FileTime; | ||||||
|  |  | ||||||
| @Singleton | @Singleton | ||||||
| public class SiteHeaderFooter { | public class SiteHeaderFooter { | ||||||
| @@ -43,13 +45,13 @@ public class SiteHeaderFooter { | |||||||
|     this.refreshHeaderFooter = cfg.getBoolean("site", "refreshHeaderFooter", true); |     this.refreshHeaderFooter = cfg.getBoolean("site", "refreshHeaderFooter", true); | ||||||
|     this.sitePaths = sitePaths; |     this.sitePaths = sitePaths; | ||||||
|  |  | ||||||
|     Template t = new Template(sitePaths); |  | ||||||
|     try { |     try { | ||||||
|  |       Template t = new Template(sitePaths); | ||||||
|       t.load(); |       t.load(); | ||||||
|  |       template = t; | ||||||
|     } catch (IOException e) { |     } catch (IOException e) { | ||||||
|       log.warn("Cannot load site header or footer", e); |       log.warn("Cannot load site header or footer", e); | ||||||
|     } |     } | ||||||
|     template = t; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public Document parse(Class<?> clazz, String name) throws IOException { |   public Document parse(Class<?> clazz, String name) throws IOException { | ||||||
| @@ -110,7 +112,7 @@ public class SiteHeaderFooter { | |||||||
|     Element header; |     Element header; | ||||||
|     Element footer; |     Element footer; | ||||||
|  |  | ||||||
|     Template(SitePaths site) { |     Template(SitePaths site) throws IOException { | ||||||
|       cssFile = new FileInfo(site.site_css); |       cssFile = new FileInfo(site.site_css); | ||||||
|       headerFile = new FileInfo(site.site_header); |       headerFile = new FileInfo(site.site_header); | ||||||
|       footerFile = new FileInfo(site.site_footer); |       footerFile = new FileInfo(site.site_footer); | ||||||
| @@ -118,13 +120,13 @@ public class SiteHeaderFooter { | |||||||
|  |  | ||||||
|     void load() throws IOException { |     void load() throws IOException { | ||||||
|       css = HtmlDomUtil.readFile( |       css = HtmlDomUtil.readFile( | ||||||
|           cssFile.path.getParentFile(), |           cssFile.path.getParent(), | ||||||
|           cssFile.path.getName()); |           cssFile.path.getFileName().toString()); | ||||||
|       header = readXml(headerFile); |       header = readXml(headerFile); | ||||||
|       footer = readXml(footerFile); |       footer = readXml(footerFile); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     boolean isStale() { |     boolean isStale() throws IOException { | ||||||
|       return cssFile.isStale() || headerFile.isStale() || footerFile.isStale(); |       return cssFile.isStale() || headerFile.isStale() || footerFile.isStale(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -135,16 +137,16 @@ public class SiteHeaderFooter { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   private static class FileInfo { |   private static class FileInfo { | ||||||
|     final File path; |     final Path path; | ||||||
|     final long time; |     final FileTime time; | ||||||
|  |  | ||||||
|     FileInfo(File p) { |     FileInfo(Path p) throws IOException { | ||||||
|       path = p; |       path = p; | ||||||
|       time = path.lastModified(); |       time = Files.getLastModifiedTime(path); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     boolean isStale() { |     boolean isStale() throws IOException { | ||||||
|       return time != path.lastModified(); |       return !time.equals(Files.getLastModifiedTime(path)); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -56,10 +56,10 @@ public final class SitePaths { | |||||||
|   public final File ssh_dsa; |   public final File ssh_dsa; | ||||||
|   public final File peer_keys; |   public final File peer_keys; | ||||||
|  |  | ||||||
|   public final File site_css; |   public final Path site_css; | ||||||
|   public final File site_header; |   public final Path site_header; | ||||||
|   public final File site_footer; |   public final Path site_footer; | ||||||
|   public final File site_gitweb; |   public final Path site_gitweb; | ||||||
|  |  | ||||||
|   /** {@code true} if {@link #site_path} has not been initialized. */ |   /** {@code true} if {@link #site_path} has not been initialized. */ | ||||||
|   public final boolean isNew; |   public final boolean isNew; | ||||||
| @@ -96,10 +96,11 @@ public final class SitePaths { | |||||||
|     ssh_dsa = new File(etc_dir, "ssh_host_dsa_key"); |     ssh_dsa = new File(etc_dir, "ssh_host_dsa_key"); | ||||||
|     peer_keys = new File(etc_dir, "peer_keys"); |     peer_keys = new File(etc_dir, "peer_keys"); | ||||||
|  |  | ||||||
|     site_css = new File(etc_dir, CSS_FILENAME); |     Path etcDirPath = etc_dir.toPath(); | ||||||
|     site_header = new File(etc_dir, HEADER_FILENAME); |     site_css = etcDirPath.resolve(CSS_FILENAME); | ||||||
|     site_footer = new File(etc_dir, FOOTER_FILENAME); |     site_header = etcDirPath.resolve(HEADER_FILENAME); | ||||||
|     site_gitweb = new File(etc_dir, "gitweb_config.perl"); |     site_footer = etcDirPath.resolve(FOOTER_FILENAME); | ||||||
|  |     site_gitweb = etcDirPath.resolve("gitweb_config.perl"); | ||||||
|  |  | ||||||
|     if (site_path.exists()) { |     if (site_path.exists()) { | ||||||
|       final String[] contents = site_path.list(); |       final String[] contents = site_path.list(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Dave Borowitz
					Dave Borowitz