Add request attribute indicating a response is streaming

Servlet containers may need to give streaming responses special
treatment, e.g. to avoid aggressively buffering even in the presence
of flush(). Expose in a request attribute whether the request requires
a streaming response, so this can be introspected by filters.

Change-Id: If9cb6633fcbcfc5b851f097e633d3705321f007d
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/BaseServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/BaseServlet.java
index 80af135..08920a2 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/BaseServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/BaseServlet.java
@@ -23,6 +23,7 @@
 import static javax.servlet.http.HttpServletResponse.SC_OK;
 
 import com.google.common.base.Charsets;
+import com.google.common.base.Objects;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
@@ -47,8 +48,9 @@
 /** Base servlet class for Gitiles servlets that serve Soy templates. */
 public abstract class BaseServlet extends HttpServlet {
   private static final long serialVersionUID = 1L;
-  private static final String DATA_ATTRIBUTE = BaseServlet.class.getName() + "/Data";
   private static final String ACCESS_ATTRIBUTE = BaseServlet.class.getName() + "/GitilesAccess";
+  private static final String DATA_ATTRIBUTE = BaseServlet.class.getName() + "/Data";
+  private static final String STREAMING_ATTRIBUTE = BaseServlet.class.getName() + "/Streaming";
 
   static void setNotCacheable(HttpServletResponse res) {
     res.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0, must-revalidate");
@@ -75,6 +77,10 @@
     }
   }
 
+  public static boolean isStreamingResponse(HttpServletRequest req) {
+    return Objects.firstNonNull((Boolean) req.getAttribute(STREAMING_ATTRIBUTE), false);
+  }
+
   protected static ArchiveFormat getArchiveFormat(GitilesAccess access) throws IOException {
     return ArchiveFormat.getDefault(access.getConfig());
   }
@@ -214,6 +220,7 @@
    */
   protected OutputStream startRenderStreamingHtml(HttpServletRequest req,
       HttpServletResponse res, String templateName, Map<String, ?> soyData) throws IOException {
+    req.setAttribute(STREAMING_ATTRIBUTE, true);
     return renderer.renderStreaming(res, templateName, startHtmlResponse(req, res, soyData));
   }