Author: lindner
Date: Sat Jan 30 02:30:48 2010
New Revision: 904715

URL: http://svn.apache.org/viewvc?rev=904715&view=rev
Log:
missing files from new gadget rewriter checkin - changeset 904642

Added:
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/GadgetRewritersProvider.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/HtmlAccelServlet.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HtmlAccelServletTest.java

Added: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/GadgetRewritersProvider.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/GadgetRewritersProvider.java?rev=904715&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/GadgetRewritersProvider.java
 (added)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/GadgetRewritersProvider.java
 Sat Jan 30 02:30:48 2010
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.shindig.gadgets.render;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.rewrite.GadgetRewriter;
+import org.apache.shindig.gadgets.servlet.HtmlAccelServlet;
+
+import java.util.List;
+
+/**
+ * Class to provide list of rewriters according to gadget request.
+ * Provide different list of rewriters fro html accelerate request
+ *
+ */
+public class GadgetRewritersProvider {
+
+  private final List<GadgetRewriter> renderRewriters;
+  private final List<GadgetRewriter> accelRewriters;
+  
+  @Inject
+  public GadgetRewritersProvider(
+      @Named("shindig.rewriters.gadget") List<GadgetRewriter> renderRewriters,
+      @Named("shindig.rewriters.accelerate") List<GadgetRewriter> 
accelRewriters) {
+    this.renderRewriters = renderRewriters;
+    this.accelRewriters = accelRewriters;
+  }
+
+  public List<GadgetRewriter> getRewriters(GadgetContext context) {
+    if (context.getParameter(HtmlAccelServlet.ACCEL_GADGET_PARAM_NAME) == 
+      HtmlAccelServlet.ACCEL_GADGET_PARAM_VALUE) {
+      return accelRewriters;
+    }
+    return renderRewriters;
+  }
+  
+}

