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();
+ }
+ }
+
+
+}