You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by lr...@apache.org on 2008/02/07 18:40:38 UTC

svn commit: r619525 - in /incubator/shindig/trunk: features/core/io.js java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java

Author: lryan
Date: Thu Feb  7 09:40:33 2008
New Revision: 619525

URL: http://svn.apache.org/viewvc?rev=619525&view=rev
Log:
Fix error handling, post handling in makeRequest
Fix response binding in ProxyHandler
Fix handling of double-encoded URLS and URLs of the form x.y.com?a=b

Modified:
    incubator/shindig/trunk/features/core/io.js
    incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java

Modified: incubator/shindig/trunk/features/core/io.js
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/features/core/io.js?rev=619525&r1=619524&r2=619525&view=diff
==============================================================================
--- incubator/shindig/trunk/features/core/io.js (original)
+++ incubator/shindig/trunk/features/core/io.js Thu Feb  7 09:40:33 2008
@@ -60,6 +60,11 @@
     if (xobj.readyState !== 4) {
       return;
     }
+    if (xobj.status !== 200) {
+      // TODO Need to work on standardizing errors
+      callback({errors : ["Error " + xobj.status] });
+      return;
+    }
     var txt = xobj.responseText;
     // remove unparseable cruft.
     // TODO: really remove this by eliminating it. It's not any real security
@@ -76,6 +81,10 @@
       case "JSON":
       case "FEED":
         resp.data = gadgets.json.parse(resp.text);
+        if (!resp.data) {
+          resp.errors = ["failed to parse JSON"];
+          resp.data = null;
+        }
         break;
      case "DOM":
       var dom;
@@ -84,12 +93,20 @@
         dom.async = false;
         dom.validateOnParse = false;
         dom.resolveExternals = false;
-        dom.loadXML(resp.text);
+        if (!dom.loadXML(resp.text)) {
+          resp.errors = ["failed to parse XML"];
+        } else {
+          resp.data = dom;
+        }
       } else {
         var parser = new DOMParser();
         dom = parser.parseFromString(resp.text, "text/xml");
+        if ("parsererror" == dom.documentElement.nodeName) {
+          resp.errors = ["failed to parse XML"];
+        } else {
+          resp.data = dom;
+        }
       }
-      resp.data = dom;
       break;
     default:
       resp.data = resp.text;
@@ -128,7 +145,7 @@
           encodeURIComponent(url));
 
       // Check if authorization is requested
-      if (opt_params.AUTHORIZATION &&
+      if (opt_params && opt_params.AUTHORIZATION &&
           gadgets.io.AuthorizationType[opt_params.AUTHORIZATION.toUpperCase()]
               != gadgets.io.AuthorizationType.NONE) {
         newUrl += "&authz=" + opt_params.AUTHORIZATION.toLowerCase();
@@ -143,8 +160,16 @@
         xhr.onreadystatechange = gadgets.util.makeClosure(null,
             processResponse, url, callback, params, xhr);
       }
-      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
-      xhr.send("postData=" + encodeURIComponent(params.postData));
+      if (params.METHOD == "POST") {
+        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+        if (params.postData) {
+          xhr.send("postData=" + encodeURIComponent(params.postData));
+        } else {
+          xhr.send("postData=");
+        }
+      } else {
+        xhr.send();
+      }
     },
 
     /**

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java?rev=619525&r1=619524&r2=619525&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java Thu Feb  7 09:40:33 2008
@@ -34,6 +34,8 @@
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLDecoder;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.List;
 import java.util.Map;
 
@@ -71,22 +73,26 @@
     RemoteContent results = fetchContent(signedUrl, request,
         new ProcessingOptions());
 
-    String output;
-    try {
-      String json = new JSONObject().put(originalUrl.toString(), new JSONObject()
-          .put("body", new String(results.getByteArray()))
-          .put("rc", results.getHttpStatusCode())
-          ).toString();
-      output = UNPARSEABLE_CRUFT + json;
-    } catch (JSONException e) {
-      output = "";
+    response.setStatus(results.getHttpStatusCode());
+    if (results.getHttpStatusCode() == HttpServletResponse.SC_OK) {
+      String output;
+      try {
+        // Use raw param as key as URL may have to be decoded
+        String json = new JSONObject().put(request.getParameter("url"), new JSONObject()
+            .put("body", new String(results.getByteArray()))
+            .put("rc", results.getHttpStatusCode())
+            ).toString();
+        output = UNPARSEABLE_CRUFT + json;
+      } catch (JSONException e) {
+        output = "";
+      }
+
+      setCachingHeaders(response);
+      response.setContentType("application/json; charset=utf-8");
+      response.setHeader("Content-Disposition", "attachment;filename=p.txt");
+      PrintWriter pw = response.getWriter();
+      pw.write(output);
     }
-    response.setStatus(HttpServletResponse.SC_OK);
-    setCachingHeaders(response);
-    response.setContentType("application/json; charset=utf-8");
-    response.setHeader("Content-Disposition", "attachment;filename=p.txt");
-    PrintWriter pw = response.getWriter();
-    pw.write(output);
   }
 
   public void fetch(HttpServletRequest request,
@@ -152,26 +158,42 @@
    * @return A URL object of the URL
    * @throws ServletException if the URL fails security checks or is malformed.
    */