Added: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/HtmlAccelServlet.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/HtmlAccelServlet.java?rev=904715&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/HtmlAccelServlet.java
 (added)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/HtmlAccelServlet.java
 Sat Jan 30 02:30:48 2010
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.shindig.gadgets.servlet;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.shindig.gadgets.DefaultGadgetSpecFactory;
+import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.GadgetException.Code;
+import org.apache.shindig.gadgets.http.HttpRequest;
+import org.apache.shindig.gadgets.http.HttpResponse;
+import org.apache.shindig.gadgets.http.RequestPipeline;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Html pages acceleration servlet.
+ * It uses the rewriter pipeline to improve speed of loading html.
+ * Internally it create a fake gadget spec and uses the Gadget rendering 
servlet.
+ * Only html content is being rewritten, other content is passed as is.
+ * (It uses the rawxml tag to pass spec, so require DefaultGadgetSpecFactory)
+ */
+public class HtmlAccelServlet extends GadgetRenderingServlet {
+
+  public static final String URL_PARAM_NAME = "url";
+  /**
+   * Use ACCEL_GADGET parameter to check for AccelServlet during rendering.
+   */
+  public static final String ACCEL_GADGET_PARAM_NAME = "accelGadget";
+  /** 
+   * Use the next value with '==' operation when checking for ACCEL_GADGET,
+   * That will prevent spoofing it using url params.
+   */
+  public static final String ACCEL_GADGET_PARAM_VALUE = "true";
+  public static final String CONTENT_TYPE = "Content-Type";
+  public static final String HTML_CONTENT = "text/html";
+  public static final String CONTENT_ENCODING = "Content-Encoding";
+  public static final String CONTENT_LENGTH = "Content-Length";
+
+  /** Fake spec to wrap the html data */
+  private static final String FAKE_SPEC_TPL_PREFIX = 
+      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+      + "<Module>\n"
+      + "  <ModulePrefs title=\"Apache Shindig Accelerator\"\n"
+      + "               author=\"Apache Shindig\"\n"
+      + "               author_email=\"[email protected]\">\n"
+      + "    <Require feature=\"core.none\"/>\n"
+      + "    <Optional feature=\"content-rewrite\">\n"
+      + "      <Param name=\"include-urls\">.*</Param>\n"
+      + "    </Optional>\n"
+      + "  </ModulePrefs>\n"
+      + "  <Content type=\"html\">\n"
+      + "    <![CDATA[";
+  private static final String FAKE_SPEC_TPL_SUFFIX = 
+      "]]>\n" 
+      + "  </Content>\n"
+      + "</Module>\n";
+
+  private RequestPipeline requestPipeline;
+  private Map<String, String> addedServletParams = null;
+  
+  @Inject
+  public void setRequestPipeLine(RequestPipeline pipeline) {
+    this.requestPipeline = pipeline;
+  }
+  
+  @Inject(optional = true)
+  public void setAddedServletParams(
+      @Named("shindig.accelerate.added-params") Map<String, String> params) {
+    this.addedServletParams = params;
+  }
+
+  @Override
+  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+      throws IOException {
+
+    // Get data to accelerate:
+    HttpResponse data;
+    HttpGadgetContext context = new HttpGadgetContext(req);
+    try {
+      data = fetch(context);
+    } catch (GadgetException e) {
+      resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+      return;
+    }
+    
+    // No such page:
+    if (data == null) {
+      resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Error fetching 
data");
+      return;
+    }
+    
+    // If not html, just return data
+    if (data.getHeader(CONTENT_TYPE) == null ||
+        !data.getHeader(CONTENT_TYPE).contains(HTML_CONTENT)) {
+      respondVerbatim(data,resp);
+      return;
+    }
+    
+    // For html, use the gadgetServlet for rewrite
+    String content = data.getResponseAsString();
+
+    // Create fake spec wrapper for the html:
+    // (Note that the content can be big so don't use the limited 
String.Format)
+    final String spec = createFakeSpec(content);
+    
+    // wrap the request with the added params
+    HttpServletRequestWrapper reqWrapper = new HttpServletRequestWrapper(req) {
+      @Override
+      public String getParameter(String name) {
+        // Mark this as an accelerate page spec
+        // (The code that check for that field have to use the defined 
constant,
+        //  hence the use of == )
+        if (name == ACCEL_GADGET_PARAM_NAME) {
+          return ACCEL_GADGET_PARAM_VALUE;
+        }
+        // Pass the spec using rawxml (require DefaultGadgetSpecFactory):
+        if (name == DefaultGadgetSpecFactory.RAW_GADGETSPEC_XML_PARAM_NAME) {
+          return spec;
+        }
+        // Allow overriding extra params (i.e. container)
+        if (addedServletParams != null && 
addedServletParams.containsKey(name)) {
+          return addedServletParams.get(name);
+        }
+        return super.getParameter(name);
+      }
+    };
+    
+    // Call the gadget renderer to rewrite content:
+    super.doGet(reqWrapper,resp);
+  }
+
+  @Override
+  protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
throws IOException {
+    doGet(req,resp);
+  }
+
+  private HttpResponse fetch(HttpGadgetContext context) throws GadgetException 
{
+
+    if (context.getUrl() == null) {
+      throw new GadgetException(Code.INVALID_PARAMETER, "Missing url 
paramater");
+    }
+
+    HttpRequest request = new HttpRequest(context.getUrl())
+        .setIgnoreCache(context.getIgnoreCache())
+        .setContainer(context.getContainer());
+
+    HttpResponse results = requestPipeline.execute(request);
+    return results;
+  }
+  
+  private void respondVerbatim(HttpResponse results, HttpServletResponse 
response) 
+      throws IOException {
+    
+    for (Map.Entry<String, String> entry : results.getHeaders().entries()) {
+      // Encoding such as gzip was already stripped from data
+      if (!CONTENT_ENCODING.equals(entry.getKey()) &&
+          !CONTENT_LENGTH.equals(entry.getKey())) {
+        response.setHeader(entry.getKey(), entry.getValue());
+      }
+    }
+    response.setStatus(results.getHttpStatusCode());
+    IOUtils.copy(results.getResponse(), response.getOutputStream());
+  }
+
+  private String createFakeSpec(String content) {
+    // need to rescape CDATA: ( each "]]>" and "<![CDATA[" should be 
"]]><![CDATA[") 
+    String data = content.replace("]]>", "<![CDATA[")
+      .replace("<![CDATA[", "]]><![CDATA[");
+    
+    return FAKE_SPEC_TPL_PREFIX + data + FAKE_SPEC_TPL_SUFFIX;   
+  }
+}

