WIP: proxy
authorKai Moritz <kai@juplo.de>
Thu, 16 Jun 2016 10:00:43 +0000 (12:00 +0200)
committerKai Moritz <kai@juplo.de>
Thu, 16 Jun 2016 10:00:43 +0000 (12:00 +0200)
pom.xml
src/main/java/de/juplo/thymeproxy/Application.java
src/main/java/de/juplo/thymeproxy/ProxyHttpRequestHandler.java
src/main/resources/application.properties
src/main/resources/logback.xml [deleted file]

diff --git a/pom.xml b/pom.xml
index d58173c..01ceb99 100644 (file)
--- a/pom.xml
+++ b/pom.xml
 
     <!-- application-settings -->
     <thymeproxy.name>${project.name}</thymeproxy.name>
-    <thymeproxy.origin>http://localhost:8080</thymeproxy.origin>
+    <thymeproxy.origin>http://localhost:8080/</thymeproxy.origin>
     <thymeproxy.port>8888</thymeproxy.port>
     <thymeproxy.ttl>300000</thymeproxy.ttl><!-- 5 minutes -->
+    <httpclient.logging.level>ERROR</httpclient.logging.level>
 
     <!-- used versions (not defined in spring-boot) -->
     <httpclient-spring-boot-starter.version>1.0-SNAPSHOT</httpclient-spring-boot-starter.version>
index 47a60c9..c0293cd 100644 (file)
@@ -1,12 +1,15 @@
 package de.juplo.thymeproxy;
 
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.context.annotation.Bean;
 import org.springframework.core.Ordered;
 import org.springframework.core.env.Environment;
+import org.springframework.web.HttpRequestHandler;
 import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
 
 
@@ -20,7 +23,13 @@ public class Application
   {
     SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
     mapping.setOrder(Ordered.HIGHEST_PRECEDENCE);
-    mapping.setUrlMap(Collections.singletonMap("*.html", handler));
+    Map<String, HttpRequestHandler> mappings = new HashMap<>();
+    mappings.put("/*.html", handler);
+    mappings.put("/*/", handler);
+    mappings.put("/*/*.html", handler);
+    mappings.put("/**/", handler);
+    mappings.put("/**/*.html", handler);
+    mapping.setUrlMap(mappings);
        return mapping;
   }
 
index 8320c7e..41c3bdd 100644 (file)
@@ -15,6 +15,7 @@ import org.apache.http.Header;
 import org.apache.http.HeaderElement;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
