// Copyright (C) 2009 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.

// CGI environment and execution management portions are:
//
// ========================================================================
// Copyright (c) 2006-2009 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================

package com.google.gerrit.httpd.gitweb;

import static java.nio.charset.StandardCharsets.ISO_8859_1;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.reviewdb.client.Project;
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.GitRepositoryManager;
import com.google.gerrit.server.git.LocalDiskRepositoryManager;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.ProjectPermission;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.ssh.SshInfo;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.ProvisionException;
import com.google.inject.Singleton;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Repository;

/** Invokes {@code gitweb.cgi} for the project given in {@code p}. */
@SuppressWarnings("serial")
@Singleton
class GitwebServlet extends HttpServlet {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private static final String PROJECT_LIST_ACTION = "project_list";

  private final Set<String> deniedActions;
  private final int bufferSize = 8192;
  private final Path gitwebCgi;
  private final URI gitwebUrl;
  private final LocalDiskRepositoryManager repoManager;
  private final ProjectCache projectCache;
  private final PermissionBackend permissionBackend;
  private final Provider<AnonymousUser> anonymousUserProvider;
  private final Provider<CurrentUser> userProvider;
  private final EnvList _env;

  @Inject
  GitwebServlet(
      GitRepositoryManager repoManager,
      ProjectCache projectCache,
      PermissionBackend permissionBackend,
      Provider<CurrentUser> userProvider,
      SitePaths site,
      @GerritServerConfig Config cfg,
      SshInfo sshInfo,
      Provider<AnonymousUser> anonymousUserProvider,
      GitwebConfig gitwebConfig,
      GitwebCgiConfig gitwebCgiConfig)
      throws IOException {
    if (!(repoManager instanceof LocalDiskRepositoryManager)) {
      throw new ProvisionException("Gitweb can only be used with LocalDiskRepositoryManager");
    }
    this.repoManager = (LocalDiskRepositoryManager) repoManager;
    this.projectCache = projectCache;
    this.permissionBackend = permissionBackend;
    this.anonymousUserProvider = anonymousUserProvider;
    this.userProvider = userProvider;
    this.gitwebCgi = gitwebCgiConfig.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) {
        logger.atSevere().log("Invalid gitweb.url: %s", url);
      }
      gitwebUrl = uri;
    } else {
      gitwebUrl = null;
    }

    deniedActions.add("forks");
    deniedActions.add("opml");
    deniedActions.add("project_index");

    _env = new EnvList();
    makeSiteConfig(site, cfg, sshInfo);

    if (!_env.envMap.containsKey("SystemRoot")) {
      String os = System.getProperty("os.name");
      if (os != null && os.toLowerCase().contains("windows")) {
        String sysroot = System.getenv("SystemRoot");
        if (sysroot == null || sysroot.isEmpty()) {
          sysroot = "C:\\WINDOWS";
        }
        _env.set("SystemRoot", sysroot);
      }
    }

    if (!_env.envMap.containsKey("PATH")) {
      _env.set("PATH", System.getenv("PATH"));
    }
  }

  private void makeSiteConfig(SitePaths site, Config cfg, SshInfo sshInfo) throws IOException {
    if (!Files.exists(site.tmp_dir)) {
      Files.createDirectories(site.tmp_dir);
    }
    Path myconf = Files.createTempFile(site.tmp_dir, "gitweb_config", ".perl");

    // To make our configuration file only readable or writable by us;
    // this reduces the chances of someone tampering with the file.
    //
    // TODO(dborowitz): Is there a portable way to do this with NIO?
    File myconfFile = myconf.toFile();
    myconfFile.setWritable(false, false /* all */);
    myconfFile.setReadable(false, false /* all */);
    myconfFile.setExecutable(false, false /* all */);

    myconfFile.setWritable(true, true /* owner only */);
    myconfFile.setReadable(true, true /* owner only */);

    myconfFile.deleteOnExit();

    _env.set("GIT_DIR", ".");
    _env.set("GITWEB_CONFIG", myconf.toAbsolutePath().toString());

    try (PrintWriter p = new PrintWriter(Files.newBufferedWriter(myconf, UTF_8))) {
      p.print("# Autogenerated by Gerrit Code Review \n");
      p.print("# DO NOT EDIT\n");
      p.print("\n");

      // We are mounted at the same level in the context as the main
      // UI, so we can include the same header and footer scheme.
      //
      Path hdr = site.site_header;
      if (Files.isRegularFile(hdr)) {
        p.print("$site_header = " + quoteForPerl(hdr) + ";\n");
      }
      Path ftr = site.site_footer;
      if (Files.isRegularFile(ftr)) {
        p.print("$site_footer = " + quoteForPerl(ftr) + ";\n");
      }

      // Top level should return to Gerrit's UI.
      //
      p.print("$home_link = $ENV{'GERRIT_CONTEXT_PATH'};\n");
      p.print("$home_link_str = 'Code Review';\n");

      p.print("$favicon = 'favicon.ico';\n");
      p.print("$logo = 'gitweb-logo.png';\n");
      p.print("$javascript = 'gitweb.js';\n");
      p.print("@stylesheets = ('gitweb-default.css');\n");
      Path css = site.site_css;
      if (Files.isRegularFile(css)) {
        p.print("push @stylesheets, 'gitweb-site.css';\n");
      }

      // Try to make the title match Gerrit's normal window title
      // scheme of host followed by 'Code Review'.
      //
      p.print("$site_name = $home_link_str;\n");
      p.print("$site_name = qq{$1 $site_name} if ");
      p.print("$ENV{'SERVER_NAME'} =~ m,^([^.]+(?:\\.[^.]+)?)(?:\\.|$),;\n");

      // Assume by default that XSS is a problem, and try to prevent it.
      //
      p.print("$prevent_xss = 1;\n");

      // Generate URLs using smart http://
      //
      p.print("{\n");
      p.print("  my $secure = $ENV{'HTTPS'} =~ /^ON$/i;\n");
      p.print("  my $http_url = $secure ? 'https://' : 'http://';\n");
      p.print("  $http_url .= qq{$ENV{'GERRIT_USER_NAME'}@}\n");
      p.print("    unless $ENV{'GERRIT_ANONYMOUS_READ'};\n");
      p.print("  $http_url .= $ENV{'SERVER_NAME'};\n");
      p.print("  $http_url .= qq{:$ENV{'SERVER_PORT'}}\n");
      p.print("    if (( $secure && $ENV{'SERVER_PORT'} != 443)\n");
      p.print("     || (!$secure && $ENV{'SERVER_PORT'} != 80)\n");
      p.print("    );\n");
      p.print("  my $context = $ENV{'GERRIT_CONTEXT_PATH'};\n");
      p.print("  chop($context);\n");
      p.print("  $http_url .= qq{$context};\n");
      p.print("  $http_url .= qq{/a}\n");
      p.print("    unless $ENV{'GERRIT_ANONYMOUS_READ'};\n");
      p.print("  push @git_base_url_list, $http_url;\n");
      p.print("}\n");

      // Generate URLs using anonymous git://
      //
      String url = cfg.getString("gerrit", null, "canonicalGitUrl");
      if (url != null) {
        if (url.endsWith("/")) {
          url = url.substring(0, url.length() - 1);
        }
        p.print("if ($ENV{'GERRIT_ANONYMOUS_READ'}) {\n");
        p.print("  push @git_base_url_list, ");
        p.print(quoteForPerl(url));
        p.print(";\n");
        p.print("}\n");
      }

      // Generate URLs using authenticated ssh://
      //
      if (sshInfo != null && !sshInfo.getHostKeys().isEmpty()) {
        String sshAddr = sshInfo.getHostKeys().get(0).getHost();
        p.print("if ($ENV{'GERRIT_USER_NAME'}) {\n");
        p.print("  push @git_base_url_list, join('', 'ssh://'");
        p.print(", $ENV{'GERRIT_USER_NAME'}");
        p.print(", '@'");
        if (sshAddr.startsWith("*:") || "".equals(sshAddr)) {
          p.print(", $ENV{'SERVER_NAME'}");
        }
        if (sshAddr.startsWith("*")) {
          sshAddr = sshAddr.substring(1);
        }
        p.print(", " + quoteForPerl(sshAddr));
        p.print(");\n");
        p.print("}\n");
      }

      // Link back to Gerrit (when possible, to matching review record).
      // Supported gitweb's hash values are:
      // - (missing),
      // - HEAD,
      // - refs/heads/<branch>,
      // - refs/changes/*/<change>/*,
      // - <revision>.
      //
      p.print("sub add_review_link {\n");
      p.print("  my $h = shift;\n");
      p.print("  my $q;\n");
      p.print("  if (!$h || $h eq 'HEAD') {\n");
      p.print("    $q = qq{#/q/project:$ENV{'GERRIT_PROJECT_NAME'}};\n");
      p.print("  } elsif ($h =~ /^refs\\/heads\\/([-\\w]+)$/) {\n");
      p.print("    $q = qq{#/q/project:$ENV{'GERRIT_PROJECT_NAME'}");
      p.print("+branch:$1};\n"); // wrapped
      p.print("  } elsif ($h =~ /^refs\\/changes\\/\\d{2}\\/(\\d+)\\/\\d+$/) ");
      p.print("{\n"); // wrapped
      p.print("    $q = qq{#/c/$1};\n");
      p.print("  } else {\n");
      p.print("    $q = qq{#/q/$h};\n");
      p.print("  }\n");
      p.print("  my $r = qq{$ENV{'GERRIT_CONTEXT_PATH'}$q};\n");
      p.print("  push @{$feature{'actions'}{'default'}},\n");
      p.print("      ('review',$r,'commitdiff');\n");
      p.print("}\n");
      p.print("if ($cgi->param('hb')) {\n");
      p.print("  add_review_link(scalar $cgi->param('hb'));\n");
      p.print("} elsif ($cgi->param('h')) {\n");
      p.print("  add_review_link(scalar $cgi->param('h'));\n");
      p.print("} else {\n");
      p.print("  add_review_link();\n");
      p.print("}\n");

      // If the administrator has created a site-specific gitweb_config,
      // load that before we perform any final overrides.
      //
      Path sitecfg = site.site_gitweb;
      if (Files.isRegularFile(sitecfg)) {
        p.print("$GITWEB_CONFIG = " + quoteForPerl(sitecfg) + ";\n");
        p.print("if (-e $GITWEB_CONFIG) {\n");
        p.print("  do " + quoteForPerl(sitecfg) + ";\n");
        p.print("}\n");
      }

      p.print("$projectroot = $ENV{'GITWEB_PROJECTROOT'};\n");

      // Permit exporting only the project we were started for.
      // We use the name under $projectroot in case symlinks
      // were involved in the path.
      //
      p.print("$export_auth_hook = sub {\n");
      p.print("    my $dir = shift;\n");
      p.print("    my $name = $ENV{'GERRIT_PROJECT_NAME'};\n");
      p.print("    my $allow = qq{$projectroot/$name.git};\n");
      p.print("    return $dir eq $allow;\n");
      p.print("  };\n");

      // Do not allow the administrator to enable path info, its
      // not a URL format we currently support.
      //
      p.print("$feature{'pathinfo'}{'override'} = 0;\n");
      p.print("$feature{'pathinfo'}{'default'} = [0];\n");

      // We don't do forking, so don't allow it to be enabled.
      //
      p.print("$feature{'forks'}{'override'} = 0;\n");
      p.print("$feature{'forks'}{'default'} = [0];\n");
    }

    myconfFile.setReadOnly();
  }

  private static String quoteForPerl(Path value) {
    return quoteForPerl(value.toAbsolutePath().toString());
  }

  private static String quoteForPerl(String value) {
    if (value == null || value.isEmpty()) {
      return "''";
    }
    if (!value.contains("'")) {
      return "'" + value + "'";
    }
    if (!value.contains("{") && !value.contains("}")) {
      return "q{" + value + "}";
    }
    throw new IllegalArgumentException("Cannot quote in Perl: " + value);
  }

  @Override
  protected void service(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
    if (req.getQueryString() == null || req.getQueryString().isEmpty()) {
      // No query string? They want the project list, which we don't
      // currently support. Return to Gerrit's own web UI.
      //
      rsp.sendRedirect(req.getContextPath() + "/");
      return;
    }

    final Map<String, String> params = getParameters(req);
    String a = params.get("a");
    if (a != null) {
      if (deniedActions.contains(a)) {
        rsp.sendError(HttpServletResponse.SC_FORBIDDEN);
        return;
      }

      if (a.equals(PROJECT_LIST_ACTION)) {
        rsp.sendRedirect(
            req.getContextPath()
                + "/#"
                + PageLinks.ADMIN_PROJECTS
                + "?filter="
                + Url.encode(params.get("pf") + "/"));
        return;
      }
    }

    String name = params.get("p");
    if (name == null) {
      rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    }
    if (name.endsWith(".git")) {
      name = name.substring(0, name.length() - 4);
    }

    Project.NameKey nameKey = new Project.NameKey(name);
    ProjectState projectState;
    try {
      projectState = projectCache.checkedGet(nameKey);
      if (projectState == null) {
        sendErrorOrRedirect(req, rsp, HttpServletResponse.SC_NOT_FOUND);
        return;
      }

      projectState.checkStatePermitsRead();
      permissionBackend.user(userProvider.get()).project(nameKey).check(ProjectPermission.READ);
    } catch (AuthException e) {
      sendErrorOrRedirect(req, rsp, HttpServletResponse.SC_NOT_FOUND);
      return;
    } catch (IOException | PermissionBackendException err) {
      logger.atSevere().withCause(err).log("cannot load %s", name);
      rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
      return;
    } catch (ResourceConflictException e) {
      sendErrorOrRedirect(req, rsp, HttpServletResponse.SC_CONFLICT);
      return;
    }

    try (Repository repo = repoManager.openRepository(nameKey)) {
      CacheHeaders.setNotCacheable(rsp);
      exec(req, rsp, projectState);
    } catch (RepositoryNotFoundException e) {
      getServletContext().log("Cannot open repository", e);
      rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }
  }

  /**
   * Sends error response if the user is authenticated. Or redirect the user to the login page. By
   * doing this, anonymous users cannot infer the existence of a resource from the status code.
   */
  private void sendErrorOrRedirect(HttpServletRequest req, HttpServletResponse rsp, int statusCode)
      throws IOException {
    if (userProvider.get().isIdentifiedUser()) {
      rsp.sendError(statusCode);
    } else {
      rsp.sendRedirect(getLoginRedirectUrl(req));
    }
  }

  private static String getLoginRedirectUrl(HttpServletRequest req) {
    String contextPath = req.getContextPath();
    String loginUrl = contextPath + "/login/";
    String token = req.getRequestURI();
    if (!contextPath.isEmpty()) {
      token = token.substring(contextPath.length());
    }

    String queryString = req.getQueryString();
    if (queryString != null && !queryString.isEmpty()) {
      token = token + "?" + queryString;
    }
    return (loginUrl + Url.encode(token));
  }

  private static Map<String, String> getParameters(HttpServletRequest req) {
    final Map<String, String> params = new HashMap<>();
    for (String pair : Splitter.on(CharMatcher.anyOf("&;")).split(req.getQueryString())) {
      final int eq = pair.indexOf('=');
      if (0 < eq) {
        String name = pair.substring(0, eq);
        String value = pair.substring(eq + 1);

        name = Url.decode(name);
        value = Url.decode(value);
        params.put(name, value);
      }
    }
    return params;
  }

  private void exec(HttpServletRequest req, HttpServletResponse rsp, ProjectState projectState)
      throws IOException {
    final Process proc =
        Runtime.getRuntime()
            .exec(
                new String[] {gitwebCgi.toAbsolutePath().toString()},
                makeEnv(req, projectState),
                gitwebCgi.toAbsolutePath().getParent().toFile());

    copyStderrToLog(proc.getErrorStream());
    if (0 < req.getContentLength()) {
      copyContentToCGI(req, proc.getOutputStream());
    } else {
      proc.getOutputStream().close();
    }

    try (InputStream in = new BufferedInputStream(proc.getInputStream(), bufferSize)) {
      readCgiHeaders(rsp, in);

      try (OutputStream out = rsp.getOutputStream()) {
        final byte[] buf = new byte[bufferSize];
        int n;
        while ((n = in.read(buf)) > 0) {
          out.write(buf, 0, n);
        }
      }
    } catch (IOException e) {
      // The browser has probably closed its input stream. We don't
      // want to continue executing this request.
      //
      proc.destroy();
      return;
    }

    try {
      proc.waitFor();

      final int status = proc.exitValue();
      if (0 != status) {
        logger.atSevere().log("Non-zero exit status (%d) from %s", status, gitwebCgi);
        if (!rsp.isCommitted()) {
          rsp.sendError(500);
        }
      }
    } catch (InterruptedException ie) {
      logger.atFine().log("CGI: interrupted waiting for CGI to terminate");
    }
  }

  private String[] makeEnv(HttpServletRequest req, ProjectState projectState) {
    final EnvList env = new EnvList(_env);
    final int contentLength = Math.max(0, req.getContentLength());

    // These ones are from "The WWW Common Gateway Interface Version 1.1"
    //
    env.set("AUTH_TYPE", req.getAuthType());
    env.set("CONTENT_LENGTH", Integer.toString(contentLength));
    env.set("CONTENT_TYPE", req.getContentType());
    env.set("GATEWAY_INTERFACE", "CGI/1.1");
    env.set("PATH_INFO", req.getPathInfo());
    env.set("PATH_TRANSLATED", null);
    env.set("QUERY_STRING", req.getQueryString());
    env.set("REMOTE_ADDR", req.getRemoteAddr());
    env.set("REMOTE_HOST", req.getRemoteHost());
    env.set("HTTPS", req.isSecure() ? "ON" : "OFF");

    // The identity information reported about the connection by a
    // RFC 1413 [11] request to the remote agent, if
    // available. Servers MAY choose not to support this feature, or
    // not to request the data for efficiency reasons.
    // "REMOTE_IDENT" => "NYI"
    //
    env.set("REQUEST_METHOD", req.getMethod());
    env.set("SCRIPT_NAME", req.getContextPath() + req.getServletPath());
    env.set("SCRIPT_FILENAME", gitwebCgi.toAbsolutePath().toString());
    env.set("SERVER_NAME", req.getServerName());
    env.set("SERVER_PORT", Integer.toString(req.getServerPort()));
    env.set("SERVER_PROTOCOL", req.getProtocol());
    env.set("SERVER_SOFTWARE", getServletContext().getServerInfo());

    final Enumeration<String> hdrs = enumerateHeaderNames(req);
    while (hdrs.hasMoreElements()) {
      final String name = hdrs.nextElement();
      final String value = req.getHeader(name);
      env.set("HTTP_" + name.toUpperCase().replace('-', '_'), value);
    }

    Project.NameKey nameKey = projectState.getNameKey();
    env.set("GERRIT_CONTEXT_PATH", req.getContextPath() + "/");
    env.set("GERRIT_PROJECT_NAME", nameKey.get());

    env.set("GITWEB_PROJECTROOT", repoManager.getBasePath(nameKey).toAbsolutePath().toString());

    if (projectState.statePermitsRead()
        && permissionBackend
            .user(anonymousUserProvider.get())
            .project(nameKey)
            .testOrFalse(ProjectPermission.READ)) {
      env.set("GERRIT_ANONYMOUS_READ", "1");
    }

    String remoteUser = null;
    if (userProvider.get().isIdentifiedUser()) {
      IdentifiedUser u = userProvider.get().asIdentifiedUser();
      Optional<String> user = u.getUserName();
      env.set("GERRIT_USER_NAME", user.orElse(null));
      remoteUser = user.orElseGet(() -> "account-" + u.getAccountId());
    }
    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();
  }

  private void copyContentToCGI(HttpServletRequest req, OutputStream dst) throws IOException {
    final int contentLength = req.getContentLength();
    final InputStream src = req.getInputStream();
    new Thread(
            () -> {
              try {
                try {
                  final byte[] buf = new byte[bufferSize];
                  int remaining = contentLength;
                  while (0 < remaining) {
                    final int max = Math.max(buf.length, remaining);
                    final int n = src.read(buf, 0, max);
                    if (n < 0) {
                      throw new EOFException("Expected " + remaining + " more bytes");
                    }
                    dst.write(buf, 0, n);
                    remaining -= n;
                  }
                } finally {
                  dst.close();
                }
              } catch (IOException e) {
                logger.atSevere().withCause(e).log("Unexpected error copying input to CGI");
              }
            },
            "Gitweb-InputFeeder")
        .start();
  }

  private void copyStderrToLog(InputStream in) {
    new Thread(
            () -> {
              StringBuilder b = new StringBuilder();
              try (BufferedReader br =
                  new BufferedReader(new InputStreamReader(in, ISO_8859_1.name()))) {
                String line;
                while ((line = br.readLine()) != null) {
                  if (b.length() > 0) {
                    b.append('\n');
                  }
                  b.append("CGI: ").append(line);
                }
                logger.atSevere().log(b.toString());
              } catch (IOException e) {
                logger.atSevere().withCause(e).log("Unexpected error copying stderr from CGI");
              }
            },
            "Gitweb-ErrorLogger")
        .start();
  }

  private static Enumeration<String> enumerateHeaderNames(HttpServletRequest req) {
    return req.getHeaderNames();
  }

  private void readCgiHeaders(HttpServletResponse res, InputStream in) throws IOException {
    String line;
    while (!(line = readLine(in)).isEmpty()) {
      if (line.startsWith("HTTP")) {
        // CGI believes it is a non-parsed-header CGI. We refuse
        // to support that here so abort.
        //
        throw new IOException("NPH CGI not supported: " + line);
      }

      final int sep = line.indexOf(':');
      if (sep < 0) {
        throw new IOException("CGI returned invalid header: " + line);
      }

      final String key = line.substring(0, sep).trim();
      final String value = line.substring(sep + 1).trim();
      if ("Location".equalsIgnoreCase(key)) {
        res.sendRedirect(value);

      } else if ("Status".equalsIgnoreCase(key)) {
        final List<String> token = Splitter.on(' ').splitToList(value);
        final int status = Integer.parseInt(token.get(0));
        res.setStatus(status);

      } else {
        res.addHeader(key, value);
      }
    }
  }

  private String readLine(InputStream in) throws IOException {
    final StringBuilder buf = new StringBuilder();
    int b;
    while ((b = in.read()) != -1 && b != '\n') {
      buf.append((char) b);
    }
    return buf.toString().trim();
  }

  /** private utility class that manages the Environment passed to exec. */
  private static class EnvList {
    private Map<String, String> envMap;

    EnvList() {
      envMap = new HashMap<>();
    }

    EnvList(EnvList l) {
      envMap = new HashMap<>(l.envMap);
    }

    /** Set a name/value pair, null values will be treated as an empty String */
    public void set(String name, String value) {
      if (value == null) {
        value = "";
      }
      envMap.put(name, name + "=" + value);
    }

    /** Get representation suitable for passing to exec. */
    public String[] getEnvArray() {
      return envMap.values().toArray(new String[envMap.size()]);
    }

    @Override
    public String toString() {
      return envMap.toString();
    }
  }
}