Added: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HtmlAccelServletTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HtmlAccelServletTest.java?rev=904715&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HtmlAccelServletTest.java
 (added)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HtmlAccelServletTest.java
 Sat Jan 30 02:30:48 2010
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.shindig.gadgets.servlet;
+
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+
+import com.google.caja.util.Maps;
+
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.UrlGenerator;
+import org.apache.shindig.gadgets.UrlValidationStatus;
+import org.apache.shindig.gadgets.http.HttpRequest;
+import org.apache.shindig.gadgets.http.HttpResponse;
+import org.apache.shindig.gadgets.http.HttpResponseBuilder;
+import org.apache.shindig.gadgets.render.Renderer;
+import org.apache.shindig.gadgets.render.RenderingResults;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collection;
+import java.util.Map;
+
+public class HtmlAccelServletTest extends ServletTestFixture {
+
+  private static final String REWRITE_CONTENT = "working rewrite";
+  
+  private HtmlAccelServlet servlet;
+  private Renderer renderer;
+
+  @Before
+  public void setUp() throws Exception {
+    servlet = new HtmlAccelServlet();
+    servlet.setRequestPipeLine(pipeline);
+    servlet.setUrlGenerator(new FakeUrlGenerator());
+    renderer = mock(Renderer.class);
+    servlet.setRenderer(renderer);
+  }
+
+  @Test
+  public void testHtmlAccelNoData() throws Exception {
+    String url = "http://example.org/data.html";;
+    
+    HttpRequest req = new HttpRequest(Uri.parse(url));
+    expect(pipeline.execute(req)).andReturn(null).once();
+    expect(request.getParameter("url")).andReturn(url).once();
+    replay();
+    
+    servlet.doGet(request, recorder);
+    verify();
+    assertEquals("Error fetching data", recorder.getResponseAsString());
+    assertEquals(400, recorder.getHttpStatusCode());
+  }
+
+  @Test
+  public void testHtmlAccelNoHtml() throws Exception {
+    String url = "http://example.org/data.xml";;
+    String data = "<html><body>Hello World</body></html>";
+    
+    HttpRequest req = new HttpRequest(Uri.parse(url));
+    HttpResponse resp = new HttpResponseBuilder()
+        .setResponse(data.getBytes())
+        .setHeader("Content-Type", "text/xml")
+        .setHttpStatusCode(200)
+        .create();
+    expect(pipeline.execute(req)).andReturn(resp).once();
+    expect(request.getParameter("url")).andReturn(url).once();
+    replay();
+    
+    servlet.doGet(request, recorder);
+    verify();
+    assertEquals(data, recorder.getResponseAsString());
+  }
+
+  @Test
+  public void testHtmlAccelRewriteSimple() throws Exception {
+    String url = "http://example.org/data.html";;
+    String data = "<html><body>Hello World</body></html>";
+    
+    HttpRequest req = new HttpRequest(Uri.parse(url));
+    HttpResponse resp = new HttpResponseBuilder()
+        .setResponse(data.getBytes())
+        .setHeader("Content-Type", "text/html")
+        .setHttpStatusCode(200)
+        .create();
+    expect(pipeline.execute(req)).andReturn(resp).once();
+    expect(request.getParameter("url")).andReturn(url).once();
+    expect(request.getRequestURL()).andReturn(new 
StringBuffer("gmodules.com/gadgets/accel")).once();
+    expect(request.getQueryString()).andReturn("url=" + url).once();
+    expect(renderer.render(isA(GadgetContext.class)))
+        .andReturn(RenderingResults.ok(REWRITE_CONTENT));
+    replay();
+    
+    servlet.doGet(request, recorder);
+    verify();
+    assertEquals(REWRITE_CONTENT, recorder.getResponseAsString());
+    assertEquals(200, recorder.getHttpStatusCode());
+  }
+
+  @Test
+  public void testHtmlAccelParams() throws Exception {
+
+    Renderer newRenderer = new Renderer(null, null, null, lockedDomainService) 
{
+      @Override
+      public RenderingResults render(GadgetContext context) {
+        assertTrue(HtmlAccelServlet.ACCEL_GADGET_PARAM_VALUE == 
+          context.getParameter(HtmlAccelServlet.ACCEL_GADGET_PARAM_NAME));
+        assertEquals("accel", context.getParameter("container"));
+        return RenderingResults.ok(REWRITE_CONTENT);
+      }
+    };
+    servlet.setRenderer(newRenderer);
+    Map<String,String> paramMap = Maps.newHashMap();
+    paramMap.put("container","accel");
+    servlet.setAddedServletParams(paramMap);
+    
+    String url = "http://example.org/data.html";;
+    
+    HttpRequest req = new HttpRequest(Uri.parse(url));
+    HttpResponse resp = new HttpResponseBuilder()
+        .setHeader("Content-Type", "text/html")
+        .setHttpStatusCode(200)
+        .create();
+    expect(pipeline.execute(req)).andReturn(resp).once();
+    expect(request.getParameter("url")).andReturn(url).once();
+    expect(request.getRequestURL()).andReturn(new 
StringBuffer("gmodules.com/gadgets/accel")).once();
+    expect(request.getQueryString()).andReturn("url=" + url).once();
+    replay();
+   
+    servlet.doGet(request, recorder);
+    verify();
+  }
+  
+  private static class FakeUrlGenerator implements UrlGenerator {
+
+    public UrlValidationStatus validateJsUrl(String url) {
+      throw new UnsupportedOperationException();
+    }
+
+    public String getIframeUrl(Gadget gadget) {
+      throw new UnsupportedOperationException();
+    }
+
+    public UrlValidationStatus validateIframeUrl(String url) {
+      return UrlValidationStatus.VALID_UNVERSIONED;
+    }
+
+    public String getBundledJsUrl(Collection<String> features, GadgetContext 
context) {
+      throw new UnsupportedOperationException();
+    }
+
+    public String getGadgetDomainOAuthCallback(String container, String 
gadgetHost) {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+
+}


Reply via email to