You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by jo...@apache.org on 2010/03/30 22:10:06 UTC

svn commit: r929245 - in /shindig/trunk/java/gadgets/src: main/java/org/apache/shindig/gadgets/rewrite/ main/java/org/apache/shindig/gadgets/rewrite/image/ main/java/org/apache/shindig/gadgets/servlet/ main/java/org/apache/shindig/gadgets/uri/ test/jav...

Author: johnh
Date: Tue Mar 30 20:10:06 2010
New Revision: 929245

URL: http://svn.apache.org/viewvc?rev=929245&view=rev
Log:
Adds support for extended (image rewrite/resizing, mime type, and fallback url) parameters to ProxyUris.

Patch provided by Ziv Horesh.


Modified:
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitor.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BasicImageRewriter.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyBase.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultConcatUriManager.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultProxyUriManager.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriBase.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriManager.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriCommon.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/ProxyHandlerTest.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultProxyUriManagerTest.java

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitor.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitor.java?rev=929245&r1=929244&r2=929245&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitor.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitor.java Tue Mar 30 20:10:06 2010
@@ -18,17 +18,18 @@
  */
 package org.apache.shindig.gadgets.rewrite;
 
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
 import org.apache.shindig.common.Pair;
 import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.common.uri.Uri.UriException;
 import org.apache.shindig.gadgets.Gadget;
 import org.apache.shindig.gadgets.uri.ProxyUriManager;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -97,7 +98,7 @@ public class ProxyingVisitor implements 
       String uriStr = element.getAttribute(RESOURCE_TAGS.get(element.getNodeName()));
       try {
         reservedUris.add(new ProxyUriManager.ProxyUri(gadget, Uri.parse(uriStr)));
-      } catch (Exception e) {
+      } catch (UriException e) {
         // Uri parse exception, add null.
         reservedUris.add(null);
       }

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BasicImageRewriter.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BasicImageRewriter.java?rev=929245&r1=929244&r2=929245&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BasicImageRewriter.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BasicImageRewriter.java Tue Mar 30 20:10:06 2010
@@ -37,6 +37,7 @@ import org.apache.shindig.gadgets.http.H
 import org.apache.shindig.gadgets.http.HttpResponseBuilder;
 import org.apache.shindig.gadgets.rewrite.image.BaseOptimizer.ImageIOOutputter;
 import org.apache.shindig.gadgets.rewrite.image.BaseOptimizer.ImageOutputter;
+import org.apache.shindig.gadgets.uri.UriCommon.Param;
 
 import java.awt.AlphaComposite;
 import java.awt.Color;
@@ -68,13 +69,13 @@ public class BasicImageRewriter implemen
 
   private static final String CONTENT_LENGTH = "Content-Length";
   /** Parameter used to request image rendering quality */
-  public static final String PARAM_RESIZE_QUALITY = "resize_q";
+  public static final String PARAM_RESIZE_QUALITY = Param.RESIZE_QUALITY.getKey();
   /** Parameter used to request image width change */
-  public static final String PARAM_RESIZE_WIDTH = "resize_w";
+  public static final String PARAM_RESIZE_WIDTH = Param.RESIZE_WIDTH.getKey();
   /** Parameter used to request image height change */
-  public static final String PARAM_RESIZE_HEIGHT = "resize_h";
+  public static final String PARAM_RESIZE_HEIGHT = Param.RESIZE_HEIGHT.getKey();
   /** Parameter used to request resizing will not expand image */
-  public static final String PARAM_NO_EXPAND = "no_expand";
+  public static final String PARAM_NO_EXPAND = Param.NO_EXPAND.getKey();
 
   public static final String
       CONTENT_TYPE_AND_EXTENSION_MISMATCH =

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyBase.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyBase.java?rev=929245&r1=929244&r2=929245&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyBase.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyBase.java Tue Mar 30 20:10:06 2010
@@ -29,6 +29,7 @@ import org.apache.shindig.config.Contain
 import org.apache.shindig.gadgets.GadgetException;
 import org.apache.shindig.gadgets.http.HttpRequest;
 import org.apache.shindig.gadgets.http.HttpResponse;
+import org.apache.shindig.gadgets.uri.UriCommon.Param;
 
 import java.io.IOException;
 import java.util.Set;
