mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-12 00:15:44 +01:00
Merged in feature/ui-for-production (pull request #70)
Feature/ui for production
This commit is contained in:
@@ -1,24 +0,0 @@
|
||||
package sonia.scm;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This dispatcher forwards every request to the index.html of the application.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class ForwardingPushStateDispatcher implements PushStateDispatcher {
|
||||
@Override
|
||||
public void dispatch(HttpServletRequest request, HttpServletResponse response, String uri) throws IOException {
|
||||
RequestDispatcher dispatcher = request.getRequestDispatcher("/index.html");
|
||||
try {
|
||||
dispatcher.forward(request, response);
|
||||
} catch (ServletException e) {
|
||||
throw new IOException("failed to forward request", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,13 @@ package sonia.scm;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
/**
|
||||
* Injection Provider for the {@link PushStateDispatcher}. The provider will return a {@link ProxyPushStateDispatcher}
|
||||
* if the system property {@code PushStateDispatcherProvider#PROPERTY_TARGET} is set to a proxy target url, otherwise
|
||||
* a {@link ForwardingPushStateDispatcher} is used.
|
||||
* a {@link TemplatingPushStateDispatcher} is used.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@@ -17,11 +18,18 @@ public class PushStateDispatcherProvider implements Provider<PushStateDispatcher
|
||||
@VisibleForTesting
|
||||
static final String PROPERTY_TARGET = "sonia.scm.ui.proxy";
|
||||
|
||||
private Provider<TemplatingPushStateDispatcher> templatingPushStateDispatcherProvider;
|
||||
|
||||
@Inject
|
||||
public PushStateDispatcherProvider(Provider<TemplatingPushStateDispatcher> templatingPushStateDispatcherProvider) {
|
||||
this.templatingPushStateDispatcherProvider = templatingPushStateDispatcherProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushStateDispatcher get() {
|
||||
String target = System.getProperty(PROPERTY_TARGET);
|
||||
if (Strings.isNullOrEmpty(target)) {
|
||||
return new ForwardingPushStateDispatcher();
|
||||
return templatingPushStateDispatcherProvider.get();
|
||||
}
|
||||
return new ProxyPushStateDispatcher(target);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package sonia.scm;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import sonia.scm.template.Template;
|
||||
import sonia.scm.template.TemplateEngine;
|
||||
import sonia.scm.template.TemplateEngineFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* This dispatcher renders the /index.mustache template, which is merged in from the scm-ui package.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class TemplatingPushStateDispatcher implements PushStateDispatcher {
|
||||
|
||||
@VisibleForTesting
|
||||
static final String TEMPLATE = "/index.mustache";
|
||||
|
||||
private final TemplateEngine templateEngine;
|
||||
|
||||
@Inject
|
||||
public TemplatingPushStateDispatcher(TemplateEngineFactory templateEngineFactory) {
|
||||
this(templateEngineFactory.getDefaultEngine());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
TemplatingPushStateDispatcher(TemplateEngine templateEngine) {
|
||||
this.templateEngine = templateEngine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(HttpServletRequest request, HttpServletResponse response, String uri) throws IOException {
|
||||
response.setContentType("text/html");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
|
||||
Template template = templateEngine.getTemplate(TEMPLATE);
|
||||
try (Writer writer = response.getWriter()) {
|
||||
template.execute(writer, new IndexHtmlModel(request));
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class IndexHtmlModel {
|
||||
|
||||
private final HttpServletRequest request;
|
||||
|
||||
private IndexHtmlModel(HttpServletRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
public String getContextPath() {
|
||||
return request.getContextPath();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package sonia.scm;
|
||||
|
||||
import com.github.sdorra.webresources.WebResourceSender;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.io.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.filter.WebElement;
|
||||
@@ -15,7 +15,6 @@ import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
@@ -27,6 +26,7 @@ import java.net.URL;
|
||||
@WebElement(value = WebResourceServlet.PATTERN, regex = true)
|
||||
public class WebResourceServlet extends HttpServlet {
|
||||
|
||||
|
||||
/**
|
||||
* exclude api requests and the old frontend servlets.
|
||||
*
|
||||
@@ -37,6 +37,11 @@ public class WebResourceServlet extends HttpServlet {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(WebResourceServlet.class);
|
||||
|
||||
private final WebResourceSender sender = WebResourceSender.create()
|
||||
.withGZIP()
|
||||
.withGZIPMinLength(512)
|
||||
.withBufferSize(16384);
|
||||
|
||||
private final UberWebResourceLoader webResourceLoader;
|
||||
private final PushStateDispatcher pushStateDispatcher;
|
||||
|
||||
@@ -53,7 +58,7 @@ public class WebResourceServlet extends HttpServlet {
|
||||
LOG.trace("try to load {}", uri);
|
||||
URL url = webResourceLoader.getResource(uri);
|
||||
if (url != null) {
|
||||
serveResource(response, url);
|
||||
serveResource(request, response, url);
|
||||
} else {
|
||||
dispatch(request, response, uri);
|
||||
}
|
||||
@@ -72,10 +77,9 @@ public class WebResourceServlet extends HttpServlet {
|
||||
return HttpUtil.getStrippedURI(request);
|
||||
}
|
||||
|
||||
private void serveResource(HttpServletResponse response, URL url) {
|
||||
// TODO lastModifiedDate, if-... ???
|
||||
try (OutputStream output = response.getOutputStream()) {
|
||||
Resources.copy(url, output);
|
||||
private void serveResource(HttpServletRequest request, HttpServletResponse response, URL url) {
|
||||
try {
|
||||
sender.resource(url).send(request, response);
|
||||
} catch (IOException ex) {
|
||||
LOG.warn("failed to serve resource: {}", url);
|
||||
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
|
||||
@@ -31,18 +31,11 @@
|
||||
|
||||
package sonia.scm.plugin;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
@@ -55,47 +48,27 @@ import java.nio.file.Path;
|
||||
public class PathWebResourceLoader implements WebResourceLoader
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final String DEFAULT_SEPARATOR = "/";
|
||||
private static final String SEPARATOR = "/";
|
||||
|
||||
/**
|
||||
* the logger for PathWebResourceLoader
|
||||
*/
|
||||
private static final Logger logger =
|
||||
private static final Logger LOG =
|
||||
LoggerFactory.getLogger(PathWebResourceLoader.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param directory
|
||||
*/
|
||||
public PathWebResourceLoader(Path directory)
|
||||
{
|
||||
this.directory = directory;
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param path
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public URL getResource(String path)
|
||||
{
|
||||
public URL getResource(String path) {
|
||||
URL resource = null;
|
||||
Path file = directory.resolve(filePath(path));
|
||||
|
||||
if (Files.exists(file) && ! Files.isDirectory(file))
|
||||
{
|
||||
logger.trace("found path {} at {}", path, file);
|
||||
LOG.trace("found path {} at {}", path, file);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -103,56 +76,20 @@ public class PathWebResourceLoader implements WebResourceLoader
|
||||
}
|
||||
catch (MalformedURLException ex)
|
||||
{
|
||||
logger.error("could not transform path to url", ex);
|
||||
LOG.error("could not transform path to url", ex);
|
||||
}
|
||||
} else {
|
||||
LOG.trace("could not find file {}", file);
|
||||
}
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param path
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String filePath(String path)
|
||||
{
|
||||
|
||||
// TODO handle illegal path parts, such as ..
|
||||
String filePath = filePath(DEFAULT_SEPARATOR, path);
|
||||
|
||||
if (!DEFAULT_SEPARATOR.equals(File.separator))
|
||||
{
|
||||
filePath = filePath(File.separator, path);
|
||||
private String filePath(String path) {
|
||||
if (path.startsWith(SEPARATOR)) {
|
||||
return path.substring(1);
|
||||
}
|
||||
|
||||
return filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param separator
|
||||
* @param path
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String filePath(String separator, String path)
|
||||
{
|
||||
String filePath = path;
|
||||
|
||||
if (filePath.startsWith(separator))
|
||||
{
|
||||
filePath = filePath.substring(separator.length());
|
||||
}
|
||||
|
||||
return filePath;
|
||||
return path;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user