+import org.apache.http.StatusLine;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.CloseableHttpClient;
@@ -78,7 +79,9 @@ public class ProxyHttpRequestHandler
         ServletException,
         IOException
   {
-       String path =
+    LOG.debug("handling: {}", request.getRequestURI());
+
+    String path =
         (String)
         request.getAttribute(
             HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE
@@ -99,26 +102,35 @@ public class ProxyHttpRequestHandler
     }
 
     String resource = builder.toString();
+    LOG.debug("requesting: {}", resource);
 
+    CloseableHttpResponse p_response = null;
     try
     {
       HttpGet p_request = new HttpGet(resource);
-      CloseableHttpResponse p_response = client.execute(p_request);
+
+      p_response = client.execute(p_request);
+
+      StatusLine status = p_response.getStatusLine();
+      int code = status.getStatusCode();
+      LOG.debug("response: {} - {}", code, status.getReasonPhrase());
 
       setCacheControl(computeCacheControl(p_response));
       prepareResponse(response);
 
-      Header length = p_response.getLastHeader("Content-Length");
-      if (length != null)
-        response.addHeader(length.getName(), length.getValue());
+      /** Copy some headers, if present.. */
+      ProxyHttpRequestHandler.copyHeader(p_response, response, "Date");
+      ProxyHttpRequestHandler.copyHeader(p_response, response, "ETag");
+      ProxyHttpRequestHandler.copyHeader(p_response, response, "Last-Modified");
+      ProxyHttpRequestHandler.copyHeader(p_response, response, "Content-Length");
+      ProxyHttpRequestHandler.copyHeader(p_response, response, "Content-Type");
 
-      int status = p_response.getStatusLine().getStatusCode();
-      switch (status)
+      switch (code)
       {
         case HttpServletResponse.SC_FOUND:
         case HttpServletResponse.SC_OK:
           /** OK. Continue as normal... */
-          response.setStatus(status);
+          response.setStatus(code);
 
           HttpEntity entity = p_response.getEntity();
 
@@ -128,12 +140,12 @@ public class ProxyHttpRequestHandler
           EntityUtils.consume(entity);
           p_response.close();
 
-          break;
+          return;
 
         case HttpServletResponse.SC_NOT_FOUND:
         case HttpServletResponse.SC_GONE:
           /** The resource can not be resolved through this origin */
-          response.sendError(status, p_response.getStatusLine().getReasonPhrase());
+          response.sendError(code, status.getReasonPhrase());
           return;
 
         case HttpServletResponse.SC_MOVED_PERMANENTLY:
@@ -157,6 +169,28 @@ public class ProxyHttpRequestHandler
       // TODO: throw sensible exceptions, to communicate resolving-errors
       throw new RuntimeException(e);
     }
+    finally
+    {
+      if (p_response != null)
+      {
+        EntityUtils.consumeQuietly(p_response.getEntity());
+        p_response.close();
+      }
+    }
+  }
+
+  public static void copyHeader(
+      HttpResponse source,
+      HttpServletResponse target,
+      String name
+      )
+  {
+    Header header = source.getLastHeader(name);
+    if (header != null)
+    {
+      LOG.trace("copy header {}: {}", header.getName(), header.getValue());
+      target.addHeader(header.getName(), header.getValue());
+    }
   }
 
   public CacheControl computeCacheControl(HttpResponse response)
@@ -308,7 +342,10 @@ public class ProxyHttpRequestHandler
 
   public ProxyHttpRequestHandler setOrigin(String origin)
   {
-    this.origin = origin;
+    if (origin.endsWith("/"))
+      this.origin = origin;
+    else
+      this.origin = origin + "/";
     return this;
   }
 
@@ -326,9 +363,10 @@ public class ProxyHttpRequestHandler
    *
    * @see org.springframework.web.util.UrlPathHelper#setAlwaysUseFullPath
    */
-  public void setAlwaysUseFullPath(boolean alwaysUseFullPath)
+  public ProxyHttpRequestHandler setAlwaysUseFullPath(boolean alwaysUseFullPath)
   {
     this.urlPathHelper.setAlwaysUseFullPath(alwaysUseFullPath);
+    return this;
   }
 
   /**
@@ -341,9 +379,10 @@ public class ProxyHttpRequestHandler
    *
    * @see org.springframework.web.util.UrlPathHelper#setUrlDecode
    */
-  public void setUrlDecode(boolean urlDecode)
+  public ProxyHttpRequestHandler setUrlDecode(boolean urlDecode)
   {
     this.urlPathHelper.setUrlDecode(urlDecode);
+    return this;
   }
 
   /**
@@ -352,9 +391,10 @@ public class ProxyHttpRequestHandler
    * @see
    * org.springframework.web.util.UrlPathHelper#setRemoveSemicolonContent(boolean)
    */
-  public void setRemoveSemicolonContent(boolean removeSemicolonContent)
+  public ProxyHttpRequestHandler setRemoveSemicolonContent(boolean removeSemicolonContent)
   {
     this.urlPathHelper.setRemoveSemicolonContent(removeSemicolonContent);
+    return this;
   }
 
   /**
@@ -368,17 +408,10 @@ public class ProxyHttpRequestHandler
    * @see
    * org.springframework.web.servlet.handler.AbstractUrlHandlerMapping#setUrlPathHelper
    */
-  public void setUrlPathHelper(UrlPathHelper urlPathHelper)
+  public ProxyHttpRequestHandler setUrlPathHelper(UrlPathHelper urlPathHelper)
   {
     Assert.notNull(urlPathHelper, "UrlPathHelper must not be null");
     this.urlPathHelper = urlPathHelper;
-  }
-
-  /**
-   * Return the UrlPathHelper to use for the resolution of lookup paths.
-   */
-  protected UrlPathHelper getUrlPathHelper()
-  {
-    return this.urlPathHelper;
+    return this;
   }
 }
index 1ada05c..496184b 100644 (file)
@@ -3,3 +3,7 @@ thymeproxy.origin=@thymeproxy.origin@
 server.port=@thymeproxy.port@
 thymeproxy.ttl=@thymeproxy.ttl@
 thymeproxy.origins[0].uri=http://localhost:8080/thymeleaf/
+
+logging.level.de.juplo=trace
+logging.level.org.apache.http=@httpclient.logging.level@
+logging.level.org.apache.http.wire=ERROR
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
deleted file mode 100644 (file)
index 793eaa1..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<configuration>
-
-  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
-    <encoder>
-      <pattern>%p - %c{0}.%M\(%L\) | %m%n</pattern>
-    </encoder>
-  </appender>
-
-  <logger name="de.juplo">
-    <level value="trace"/>
-  </logger>
-
-  <root>
-    <level value="info"/>
-    <appender-ref ref="CONSOLE"/>
-  </root>
-
-</configuration>