-  private URL extractAndValidateUrl(HttpServletRequest request)
+  private URL extractAndValidateUrl(HttpServletRequest request)                                                                 
       throws ServletException {
     String url = request.getParameter("url");
     if (url == null) {
       throw new ServletException("Missing url parameter");
     }
 
-    // TODO: are there other tests that should be here?
-    // url.matches("[a-zA-Z0-9_:%&#+-]+"), perhaps?
-    if (!url.startsWith("http://")) {
-      throw new ServletException("url parameter does not start with http://");
-    }
-
-    URL origin;
     try {
-      origin = new URL(url);
-    } catch (MalformedURLException e) {
-      throw new ServletException("Malformed url parameter");
+      URI origin = new URI(request.getParameter("url"));
+      if (origin.getScheme() == null) {
+        // No scheme, assume it was double-encoded.
+        origin = new URI(
+            URLDecoder.decode(request.getParameter("url"), request.getCharacterEncoding()));
+        if (origin.getScheme() == null) {
+          throw new ServletException("Invalid URL " + origin.toString());
+        }
+      }
+      if (!origin.getScheme().equals("http")) {
+        throw new ServletException("Unsupported protocol: " + origin.getScheme());
+      }
+      if (origin.getPath() == null || origin.getPath().length() == 0) {
+        // Forcibly set the path to "/" if it is empty
+        origin = new URI(origin.getScheme(),
+            origin.getUserInfo(), origin.getHost(),
+            origin.getPort(),
+            "/", origin.getQuery(),
+            origin.getFragment());
+      }
+      return origin.toURL();
+    } catch (URISyntaxException use) {
+      throw new ServletException("Malformed URL " + use.getMessage());
+    } catch (MalformedURLException mfe) {
+      throw new ServletException("Malformed URL " + mfe.getMessage());
+    } catch (UnsupportedEncodingException uee) {
+      throw new ServletException("Unsupported encoding " + uee.getMessage());
     }
-    return origin;
   }
 
   /**



Re: svn commit: r619525 - in /incubator/shindig/trunk: features/core/io.js java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java

Posted by Kevin Brown <et...@google.com>.
On Feb 7, 2008 9:40 AM, <lr...@apache.org> wrote:

> Author: lryan
> Date: Thu Feb  7 09:40:33 2008
> New Revision: 619525
>
> URL: http://svn.apache.org/viewvc?rev=619525&view=rev
> Log:
> Fix error handling, post handling in makeRequest
> Fix response binding in ProxyHandler
> Fix handling of double-encoded URLS and URLs of the form x.y.com?a=b
>
> Modified:
>    incubator/shindig/trunk/features/core/io.js
>
>  incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java
>
> Modified: incubator/shindig/trunk/features/core/io.js
> URL:
> http://svn.apache.org/viewvc/incubator/shindig/trunk/features/core/io.js?rev=619525&r1=619524&r2=619525&view=diff
>
> ==============================================================================
> --- incubator/shindig/trunk/features/core/io.js (original)
> +++ incubator/shindig/trunk/features/core/io.js Thu Feb  7 09:40:33 2008
> @@ -60,6 +60,11 @@
>     if (xobj.readyState !== 4) {
>       return;
>     }
> +    if (xobj.status !== 200) {
> +      // TODO Need to work on standardizing errors
> +      callback({errors : ["Error " + xobj.status] });
> +      return;
> +    }
>     var txt = xobj.responseText;
>     // remove unparseable cruft.
>     // TODO: really remove this by eliminating it. It's not any real
> security
> @@ -76,6 +81,10 @@
>       case "JSON":
>       case "FEED":
>         resp.data = gadgets.json.parse(resp.text);
> +        if (!resp.data) {
> +          resp.errors = ["failed to parse JSON"];
> +          resp.data = null;
> +        }
>         break;
>      case "DOM":
>       var dom;
> @@ -84,12 +93,20 @@
>         dom.async = false;
>         dom.validateOnParse = false;
>         dom.resolveExternals = false;
> -        dom.loadXML(resp.text);
> +        if (!dom.loadXML(resp.text)) {
> +          resp.errors = ["failed to parse XML"];
> +        } else {
> +          resp.data = dom;
> +        }
>       } else {
>         var parser = new DOMParser();
>         dom = parser.parseFromString(resp.text, "text/xml");
> +        if ("parsererror" == dom.documentElement.nodeName) {
> +          resp.errors = ["failed to parse XML"];
> +        } else {
> +          resp.data = dom;
> +        }
>       }
> -      resp.data = dom;
>       break;
>     default:
>       resp.data = resp.text;
> @@ -128,7 +145,7 @@
>           encodeURIComponent(url));
>
>       // Check if authorization is requested
> -      if (opt_params.AUTHORIZATION &&
> +      if (opt_params && opt_params.AUTHORIZATION &&
>           gadgets.io.AuthorizationType
> [opt_params.AUTHORIZATION.toUpperCase()]
>               != gadgets.io.AuthorizationType.NONE) {
>         newUrl += "&authz=" + opt_params.AUTHORIZATION.toLowerCase();
> @@ -143,8 +160,16 @@
>         xhr.onreadystatechange = gadgets.util.makeClosure(null,
>             processResponse, url, callback, params, xhr);
>       }
> -      xhr.setRequestHeader('Content-Type',
> 'application/x-www-form-urlencoded');
> -      xhr.send("postData=" + encodeURIComponent(params.postData));
> +      if (params.METHOD == "POST") {
> +        xhr.setRequestHeader('Content-Type',
> 'application/x-www-form-urlencoded');
> +        if (params.postData) {
> +          xhr.send("postData=" + encodeURIComponent(params.postData));
> +        } else {
> +          xhr.send("postData=");
> +        }
> +      } else {
> +        xhr.send();
> +      }
>     },
>
>     /**
>
> Modified:
> incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java
> URL:
> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java?rev=619525&r1=619524&r2=619525&view=diff
>
> ==============================================================================
> ---
> incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java
> (original)
> +++
> incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java
> Thu Feb  7 09:40:33 2008
> @@ -34,6 +34,8 @@
>  import java.net.MalformedURLException;
>  import java.net.URL;
>  import java.net.URLDecoder;
> +import java.net.URI;
> +import java.net.URISyntaxException;
>  import java.util.List;
>  import java.util.Map;
>
> @@ -71,22 +73,26 @@
>     RemoteContent results = fetchContent(signedUrl, request,
>         new ProcessingOptions());
>
> -    String output;
> -    try {
> -      String json = new JSONObject().put(originalUrl.toString(), new
> JSONObject()
> -          .put("body", new String(results.getByteArray()))
> -          .put("rc", results.getHttpStatusCode())
> -          ).toString();
> -      output = UNPARSEABLE_CRUFT + json;
> -    } catch (JSONException e) {
> -      output = "";
> +    response.setStatus(results.getHttpStatusCode());


This was intentionally always sending a 200; the status code is returned in
the response body ("rc"). This is important for when we implement batching
of http requests.


> +    if (results.getHttpStatusCode() == HttpServletResponse.SC_OK) {
> +      String output;
> +      try {
> +        // Use raw param as key as URL may have to be decoded
> +        String json = new JSONObject().put(request.getParameter("url"),
> new JSONObject()
> +            .put("body", new String(results.getByteArray()))
> +            .put("rc", results.getHttpStatusCode())
> +            ).toString();
> +        output = UNPARSEABLE_CRUFT + json;
> +      } catch (JSONException e) {
> +        output = "";
> +      }
> +
> +      setCachingHeaders(response);
> +      response.setContentType("application/json; charset=utf-8");
> +      response.setHeader("Content-Disposition", "attachment;filename=
> p.txt");
> +      PrintWriter pw = response.getWriter();
> +      pw.write(output);
>     }
> -    response.setStatus(HttpServletResponse.SC_OK);
> -    setCachingHeaders(response);
> -    response.setContentType("application/json; charset=utf-8");
> -    response.setHeader("Content-Disposition", "attachment;filename=p.txt
> ");
> -    PrintWriter pw = response.getWriter();
> -    pw.write(output);
>   }
>
>   public void fetch(HttpServletRequest request,
> @@ -152,26 +158,42 @@
>    * @return A URL object of the URL
>    * @throws ServletException if the URL fails security checks or is
> malformed.
>    */
> -  private URL extractAndValidateUrl(HttpServletRequest request)
> +  private URL extractAndValidateUrl(HttpServletRequest request)
>       throws ServletException {
>     String url = request.getParameter("url");
>     if (url == null) {
>       throw new ServletException("Missing url parameter");
>     }
>
> -    // TODO: are there other tests that should be here?
> -    // url.matches("[a-zA-Z0-9_:%&#+-]+"), perhaps?
> -    if (!url.startsWith("http://")) {
> -      throw new ServletException("url parameter does not start with
> http://");
> -    }
> -
> -    URL origin;
>     try {
> -      origin = new URL(url);
> -    } catch (MalformedURLException e) {
> -      throw new ServletException("Malformed url parameter");
> +      URI origin = new URI(request.getParameter("url"));
> +      if (origin.getScheme() == null) {
> +        // No scheme, assume it was double-encoded.
> +        origin = new URI(
> +            URLDecoder.decode(request.getParameter("url"),
> request.getCharacterEncoding()));
> +        if (origin.getScheme() == null) {
> +          throw new ServletException("Invalid URL " + origin.toString());
> +        }
> +      }
> +      if (!origin.getScheme().equals("http")) {
> +        throw new ServletException("Unsupported protocol: " +
> origin.getScheme());
> +      }
> +      if (origin.getPath() == null || origin.getPath().length() == 0) {
> +        // Forcibly set the path to "/" if it is empty
> +        origin = new URI(origin.getScheme(),
> +            origin.getUserInfo(), origin.getHost(),
> +            origin.getPort(),
> +            "/", origin.getQuery(),
> +            origin.getFragment());
> +      }
> +      return origin.toURL();
> +    } catch (URISyntaxException use) {
> +      throw new ServletException("Malformed URL " + use.getMessage());
> +    } catch (MalformedURLException mfe) {
> +      throw new ServletException("Malformed URL " + mfe.getMessage());
> +    } catch (UnsupportedEncodingException uee) {
> +      throw new ServletException("Unsupported encoding " + uee.getMessage
> ());
>     }
> -    return origin;
>   }
>
>   /**
>
>
>