@@ -51,8 +52,8 @@ public abstract class ProxyBase {
   public static final String SYND_PARAM = "synd";
 
   // Public because of rewriter. Rewriter should be cleaned up.
-  public static final String REWRITE_MIME_TYPE_PARAM = "rewriteMime";
-  public static final String SANITIZE_CONTENT_PARAM = "sanitize";
+  public static final String REWRITE_MIME_TYPE_PARAM = Param.REWRITE_MIME_TYPE.getKey();
+  public static final String SANITIZE_CONTENT_PARAM = Param.SANITIZE.getKey();
 
   protected static final Set<String> DISALLOWED_RESPONSE_HEADERS = ImmutableSet.of(
       "set-cookie", "content-length", "content-encoding", "etag", "last-modified" ,"accept-ranges",

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java?rev=929245&r1=929244&r2=929245&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java Tue Mar 30 20:10:06 2010
@@ -18,16 +18,10 @@
  */
 package org.apache.shindig.gadgets.servlet;
 
-import static org.apache.shindig.gadgets.rewrite.image.BasicImageRewriter.PARAM_NO_EXPAND;
-import static org.apache.shindig.gadgets.rewrite.image.BasicImageRewriter.PARAM_RESIZE_HEIGHT;
-import static org.apache.shindig.gadgets.rewrite.image.BasicImageRewriter.PARAM_RESIZE_QUALITY;
-import static org.apache.shindig.gadgets.rewrite.image.BasicImageRewriter.PARAM_RESIZE_WIDTH;
-
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.math.NumberUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.shindig.common.servlet.HttpUtil;
 import org.apache.shindig.common.uri.Uri;
@@ -55,16 +49,10 @@ import javax.servlet.http.HttpServletRes
 public class ProxyHandler extends ProxyBase {
   private static final Logger logger = Logger.getLogger(ProxyHandler.class.getName());
 
-  private static final String[] INTEGER_RESIZE_PARAMS = new String[] {
-    PARAM_RESIZE_HEIGHT, PARAM_RESIZE_WIDTH, PARAM_RESIZE_QUALITY, PARAM_NO_EXPAND
-  };
-
   // TODO: parameterize these.
   static final Integer LONG_LIVED_REFRESH = (365 * 24 * 60 * 60);  // 1 year
   static final Integer DEFAULT_REFRESH = (60 * 60);                // 1 hour
   
-  static final String FALLBACK_URL_PARAM = "fallback_url";
-
   private final RequestPipeline requestPipeline;
   private final LockedDomainService lockedDomainService;
   private final RequestRewriterRegistry contentRewriterRegistry;
@@ -84,33 +72,14 @@ public class ProxyHandler extends ProxyB
   /**
    * Generate a remote content request based on the parameters sent from the client.
    */
-  private HttpRequest buildHttpRequest(HttpServletRequest request, Uri uri,
+  private HttpRequest buildHttpRequest(HttpServletRequest request,
       ProxyUriManager.ProxyUri uriCtx, Uri tgt) throws GadgetException {
     validateUrl(tgt);
-
-    HttpRequest req = uriCtx.makeHttpRequest(uriCtx.getResource());
-    copySanitizedIntegerParams(uri, req);
-
-    // Allow the rewriter to use an externally forced MIME type. This is needed
-    // allows proper rewriting of <script src="x"/> where x is returned with
-    // a content type like text/html which unfortunately happens all too often
-    req.setRewriteMimeType(uri.getQueryParameter(REWRITE_MIME_TYPE_PARAM));
-    req.setSanitizationRequested("1".equals(uri.getQueryParameter(SANITIZE_CONTENT_PARAM)));
-
+    HttpRequest req = uriCtx.makeHttpRequest(tgt);
     this.setRequestHeaders(request, req);
-    
     return req;
   }
 
-  private void copySanitizedIntegerParams(Uri uri, HttpRequest req) {
-    for (String resizeParamName : INTEGER_RESIZE_PARAMS) {
-      if (uri.getQueryParameter(resizeParamName) != null) {
-        req.setParam(resizeParamName,
-            NumberUtils.createInteger(uri.getQueryParameter(resizeParamName)));
-      }
-    }
-  }
-
   @Override
   protected void doFetch(HttpServletRequest request, HttpServletResponse response)
       throws IOException, GadgetException {
@@ -131,8 +100,9 @@ public class ProxyHandler extends ProxyB
           HttpResponse.SC_BAD_REQUEST);
     }
     
-    Uri requestUri = new UriBuilder(request).toUri();
-    ProxyUriManager.ProxyUri proxyUri = proxyUriManager.process(requestUri);
+    // Parse request uri:
+    ProxyUriManager.ProxyUri proxyUri = proxyUriManager.process(
+        new UriBuilder(request).toUri());
     
     try {
       HttpUtil.setCachingHeaders(response,
@@ -142,7 +112,7 @@ public class ProxyHandler extends ProxyB
       return;
     }
 
-    HttpRequest rcr = buildHttpRequest(request, requestUri, proxyUri, proxyUri.getResource());
+    HttpRequest rcr = buildHttpRequest(request, proxyUri, proxyUri.getResource());
     if (rcr == null) {
       throw new GadgetException(GadgetException.Code.INVALID_PARAMETER,
           "No url paramater in request", HttpResponse.SC_BAD_REQUEST);      
@@ -151,16 +121,10 @@ public class ProxyHandler extends ProxyB
     
     if (results.isError()) {
       // Error: try the fallback. Particularly useful for proxied images.
-      String fallbackStr = requestUri.getQueryParameter(FALLBACK_URL_PARAM);
-      if (fallbackStr != null) {
-        try {
-          HttpRequest fallbackRcr =
-              buildHttpRequest(request, requestUri, proxyUri, Uri.parse(fallbackStr));
-          results = requestPipeline.execute(fallbackRcr);
-        } catch (IllegalArgumentException e) {
-          throw new GadgetException(GadgetException.Code.INVALID_PARAMETER,
-              FALLBACK_URL_PARAM + " param is invalid: " + e, HttpResponse.SC_BAD_REQUEST);
-        }
+      Uri fallbackUri = proxyUri.getFallbackUri();
+      if (fallbackUri != null) {
+        HttpRequest fallbackRcr = buildHttpRequest(request, proxyUri, fallbackUri);
+        results = requestPipeline.execute(fallbackRcr);
       }
     }
     

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultConcatUriManager.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultConcatUriManager.java?rev=929245&r1=929244&r2=929245&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultConcatUriManager.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultConcatUriManager.java Tue Mar 30 20:10:06 2010
@@ -70,21 +70,6 @@ public class DefaultConcatUriManager imp
 
     ConcatUri exemplar = resourceUris.get(0);
     String container = exemplar.getContainer();
-    String concatHost = getReqVal(container, CONCAT_HOST_PARAM);
-    String concatPath = getReqVal(container, CONCAT_PATH_PARAM);
-    
-    UriBuilder uriBuilder = new UriBuilder();
-    uriBuilder.setAuthority(concatHost);
-    uriBuilder.setPath(concatPath);
-    
-    uriBuilder.addQueryParameter(Param.CONTAINER.getKey(), container);
-    uriBuilder.addQueryParameter(Param.GADGET.getKey(), exemplar.getGadget());
-    uriBuilder.addQueryParameter(Param.DEBUG.getKey(), exemplar.isDebug() ? "1" : "0");
-    uriBuilder.addQueryParameter(Param.NO_CACHE.getKey(), exemplar.isNoCache() ? "1" : "0");
-    
-    // Above params are common for all generated Uris.
-    // Use as a base for specific ConcatUri instances.
-    Uri uriBase = uriBuilder.toUri();
     
     List<String> versions = null;
     List<List<Uri>> batches = Lists.newArrayListWithCapacity(resourceUris.size());
@@ -100,31 +85,33 @@ public class DefaultConcatUriManager imp
     for (ConcatUri ctx : resourceUris) {
       String version = versionIt != null ? versionIt.next() : null;
       concatUris.add(
-          makeConcatUri(uriBase, ctx.getBatch(), ctx.getType(), container, isAdjacent, version));
+          makeConcatUri(ctx, isAdjacent, version));
     }
     
     return concatUris;
   }
   
-  private ConcatData makeConcatUri(Uri uriBase, List<Uri> resourceUris, Type contentType,
-      String container, boolean isAdjacent, String version) {
+  private ConcatData makeConcatUri(ConcatUri ctx, boolean isAdjacent, String version) {
     // TODO: Consider per-bundle isAdjacent plus first-bundle direct evaluation
     
-    if (!isAdjacent && contentType != Type.JS) {
+    if (!isAdjacent && ctx.getType() != Type.JS) {
       // Split-concat is only supported for JS at the moment.
       // This situation should never occur due to ConcatLinkRewriter's implementation.
       throw new UnsupportedOperationException("Split concatenation only supported for JS");
     }
     
-    UriBuilder uriBuilder = new UriBuilder(uriBase);
-    uriBuilder.addQueryParameter(Param.TYPE.getKey(), contentType.getType());
-    Map<Uri, String> snippets = Maps.newHashMapWithExpectedSize(resourceUris.size());
+    UriBuilder uriBuilder = ctx.makeQueryParams(null, version);
     
-    if (version != null) {
-      uriBuilder.addQueryParameter(Param.VERSION.getKey(), version);
-    }
+    String concatHost = getReqVal(ctx.getContainer(), CONCAT_HOST_PARAM);
+    String concatPath = getReqVal(ctx.getContainer(), CONCAT_PATH_PARAM);
+    uriBuilder.setAuthority(concatHost);
+    uriBuilder.setPath(concatPath);
+
+    uriBuilder.addQueryParameter(Param.TYPE.getKey(), ctx.getType().getType());
+    List<Uri> resourceUris = ctx.getBatch();
+    Map<Uri, String> snippets = Maps.newHashMapWithExpectedSize(resourceUris.size());
     
-    String splitParam = getReqVal(container, CONCAT_JS_SPLIT_PARAM);
+    String splitParam = getReqVal(ctx.getContainer(), CONCAT_JS_SPLIT_PARAM);
     if (!isAdjacent) {
       uriBuilder.addQueryParameter(Param.JSON.getKey(), splitParam);
     }

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultProxyUriManager.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultProxyUriManager.java?rev=929245&r1=929244&r2=929245&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultProxyUriManager.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultProxyUriManager.java Tue Mar 30 20:10:06 2010
@@ -113,21 +113,9 @@ public class DefaultProxyUriManager impl
   }
 
   private Uri makeProxiedUri(ProxyUri puc, Integer forcedRefresh, String version) {
-    UriBuilder queryBuilder = new UriBuilder();
-    
-    // Add all params common to both chained and query syntax.
+    UriBuilder queryBuilder = puc.makeQueryParams(forcedRefresh, version);
+
     String container = puc.getContainer();
-    queryBuilder.addQueryParameter(Param.CONTAINER.getKey(), container);
-    queryBuilder.addQueryParameter(Param.GADGET.getKey(), puc.getGadget());
-    queryBuilder.addQueryParameter(Param.DEBUG.getKey(), puc.isDebug() ? "1" : "0");
-    queryBuilder.addQueryParameter(Param.NO_CACHE.getKey(), puc.isNoCache() ? "1" : "0");
-    if (forcedRefresh != null) {
-      queryBuilder.addQueryParameter(Param.REFRESH.getKey(), forcedRefresh.toString());
-    }
-    if (version != null) {
-      queryBuilder.addQueryParameter(Param.VERSION.getKey(), version);
-    }
-    
     UriBuilder uri = new UriBuilder();
     uri.setAuthority(getReqConfig(container, PROXY_HOST_PARAM));
     

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriBase.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriBase.java?rev=929245&r1=929244&r2=929245&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriBase.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriBase.java Tue Mar 30 20:10:06 2010
@@ -19,7 +19,9 @@
 package org.apache.shindig.gadgets.uri;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.math.NumberUtils;
 import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.common.uri.UriBuilder;
 import org.apache.shindig.gadgets.Gadget;
 import org.apache.shindig.gadgets.GadgetException;
 import org.apache.shindig.gadgets.http.HttpRequest;
@@ -27,16 +29,18 @@ import org.apache.shindig.gadgets.http.H
 import org.apache.shindig.gadgets.uri.UriCommon.Param;
 
 public class ProxyUriBase {
-  private final UriStatus status;
-  private final Integer refresh;
-  private final boolean debug;
-  private final boolean noCache;
-  private final String container;
-  private final String gadget;
-
+  private UriStatus status = null;
+  private Integer refresh = null;
+  private boolean debug = false;
+  private boolean noCache = false;
+  private String container = null;
+  private String gadget = null;
+  private String rewriteMimeType = null;
+  private boolean sanitizeContent = false;
+  
   protected ProxyUriBase(Gadget gadget) {
     this(null,  // Meaningless in "context" mode. translateStatusRefresh invalid here.
-         parseRefresh(gadget.getContext().getParameter(Param.REFRESH.getKey())),
+         getIntegerValue(gadget.getContext().getParameter(Param.REFRESH.getKey())),
          gadget.getContext().getDebug(),
          gadget.getContext().getIgnoreCache(),
          gadget.getContext().getContainer(),
@@ -44,15 +48,11 @@ public class ProxyUriBase {
   }
   
   protected ProxyUriBase(UriStatus status, Uri origUri) {
-    this(status,
-         origUri != null ? parseRefresh(origUri.getQueryParameter(Param.REFRESH.getKey())) : null,
-         origUri != null ? getBooleanValue(origUri.getQueryParameter(Param.DEBUG.getKey())) : false,
-         origUri != null ? getBooleanValue(origUri.getQueryParameter(Param.NO_CACHE.getKey())) : false,
-         origUri != null ? origUri.getQueryParameter(Param.CONTAINER.getKey()) : null,
-         origUri != null ? origUri.getQueryParameter(Param.GADGET.getKey()) : null);
+    this.status = status;
+    setFromUri(origUri);
   }
-  
-  private ProxyUriBase(UriStatus status, Integer refresh, boolean debug, boolean noCache,
+
+  protected ProxyUriBase(UriStatus status, Integer refresh, boolean debug, boolean noCache,
       String container, String gadget) {
     this.status = status;
     this.refresh = refresh;
@@ -62,6 +62,33 @@ public class ProxyUriBase {
     this.gadget = gadget;
   }
 
+  /**
+   * Parse uri query paramaters.
+   * Note this function is called by a constructor,
+   * and can be override to handle derived class parsing
+   */
+  public void setFromUri(Uri uri) {
+    if (uri != null) {
+      refresh = getIntegerValue(uri.getQueryParameter(Param.REFRESH.getKey()));
+      debug = getBooleanValue(uri.getQueryParameter(Param.DEBUG.getKey()));
+      noCache = getBooleanValue(uri.getQueryParameter(Param.NO_CACHE.getKey()));
+      container = uri.getQueryParameter(Param.CONTAINER.getKey());
+      gadget = uri.getQueryParameter(Param.GADGET.getKey());
+      rewriteMimeType = uri.getQueryParameter(Param.REWRITE_MIME_TYPE.getKey());
+      sanitizeContent = getBooleanValue(uri.getQueryParameter(Param.SANITIZE.getKey()));
+    }  
+  }
+  
+  public ProxyUriBase setRewriteMimeType(String type) {
+    this.rewriteMimeType = type;
+    return this;
+  }
+  
+  public ProxyUriBase setSanitizeContent(boolean sanitize) {
+    this.sanitizeContent = sanitize;
+    return this;
+  }
+  
   public UriStatus getStatus() {
     return status;
   }
@@ -85,7 +112,15 @@ public class ProxyUriBase {
   public String getGadget() {
     return gadget;
   }
+
+  public String getRewriteMimeType() {
+    return rewriteMimeType;
+  }
   
+  public boolean sanitizeContent() {
+    return sanitizeContent;
+  }
+
   public HttpRequest makeHttpRequest(Uri targetUri) throws GadgetException {
     HttpRequest req = new HttpRequest(targetUri)
         .setIgnoreCache(isNoCache())
@@ -102,9 +137,53 @@ public class ProxyUriBase {
     if (getRefresh() != null && getRefresh() >= 0) {
       req.setCacheTtl(getRefresh());
     }
+
+    // Allow the rewriter to use an externally forced MIME type. This is needed
+    // allows proper rewriting of <script src="x"/> where x is returned with
+    // a content type like text/html which unfortunately happens all too often
+    if (rewriteMimeType != null) {
+      req.setRewriteMimeType(getRewriteMimeType());
+    }
+    req.setSanitizationRequested(sanitizeContent());
+
     return req;
   }
-  
+
+  /**
+   * Construct the query parameters for proxy url  
+   * @param forcedRefresh optional overwrite the refresh time 
+   * @param version optional version
+   * @return Url with only query parameters set
+   */
+  public UriBuilder makeQueryParams(Integer forcedRefresh, String version) {
+    UriBuilder queryBuilder = new UriBuilder();
+    
+    // Add all params common to both chained and query syntax.
+    String container = getContainer();
+    queryBuilder.addQueryParameter(Param.CONTAINER.getKey(), container);
+    queryBuilder.addQueryParameter(Param.GADGET.getKey(), getGadget());
+    queryBuilder.addQueryParameter(Param.DEBUG.getKey(), isDebug() ? "1" : "0");
+    queryBuilder.addQueryParameter(Param.NO_CACHE.getKey(), isNoCache() ? "1" : "0");
+    if (!isNoCache()) {
+      if (forcedRefresh != null) {
+        queryBuilder.addQueryParameter(Param.REFRESH.getKey(), forcedRefresh.toString());
+      } else if (getRefresh() != null) {
+        queryBuilder.addQueryParameter(Param.REFRESH.getKey(), getRefresh().toString());      
+      }
+    }
+
+    if (version != null) {
+      queryBuilder.addQueryParameter(Param.VERSION.getKey(), version);
+    }
+    if (rewriteMimeType != null) {
+      queryBuilder.addQueryParameter(Param.REWRITE_MIME_TYPE.getKey(), rewriteMimeType);
+    }
+    if (sanitizeContent) {
+      queryBuilder.addQueryParameter(Param.SANITIZE.getKey(), "1");
+    }
+    return queryBuilder;
+  }
+
   public Integer translateStatusRefresh(int longVal, int defaultVal)
       throws GadgetException {
     Integer retRefresh = 0;
@@ -139,23 +218,21 @@ public class ProxyUriBase {
     return retRefresh;
   }
 
-  private static boolean getBooleanValue(String str) {
+  protected static boolean getBooleanValue(String str) {
     if (str != null && "1".equals(str)) {
       return true;
     }
     return false;
   }
   
-  private static Integer parseRefresh(String refreshStr) {
-    Integer refreshVal = null;
-    if (refreshStr != null) {
-      try {
-        refreshVal = Integer.parseInt(refreshStr);
-      } catch (NumberFormatException e) {
-        // -1 is sentinel for invalid value.
-        refreshVal = -1;
-      }
+  protected static Integer getIntegerValue(String str) {
+    Integer val = null;
+    try {
+      val = NumberUtils.createInteger(str);
+    } catch (NumberFormatException e) {
+      // -1 is sentinel for invalid value.
+      val = -1;
     }
-    return refreshVal;
+    return val;
   }
 }

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriManager.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriManager.java?rev=929245&r1=929244&r2=929245&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriManager.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriManager.java Tue Mar 30 20:10:06 2010
@@ -18,11 +18,15 @@
  */
 package org.apache.shindig.gadgets.uri;
 
+import com.google.common.collect.Lists;
+
 import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.common.uri.UriBuilder;
 import org.apache.shindig.gadgets.Gadget;
 import org.apache.shindig.gadgets.GadgetException;
-
-import com.google.common.collect.Lists;
+import org.apache.shindig.gadgets.http.HttpRequest;
+import org.apache.shindig.gadgets.http.HttpResponse;
+import org.apache.shindig.gadgets.uri.UriCommon.Param;
 
 import java.util.List;
 
@@ -30,7 +34,6 @@ public interface ProxyUriManager {
   /**
    * Generate a Uri that proxies the given resource Uri.
    * 
-   * @param gadget Context for the rewrite
    * @param resource Resource Uri to proxy
    * @param forcedRefresh Forced expires value to use for resource
    * @return Uri of proxied resource
@@ -39,21 +42,108 @@ public interface ProxyUriManager {
   
   public static class ProxyUri extends ProxyUriBase {
     private final Uri resource;
+    private String fallbackUrl;
+    private Integer resizeHeight;
+    private Integer resizeWidth;
+    private Integer resizeQuality;
+    private boolean resizeNoExpand;
     
     public ProxyUri(Gadget gadget, Uri resource) {
       super(gadget);
       this.resource = resource;
     }
-    
+
+    public ProxyUri(Integer refresh, boolean debug, boolean noCache,
+        String container, String gadget, Uri resource) {
+      super(null, refresh, debug, noCache, container, gadget);
+      this.resource = resource;
+    }
+
     public ProxyUri(UriStatus status, Uri resource, Uri base) {
       super(status, base);
       this.resource = resource;
     }
     
+    /* (non-Javadoc)
+     * @see org.apache.shindig.gadgets.uri.ProxyUriBase#setFromUri(org.apache.shindig.common.uri.Uri)
+     */
+    @Override
+    public void setFromUri(Uri uri) {
+      super.setFromUri(uri);
+      if (uri != null) {
+        fallbackUrl = uri.getQueryParameter(Param.FALLBACK_URL_PARAM.getKey());
+        resizeHeight = getIntegerValue(uri.getQueryParameter(Param.RESIZE_HEIGHT.getKey()));
+        resizeWidth = getIntegerValue(uri.getQueryParameter(Param.RESIZE_WIDTH.getKey()));
+        resizeQuality = getIntegerValue(uri.getQueryParameter(Param.RESIZE_QUALITY.getKey()));
+        resizeNoExpand = getBooleanValue(uri.getQueryParameter(Param.NO_EXPAND.getKey()));
+      }
+    }
+
+    public ProxyUri setResize(Integer w, Integer h, Integer q, boolean noExpand) {
+      this.resizeHeight = h;
+      this.resizeWidth = w;
+      this.resizeQuality = q;
+      this.resizeNoExpand = noExpand;
+      return this;
+    }
+
+    public ProxyUri setFallbackUrl(String fallbackUrl) {
+      this.fallbackUrl = fallbackUrl;
+      return this;
+    }
+
     public Uri getResource() {
       return resource;
     }
     
+    public Uri getFallbackUri() throws GadgetException {
+      if (fallbackUrl == null) {
+        return null;
+      }
+      try {
+        // Doing delay parsing.
+        return Uri.parse(fallbackUrl);
+      } catch (IllegalArgumentException e) {
+        throw new GadgetException(GadgetException.Code.INVALID_PARAMETER,
+            Param.FALLBACK_URL_PARAM.getKey() + " param is invalid: "
+            + e, HttpResponse.SC_BAD_REQUEST);
+      }
+    }
+
+    @Override
+    public UriBuilder makeQueryParams(Integer forcedRefresh, String version) {
+      UriBuilder builder = super.makeQueryParams(forcedRefresh, version);
+      if (resizeHeight != null) {
+        builder.addQueryParameter(Param.RESIZE_HEIGHT.getKey(), resizeHeight.toString());
+      }
+      if (resizeWidth != null) {
+        builder.addQueryParameter(Param.RESIZE_WIDTH.getKey(), resizeWidth.toString());
+      }
+      if (resizeQuality != null) {
+        builder.addQueryParameter(Param.RESIZE_QUALITY.getKey(), resizeQuality.toString());
+      }
+      if (resizeNoExpand) {
+        builder.addQueryParameter(Param.NO_EXPAND.getKey(), "1");
+      }
+      if (fallbackUrl != null) {
+        builder.addQueryParameter(Param.FALLBACK_URL_PARAM.getKey(), fallbackUrl);
+      }
+      return builder;
+    }
+    
+    @Override
+    public HttpRequest makeHttpRequest(Uri targetUri) 
+        throws GadgetException {
+      HttpRequest req = super.makeHttpRequest(targetUri);
+      // Set image params:
+      req.setParam(Param.RESIZE_HEIGHT.getKey(), resizeHeight);
+      req.setParam(Param.RESIZE_WIDTH.getKey(), resizeWidth);
+      req.setParam(Param.RESIZE_QUALITY.getKey(), resizeQuality);
+      req.setParam(Param.NO_EXPAND.getKey(), resizeNoExpand);
+      return req;
+    };
+    
+    
     public static List<ProxyUri> fromList(Gadget gadget, List<Uri> uris) {
       List<ProxyUri> res = Lists.newArrayListWithCapacity(uris.size());
       for (Uri uri : uris) {

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriCommon.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriCommon.java?rev=929245&r1=929244&r2=929245&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriCommon.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriCommon.java Tue Mar 30 20:10:06 2010
@@ -35,7 +35,16 @@ public interface UriCommon {
     REFRESH("refresh"),
     LIBS("libs"),
     JSON("json"),
-    TYPE("type");
+    TYPE("type"),
+    REWRITE_MIME_TYPE("rewriteMime"),
+    SANITIZE("sanitize"),
+    
+    // Proxy resize params:
+    RESIZE_HEIGHT("resize_h"),
+    RESIZE_WIDTH("resize_w"),
+    RESIZE_QUALITY("resize_q"),
+    NO_EXPAND("no_expand"),
+    FALLBACK_URL_PARAM("fallback_url");
    
     private final String key;
     private Param(String key) {

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/ProxyHandlerTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/ProxyHandlerTest.java?rev=929245&r1=929244&r2=929245&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/ProxyHandlerTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/ProxyHandlerTest.java Tue Mar 30 20:10:06 2010
@@ -32,6 +32,7 @@ import org.apache.shindig.gadgets.http.H
 import org.apache.shindig.gadgets.http.HttpResponseBuilder;
 import org.apache.shindig.gadgets.uri.PassthruManager;
 import org.apache.shindig.gadgets.uri.ProxyUriManager;
+import org.apache.shindig.gadgets.uri.UriCommon.Param;
 import org.easymock.Capture;
 import org.junit.Test;
 
@@ -189,7 +190,7 @@ public class ProxyHandlerTest extends Se
 
     expect(lockedDomainService.isSafeForOpenProxy(domain)).andReturn(true).atLeastOnce();
     setupProxyRequestMock(domain, url, ProxyBase.IGNORE_CACHE_PARAM, "1",
-        ProxyHandler.FALLBACK_URL_PARAM, fallback_url);
+        Param.FALLBACK_URL_PARAM.getKey(), fallback_url);
 
     HttpRequest req = new HttpRequest(Uri.parse(url)).setIgnoreCache(true);
     HttpResponse resp = HttpResponse.error();

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultProxyUriManagerTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultProxyUriManagerTest.java?rev=929245&r1=929244&r2=929245&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultProxyUriManagerTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultProxyUriManagerTest.java Tue Mar 30 20:10:06 2010
@@ -63,6 +63,112 @@ public class DefaultProxyUriManagerTest 
     assertEquals(1, uris.size());
     verifyQueryUri(RESOURCE_1, uris.get(0), debug, noCache, version, host, path);
   }
+
+  @Test
+  public void refreshVerifyBasic() throws Exception {
+    verifyRefresh(false, false, "version", 20);
+  }
+
+  @Test
+  public void refreshVerifyNoCache() throws Exception {
+    verifyRefresh(false, true, "version", 20);
+  }
+
+  @Test
+  public void refreshVerifyNoRefresh() throws Exception {
+    verifyRefresh(false, false, "version", null);
+  }
+
+  public void verifyRefresh(boolean debug, boolean noCache, String version, Integer refresh)
+      throws Exception {
+    String host = "host.com";
+    String path = "/proxy/path";
+    ProxyUriManager.Versioner versioner = makeVersioner(null, version);
+    DefaultProxyUriManager manager = makeManager(host, path, versioner);
+    Gadget gadget = mockGadget(debug, noCache);
+    List<ProxyUri> proxyUris = Lists.newLinkedList();
+    proxyUris.add(new ProxyUri(refresh, debug, noCache, CONTAINER, SPEC_URI.toString(),
+        RESOURCE_1));
+    
+    List<Uri> uris = manager.make(proxyUris, null);
+    assertEquals(1, uris.size());
+    verifyQueryUriWithRefresh(RESOURCE_1, uris.get(0), debug, noCache,
+        version, refresh, host, path);
+  }
+
+  @Test
+  public void verifyAddedParamsQuery() throws Exception {
+    String host = "host.com";
+    String path = "/proxy/path";
+    ProxyUriManager.Versioner versioner = makeVersioner(null, "version1", "version2");
+    DefaultProxyUriManager manager = makeManager(host, path, versioner);
+    Gadget gadget = mockGadget(false, true);
+    List<ProxyUri> proxyUris = Lists.newLinkedList();
+    ProxyUri pUri = new ProxyUri(null, false, true, CONTAINER, SPEC_URI.toString(),
+        RESOURCE_1);
+    pUri.setResize(100, 10, 90, true);
+    proxyUris.add(pUri);
+
+    pUri = new ProxyUri(null, false, true, CONTAINER, SPEC_URI.toString(),
+        RESOURCE_2);
+    pUri.setResize(null, 10, null, false);
+    proxyUris.add(pUri);
+
+    List<Uri> uris = manager.make(proxyUris, null);
+    assertEquals(2, uris.size());
+    verifyQueryUriWithRefresh(RESOURCE_1, uris.get(0), false, true,
+        "version1", null, host, path);
+    // Verify added param:
+    assertEquals("100", uris.get(0).getQueryParameter("resize_w"));
+    assertEquals("10", uris.get(0).getQueryParameter("resize_h"));
+    assertEquals("90", uris.get(0).getQueryParameter("resize_q"));
+    assertEquals("1", uris.get(0).getQueryParameter("no_expand"));
+    assertEquals(null, uris.get(1).getQueryParameter("resize_w"));
+    assertEquals("10", uris.get(1).getQueryParameter("resize_h"));
+    assertEquals(null, uris.get(1).getQueryParameter("resize_q"));
+    assertEquals(null, uris.get(1).getQueryParameter("no_expand"));
+  }
+  
+  @Test
+  public void verifyAddedParamsChained() throws Exception {
+    String host = "host.com";
+    String path = "/proxy/" + DefaultProxyUriManager.CHAINED_PARAMS_TOKEN + "/path";
+    ProxyUriManager.Versioner versioner = makeVersioner(null, "version");
+    DefaultProxyUriManager manager = makeManager(host, path, versioner);
+    Gadget gadget = mockGadget(false, true);
+    List<ProxyUri> proxyUris = Lists.newLinkedList();
+    ProxyUri pUri = new ProxyUri(null, false, true, CONTAINER, SPEC_URI.toString(),
+        RESOURCE_1);
+    pUri.setResize(100, 10, 90, true);
+    proxyUris.add(pUri);
+    
+    List<Uri> uris = manager.make(proxyUris, null);
+    assertEquals(1, uris.size());
+    verifyChainedUri(RESOURCE_1, uris.get(0), false, true,
+        null, false, host, path);
+    // Verify added param:
+    assertEquals("/proxy/container=container&gadget=http%3A%2F%2Fexample.com%2Fgadget.xml" +
+        "&debug=0&nocache=1&v=version&resize_h=10&resize_w=100&resize_q=90&no_expand=1" +
+        "/path/http://example.com/one.dat",
+        uris.get(0).getPath());
+  }
+
+  @Test
+  public void testFallbackUrl() throws Exception {
+    ProxyUri uri = new ProxyUri(null, false, false, "open", "http://example.com/gadget",
+        Uri.parse("http://example.com/resource"));
+    uri.setFallbackUrl("http://example.com/fallback");
+    
+    assertEquals("http://example.com/fallback", uri.getFallbackUri().toString());
+  }
+  
+  @Test(expected = GadgetException.class)
+  public void testBadFallbackUrl() throws Exception {
+    ProxyUri uri = new ProxyUri(null, false, false, "open", "http://example.com/gadget",
+        Uri.parse("http://example.com/resource"));
+    uri.setFallbackUrl("bad url");
+    uri.getFallbackUri(); // throws exception!
+  }
   
   @Test
   public void basicProxyChainedStyle() throws Exception {
@@ -127,7 +233,7 @@ public class DefaultProxyUriManagerTest 
       verifyChainedUri(resources.get(i), uris.get(i), true, true, versions[i], false, host, path);
     }
   }
-  
+
   @Test
   public void validateQueryStyleUnversioned() throws Exception {
     // Validate tests also serve as end-to-end tests: create, unpack.
@@ -249,32 +355,43 @@ public class DefaultProxyUriManagerTest 
 
   private List<Uri> makeAndGet(String host, String path, boolean debug, boolean noCache,
       List<Uri> resources, String... version) {
+    return makeAndGetWithRefresh(host, path, debug, noCache, resources, 123, version);
+  }
+  
+  private List<Uri> makeAndGetWithRefresh(String host, String path, boolean debug,
+      boolean noCache, List<Uri> resources, Integer refresh, String... version) {
     ProxyUriManager.Versioner versioner = makeVersioner(null, version);
     DefaultProxyUriManager manager = makeManager(host, path, versioner);
     Gadget gadget = mockGadget(debug, noCache);
     return manager.make(
-        ProxyUriManager.ProxyUri.fromList(gadget, resources), 123);
+        ProxyUriManager.ProxyUri.fromList(gadget, resources), refresh);
   }
-  
+
   private void verifyQueryUri(Uri orig, Uri uri, boolean debug, boolean noCache, String version,
       String host, String path) throws Exception {
+    verifyQueryUriWithRefresh(orig, uri, debug, noCache, version, 123, host, path);
+  }
+  
+  private void verifyQueryUriWithRefresh(Uri orig, Uri uri, boolean debug, boolean noCache,
+      String version, Integer refresh, String host, String path) throws Exception {
     // Make sure the manager can parse out results.
     DefaultProxyUriManager manager = makeManager(host, path, null);
     ProxyUri proxyUri = manager.process(uri);
     assertEquals(orig, proxyUri.getResource());
     assertEquals(debug, proxyUri.isDebug());
     assertEquals(noCache, proxyUri.isNoCache());
-    assertEquals(noCache ? 0 : 123, (int)proxyUri.getRefresh());
+    assertEquals(noCache ? new Integer(0) : refresh, proxyUri.getRefresh());
     assertEquals(CONTAINER, proxyUri.getContainer());
     assertEquals(SPEC_URI.toString(), proxyUri.getGadget());
     
     // "Raw" query param verification.
-    assertEquals("123", uri.getQueryParameter(Param.REFRESH.getKey()));
+    assertEquals(noCache || refresh == null ? null : refresh.toString(),
+        uri.getQueryParameter(Param.REFRESH.getKey()));
     if (version != null) {
       assertEquals(version, uri.getQueryParameter(Param.VERSION.getKey()));
     }
   }
-  
+
   private void verifyChainedUri(Uri orig, Uri uri, boolean debug, boolean noCache, String version,
       boolean endOfPath, String host, String path)
       throws Exception {
@@ -299,7 +416,7 @@ public class DefaultProxyUriManagerTest 
     uri = new UriBuilder().setQuery(paramsUri).toUri();
     
     // "Raw" query param verification.
-    assertEquals("123", uri.getQueryParameter(Param.REFRESH.getKey()));
+    assertEquals(noCache ? null : "123", uri.getQueryParameter(Param.REFRESH.getKey()));
     if (version != null) {
       assertEquals(version, uri.getQueryParameter(Param.VERSION.getKey()));
     }