blob: d91f831f5712107b7f7ad3489cfd1da0b929b439 [file] [log] [blame]
// Copyright (C) 2013 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.googlesource.gerrit.plugins.gitiles;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.config.SitePaths;
import com.google.gitiles.GitilesAccess;
import com.google.gitiles.GitilesServlet;
import com.google.gitiles.GitilesUrls;
import com.google.gitiles.GitilesView;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.google.inject.servlet.ServletModule;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.transport.resolver.RepositoryResolver;
import org.eclipse.jgit.util.FS;
class HttpModule extends ServletModule {
private final Provider<CurrentUser> userProvider;
private final GitilesUrls urls;
@Inject
HttpModule(Provider<CurrentUser> userProvider, GitilesUrls urls) {
this.userProvider = userProvider;
this.urls = urls;
}
protected Filter createPathFilter() {
return new Filter() {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequestWrapper wrappedRequest =
new HttpServletRequestWrapper((HttpServletRequest) request) {
@Override
public String getRequestURI() {
try {
// Note: URLDecoder.decode() will decode "+" to a space.
// This doesn't work, so use URI.getPath() instead.
URI uri = new URI(super.getRequestURI());
return uri.getPath();
} catch (URISyntaxException e) {
return super.getRequestURI();
}
}
};
chain.doFilter(wrappedRequest, response);
}
@Override
public void destroy() {}
@Override
public void init(FilterConfig config) throws ServletException {}
};
}
private static final FluentLogger log = FluentLogger.forEnclosingClass();
@Override
protected void configureServlets() {
// Filter all paths so we can decode escaped entities in the URI
filter("/*").through(createPathFilter());
filter("/*").through(new LoginFilter(userProvider, urls));
// make this plugin's classloader the context classloader to prevent
// classloader issue when rendering markdown
filterRegex("^(/)$", "^(/[^+].*)").through(SetContextClassLoader.class);
// Let /+static, /+Documentation, etc. fall through to default servlet, but
// handle everything else.
serveRegex("^(/)$", "^(/[^+].*)").with(GitilesServlet.class);
}
@Provides
@Singleton
GitilesServlet getServlet(
@Named("gitiles") Config cfg,
GitilesUrls urls,
GitilesAccess.Factory accessFactory,
RepositoryResolver<HttpServletRequest> resolver,
MenuFilter menuFilter) {
GitilesServlet s =
new GitilesServlet(cfg, null, urls, accessFactory, resolver, null, null, null, null);
for (GitilesView.Type view : GitilesView.Type.values()) {
s.addFilter(view, menuFilter);
}
return s;
}
@Provides
@Named("gitiles")
Config getConfig(SitePaths site) throws IOException, ConfigInvalidException {
File cfgFile = site.etc_dir.resolve("gitiles.config").toFile();
FileBasedConfig cfg = new FileBasedConfig(cfgFile, FS.DETECTED);
if (cfg.getFile().exists()) {
cfg.load();
} else {
log.atInfo().log("No %s; assuming defaults", cfgFile.getAbsolutePath());
}
return cfg;
}
}