You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by jo...@gmail.com on 2010/05/26 20:13:02 UTC

Add JSONP-style onload "handler" to JsServlet (issue1313042)

Reviewers: shindig.remailer_gmail.com, mhermanto, zhoresh, jtarrio,

Description:
Particularly for container JavaScript but in other cases as well,
clients loading JavaScript from Shindig occasionally do so using dynamic
loading. When doing so, they need to know when the servlet's JS has
completed loading, which is difficult to impossible to do across all
browsers consistently in this case.

This CL adds support for the "onload" query parameter to JsServlet. Its
value is the name of a method defined globally that indicates loading
has completed, the call appended to the tail of the request. The param
is sanitized by a simple regular expression and JS escaping.

Please review this at http://codereview.appspot.com/1313042/show

Affected files:
    
java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsServlet.java


Index:  
java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsServlet.java
===================================================================
---  
java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsServlet.java	 
(revision 948322)
+++  
java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsServlet.java	 
(working copy)
@@ -20,6 +20,8 @@
  import com.google.common.collect.ImmutableSet;

  import com.google.common.collect.Maps;
+
+import org.apache.commons.lang.StringEscapeUtils;
  import org.apache.commons.lang.StringUtils;
  import org.apache.shindig.common.JsonSerializer;
  import org.apache.shindig.common.servlet.HttpUtil;
@@ -38,6 +40,7 @@
  import java.util.Collection;
  import java.util.Map;
  import java.util.Set;
+import java.util.regex.Pattern;

  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
@@ -47,6 +50,13 @@
   * Used by type=URL gadgets in loading JavaScript resources.
   */
  public class JsServlet extends InjectedServlet {
+  static final String ONLOAD_JS_TPL = "(function() {" +
+      "var nm='%s';" +
+      "if (typeof window[nm]==='function') {" +
+      "window[nm]();" +
+      "}" +
+      "})();";
+  private static final Pattern ONLOAD_FN_PATTERN =  
Pattern.compile("[a-zA-Z0-9_]+");

    private FeatureRegistry registry;
    @Inject
@@ -148,6 +158,16 @@
        }
      }

+    String onloadStr = req.getParameter("onload");
+    if (onloadStr != null) {
+      if (!ONLOAD_FN_PATTERN.matcher(onloadStr).matches()) {
+        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid onload  
callback: " +
+            onloadStr);
+        return;
+      }
+      jsData.append(String.format(ONLOAD_JS_TPL,  
StringEscapeUtils.escapeJavaScript(onloadStr)));
+    }
+
      if (jsData.length() == 0) {
        resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
        return;