[exo-jcr-commits] exo-jcr SVN: r2712 - in ws/branches/2.1.x: exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/proxy and 1 other directory.

do-not-reply at jboss.org do-not-reply at jboss.org
Tue Jun 29 06:48:19 EDT 2010


Author: aparfonov
Date: 2010-06-29 06:48:18 -0400 (Tue, 29 Jun 2010)
New Revision: 2712

Modified:
   ws/branches/2.1.x/exo.ws.commons/src/main/java/org/exoplatform/common/http/client/AuthorizationInfo.java
   ws/branches/2.1.x/exo.ws.commons/src/main/java/org/exoplatform/common/http/client/HTTPResponse.java
   ws/branches/2.1.x/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/proxy/ProxyService.java
Log:
EXOJCR-800

Modified: ws/branches/2.1.x/exo.ws.commons/src/main/java/org/exoplatform/common/http/client/AuthorizationInfo.java
===================================================================
--- ws/branches/2.1.x/exo.ws.commons/src/main/java/org/exoplatform/common/http/client/AuthorizationInfo.java	2010-06-29 10:35:54 UTC (rev 2711)
+++ ws/branches/2.1.x/exo.ws.commons/src/main/java/org/exoplatform/common/http/client/AuthorizationInfo.java	2010-06-29 10:48:18 UTC (rev 2712)
@@ -26,7 +26,7 @@
  *
  *  The HTTPClient's home page is located at:
  *
- *  http://www.innovation.ch/java/HTTPClient/ 
+ *  http://www.innovation.ch/java/HTTPClient/
  *
  */
 
@@ -54,18 +54,18 @@
  * used by the "Basic" scheme and derivatives, and the one used by the "Digest"
  * scheme and derivatives. The first form contains just the the scheme and a
  * "cookie":
- * 
+ *
  * <PRE>
  *     Authorization: Basic aGVsbG86d29ybGQ=
  * </PRE>
- * 
+ *
  * The second form contains the scheme followed by a number of parameters in the
  * form of name=value pairs:
- * 
+ *
  * <PRE>
  *     Authorization: Digest username=&quot;hello&quot;, realm=&quot;test&quot;, nonce=&quot;42&quot;, ...
  * </PRE>
- * 
+ *
  * The two fields "cookie" and "params" correspond to these two forms. <A
  * HREF="#toString()">toString()</A> is used by the AuthorizationModule when
  * generating the Authorization header and will format the info accordingly.
@@ -85,6 +85,7 @@
  * methods manipulate and query an internal list of AuthorizationInfo instances.
  * There can be only one instance per host, port, scheme, and realm combination
  * (see <A HREF="#equals">equals()</A>).
+ *
  * @version 0.3-3 06/05/2001
  * @author Ronald Tschal�r
  * @since V0.1
@@ -113,8 +114,8 @@
    private int port;
 
    /**
-    * the scheme. (e.g. "Basic") Note: don't lowercase because some buggy servers
-    * use a case-sensitive match
+    * the scheme. (e.g. "Basic") Note: don't lowercase because some buggy
+    * servers use a case-sensitive match
     */
    private String scheme;
 
@@ -140,6 +141,7 @@
 
    /**
     * Creates an new info structure for the specified host and port.
+    *
     * @param host the host
     * @param port the port
     */
@@ -152,6 +154,7 @@
    /**
     * Creates a new info structure for the specified host and port with the
     * specified scheme, realm, params. The cookie is set to null.
+    *
     * @param host the host
     * @param port the port
     * @param scheme the scheme
@@ -177,13 +180,14 @@
     * Creates a new info structure for the specified host and port with the
     * specified scheme, realm and cookie. The params is set to a zero-length
     * array, and the extra_info is set to null.
+    *
     * @param host the host
     * @param port the port
     * @param scheme the scheme
     * @param realm the realm
     * @param cookie for the "Basic" scheme this is the base64-encoded
-    *          username/password; for the "NTLM" scheme this is the
-    *          base64-encoded username/password message.
+    *        username/password; for the "NTLM" scheme this is the base64-encoded
+    *        username/password message.
     */
    public AuthorizationInfo(String host, int port, String scheme, String realm, String cookie)
    {
@@ -199,6 +203,7 @@
 
    /**
     * Creates a new copy of the given AuthorizationInfo.
+    *
     * @param templ the info to copy
     */
    AuthorizationInfo(AuthorizationInfo templ)
@@ -217,10 +222,10 @@
    // Class Methods
 
    /**
-    * Set's the authorization handler. This handler is called whenever the server
-    * requests authorization and no entry for the requested scheme and realm can
-    * be found in the list. The handler must implement the AuthorizationHandler
-    * interface.
+    * Set's the authorization handler. This handler is called whenever the
+    * server requests authorization and no entry for the requested scheme and
+    * realm can be found in the list. The handler must implement the
+    * AuthorizationHandler interface.
     * <P>
     * If no handler is set then a {@link DefaultAuthHandler default handler} is
     * used. This handler currently only handles the "Basic" and "Digest" schemes
@@ -228,6 +233,7 @@
     * <P>
     * The default handler can be disabled by setting the auth handler to
     * <var>null</var>.
+    *
     * @param handler the new authorization handler
     * @return the old authorization handler
     * @see AuthorizationHandler
@@ -242,6 +248,7 @@
 
    /**
     * Get's the current authorization handler.
+    *
     * @return the current authorization handler, or null if none is set.
     * @see AuthorizationHandler
     */
@@ -253,6 +260,7 @@
    /**
     * Searches for the authorization info using the given host, port, scheme and
     * realm. The context is the default context.
+    *
     * @param host the host
     * @param port the port
     * @param scheme the scheme
@@ -267,6 +275,7 @@
    /**
     * Searches for the authorization info in the given context using the given
     * host, port, scheme and realm.
+    *
     * @param host the host
     * @param port the port
     * @param scheme the scheme
@@ -287,13 +296,15 @@
    /**
     * Queries the AuthHandler for authorization info. It also adds this info to
     * the list.
-    * @param auth_info any info needed by the AuthHandler; at a minimum the host,
-    *          scheme and realm should be set.
+    *
+    * @param auth_info any info needed by the AuthHandler; at a minimum the
+    *        host, scheme and realm should be set.
     * @param req the request which initiated this query
     * @param resp the full response
     * @return a structure containing the requested info, or null if either no
     *         AuthHandler is set or the user canceled the request.
-    * @exception AuthSchemeNotImplException if this is thrown by the AuthHandler.
+    * @exception AuthSchemeNotImplException if this is thrown by the
+    *            AuthHandler.
     */
    static AuthorizationInfo queryAuthHandler(AuthorizationInfo auth_info, RoRequest req, RoResponse resp)
       throws AuthSchemeNotImplException, IOException
@@ -317,6 +328,7 @@
     * Searches for the authorization info using the host, port, scheme and realm
     * from the given info struct. If not found it queries the AuthHandler (if
     * set).
+    *
     * @param auth_info the AuthorizationInfo
     * @param req the request which initiated this query
     * @param resp the full response
@@ -335,6 +347,11 @@
 
       AuthorizationInfo new_info = (AuthorizationInfo)AuthList.get(auth_info);
 
+      if (new_info == null)
+         new_info =
+            (AuthorizationInfo)AuthList.get(new AuthorizationInfo(auth_info.getHost(), auth_info.getPort(), auth_info
+               .getScheme(), null, auth_info.getParams(), auth_info.getExtraInfo()));
+
       if (new_info == null && query_auth_h)
          new_info = queryAuthHandler(auth_info, req, resp);
 
@@ -344,6 +361,7 @@
    /**
     * Searches for the authorization info given a host, port, scheme and realm.
     * Queries the AuthHandler if not found in list.
+    *
     * @param host the host
     * @param port the port
     * @param scheme the scheme
@@ -363,8 +381,9 @@
 
    /**
     * Adds an authorization entry to the list using the default context. If an
-    * entry for the specified scheme and realm already exists then its cookie and
-    * params are replaced with the new data.
+    * entry for the specified scheme and realm already exists then its cookie
+    * and params are replaced with the new data.
+    *
     * @param auth_info the AuthorizationInfo to add
     */
    public static void addAuthorization(AuthorizationInfo auth_info)
@@ -376,6 +395,7 @@
     * Adds an authorization entry to the list. If an entry for the specified
     * scheme and realm already exists then its cookie and params are replaced
     * with the new data.
+    *
     * @param auth_info the AuthorizationInfo to add
     * @param context the context to associate this info with
     */
@@ -403,8 +423,9 @@
 
    /**
     * Adds an authorization entry to the list using the default context. If an
-    * entry for the specified scheme and realm already exists then its cookie and
-    * params are replaced with the new data.
+    * entry for the specified scheme and realm already exists then its cookie
+    * and params are replaced with the new data.
+    *
     * @param host the host
     * @param port the port
     * @param scheme the scheme
@@ -423,6 +444,7 @@
     * Adds an authorization entry to the list. If an entry for the specified
     * scheme and realm already exists then its cookie and params are replaced
     * with the new data.
+    *
     * @param host the host
     * @param port the port
     * @param scheme the scheme
@@ -447,6 +469,7 @@
     * Adds an authorization entry for the "Basic" authorization scheme to the
     * list using the default context. If an entry already exists for the "Basic"
     * scheme and the specified realm then it is overwritten.
+    *
     * @param host the host
     * @param port the port
     * @param realm the realm
@@ -462,6 +485,7 @@
     * Adds an authorization entry for the "Basic" authorization scheme to the
     * list. If an entry already exists for the "Basic" scheme and the specified
     * realm then it is overwritten.
+    *
     * @param host the host
     * @param port the port
     * @param realm the realm
@@ -478,8 +502,9 @@
 
    /**
     * Adds an authorization entry for the "Digest" authorization scheme to the
-    * list using the default context. If an entry already exists for the "Digest"
-    * scheme and the specified realm then it is overwritten.
+    * list using the default context. If an entry already exists for the
+    * "Digest" scheme and the specified realm then it is overwritten.
+    *
     * @param host the host
     * @param port the port
     * @param realm the realm
@@ -495,6 +520,7 @@
     * Adds an authorization entry for the "Digest" authorization scheme to the
     * list. If an entry already exists for the "Digest" scheme and the specified
     * realm then it is overwritten.
+    *
     * @param host the host
     * @param port the port
     * @param realm the realm
@@ -538,6 +564,7 @@
     * Removes an authorization entry from the list using the default context. If
     * no entry for the specified host, port, scheme and realm exists then this
     * does nothing.
+    *
     * @param auth_info the AuthorizationInfo to remove
     */
    public static void removeAuthorization(AuthorizationInfo auth_info)
@@ -546,8 +573,9 @@
    }
 
    /**
-    * Removes an authorization entry from the list. If no entry for the specified
-    * host, port, scheme and realm exists then this does nothing.
+    * Removes an authorization entry from the list. If no entry for the
+    * specified host, port, scheme and realm exists then this does nothing.
+    *
     * @param auth_info the AuthorizationInfo to remove
     * @param context the context this info is associated with
     */
@@ -561,6 +589,7 @@
     * Removes an authorization entry from the list using the default context. If
     * no entry for the specified host, port, scheme and realm exists then this
     * does nothing.
+    *
     * @param host the host
     * @param port the port
     * @param scheme the scheme
@@ -572,8 +601,9 @@
    }
 
    /**
-    * Removes an authorization entry from the list. If no entry for the specified
-    * host, port, scheme and realm exists then this does nothing.
+    * Removes an authorization entry from the list. If no entry for the
+    * specified host, port, scheme and realm exists then this does nothing.
+    *
     * @param host the host
     * @param port the port
     * @param scheme the scheme
@@ -587,9 +617,10 @@
 
    /**
     * Tries to find the candidate in the current list of auth info for the given
-    * request. The paths associated with each auth info are examined, and the one
-    * with either the nearest direct parent or child is chosen. This is used for
-    * preemptively sending auth info.
+    * request. The paths associated with each auth info are examined, and the
+    * one with either the nearest direct parent or child is chosen. This is used
+    * for preemptively sending auth info.
+    *
     * @param req the Request
     * @return an AuthorizationInfo containing the info for the best match, or
     *         null if none found.
@@ -675,6 +706,7 @@
    /**
     * Adds the path from the given resource to our path list. The path list is
     * used for deciding when to preemptively send auth info.
+    *
     * @param resource the resource from which to extract the path
     */
    public synchronized void addPath(String resource)
@@ -692,11 +724,12 @@
    }
 
    /**
-    * Parses the authentication challenge(s) into an array of new info structures
-    * for the specified host and port.
-    * @param challenge a string containing authentication info. This must have the
-    *          same format as value part of a WWW-authenticate response header
-    *          field, and may contain multiple authentication challenges.
+    * Parses the authentication challenge(s) into an array of new info
+    * structures for the specified host and port.
+    *
+    * @param challenge a string containing authentication info. This must have
+    *        the same format as value part of a WWW-authenticate response header
+    *        field, and may contain multiple authentication challenges.
     * @param req the original request.
     * @exception ProtocolException if any error during the parsing occurs.
     */
@@ -887,6 +920,7 @@
 
    /**
     * Get the host.
+    *
     * @return a string containing the host name.
     */
    public final String getHost()
@@ -896,6 +930,7 @@
 
    /**
     * Get the port.
+    *
     * @return an int containing the port number.
     */
    public final int getPort()
@@ -905,6 +940,7 @@
 
    /**
     * Get the scheme.
+    *
     * @return a string containing the scheme.
     */
    public final String getScheme()
@@ -914,6 +950,7 @@
 
    /**
     * Get the realm.
+    *
     * @return a string containing the realm.
     */
    public final String getRealm()
@@ -923,6 +960,7 @@
 
    /**
     * Get the cookie
+    *
     * @return the cookie String
     * @since V0.3-1
     */
@@ -933,6 +971,7 @@
 
    /**
     * Set the cookie
+    *
     * @param cookie the new cookie
     * @since V0.3-1
     */
@@ -943,6 +982,7 @@
 
    /**
     * Get the authentication parameters.
+    *
     * @return an array of name/value pairs.
     */
    public final NVPair[] getParams()
@@ -952,6 +992,7 @@
 
    /**
     * Set the authentication parameters.
+    *
     * @param an array of name/value pairs.
     */
    public final void setParams(NVPair[] params)
@@ -964,6 +1005,7 @@
 
    /**
     * Get the extra info.
+    *
     * @return the extra_info object
     */
    public final Object getExtraInfo()
@@ -973,6 +1015,7 @@
 
    /**
     * Set the extra info.
+    *
     * @param info the extra info
     */
    public final void setExtraInfo(Object info)
@@ -983,6 +1026,7 @@
    /**
     * Constructs a string containing the authorization info. The format is that
     * of the http Authorization header.
+    *
     * @return a String containing all info.
     */
    public String toString()
@@ -1025,6 +1069,7 @@
     * Produces a hash code based on host, scheme and realm. Port is not included
     * for simplicity (and because it probably won't make much difference). Used
     * in the AuthorizationInfo.AuthList hash table.
+    *
     * @return the hash code
     */
    public int hashCode()
@@ -1033,10 +1078,11 @@
    }
 
    /**
-    * Two AuthorizationInfos are considered equal if their host, port, scheme and
-    * realm match. Used in the AuthorizationInfo.AuthList hash table.
+    * Two AuthorizationInfos are considered equal if their host, port, scheme
+    * and realm match. Used in the AuthorizationInfo.AuthList hash table.
+    *
     * @param obj another AuthorizationInfo against which this one is to be
-    *          compared.
+    *        compared.
     * @return true if they match in the above mentioned fields; false otherwise.
     */
    public boolean equals(Object obj)
@@ -1045,7 +1091,7 @@
       {
          AuthorizationInfo auth = (AuthorizationInfo)obj;
          if (host.equals(auth.host) && (port == auth.port) && scheme.equalsIgnoreCase(auth.scheme)
-            && realm.equals(auth.realm))
+            && ((realm == null && auth.realm == null) || (realm != null && realm.equals(auth.realm))))
             return true;
       }
       return false;

Modified: ws/branches/2.1.x/exo.ws.commons/src/main/java/org/exoplatform/common/http/client/HTTPResponse.java
===================================================================
--- ws/branches/2.1.x/exo.ws.commons/src/main/java/org/exoplatform/common/http/client/HTTPResponse.java	2010-06-29 10:35:54 UTC (rev 2711)
+++ ws/branches/2.1.x/exo.ws.commons/src/main/java/org/exoplatform/common/http/client/HTTPResponse.java	2010-06-29 10:48:18 UTC (rev 2712)
@@ -128,14 +128,11 @@
       this.timeout = timeout;
       try
       {
-         int qp = orig.getRequestURI().indexOf('?');
-         this.OriginalURI =
-            new URI(orig.getConnection().getProtocol(), null, orig.getConnection().getHost(), orig.getConnection()
-               .getPort(), qp < 0 ? orig.getRequestURI() : orig.getRequestURI().substring(0, qp), qp < 0 ? null : orig
-               .getRequestURI().substring(qp + 1), null);
+         this.OriginalURI = new URI(orig.getRequestURI());
       }
       catch (ParseException pe)
       {
+         log.error("Error while create OriginalURI from request URI sring representation: " + pe.getMessage());
       }
       this.method = orig.getMethod();
    }

Modified: ws/branches/2.1.x/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/proxy/ProxyService.java
===================================================================
--- ws/branches/2.1.x/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/proxy/ProxyService.java	2010-06-29 10:35:54 UTC (rev 2711)
+++ ws/branches/2.1.x/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/proxy/ProxyService.java	2010-06-29 10:48:18 UTC (rev 2712)
@@ -18,11 +18,27 @@
  */
 package org.exoplatform.services.rest.ext.proxy;
 
+import org.exoplatform.common.http.client.HTTPConnection;
+import org.exoplatform.common.http.client.HTTPResponse;
+import org.exoplatform.common.http.client.HttpOutputStream;
+import org.exoplatform.common.http.client.ModuleException;
+import org.exoplatform.common.http.client.NVPair;
+import org.exoplatform.common.http.client.ProtocolNotSuppException;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.exoplatform.services.rest.resource.ResourceContainer;
+
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Enumeration;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
 
-import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
@@ -31,15 +47,12 @@
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
 import javax.ws.rs.core.Response.ResponseBuilder;
 
-import org.exoplatform.common.http.client.HTTPResponse;
-import org.exoplatform.common.http.client.ModuleException;
-import org.exoplatform.common.http.client.ParseException;
-import org.exoplatform.common.http.client.ProtocolNotSuppException;
-import org.exoplatform.services.rest.resource.ResourceContainer;
-
 /**
  * @author <a href="mailto:max.shaposhnik at exoplatform.com">Max Shaposhnik</a>
  * @version $Id$
@@ -47,25 +60,42 @@
 @Path("proxy")
 public class ProxyService implements ResourceContainer
 {
-   /**
-    * Handles GET proxy request.
-    * 
-    * @param httpRequestHttpServletRequest
-    * @param url the url to request
-    * @return  response Response
-    */
-   @GET
-   public Response doProxyGet(@Context HttpServletRequest httpRequest, @QueryParam("url") String url)
+   protected static final int DEFAULT_CONNECT_TIMEOUT_MS = 5000;
+
+   private static final Log LOG = ExoLogger.getLogger(ProxyService.class);
+
+   @DELETE
+   public Response doProxyDelete(@Context HttpHeaders headers, @Context UriInfo uriInfo,
+      @QueryParam("url") String urlParam)
    {
-      BaseConnector conn = new BaseConnector();
-      if (url == null)
+      if (urlParam == null)
       {
-         Throwable e = new Throwable("Necessary URL parameter not found in proxy request");
+         IllegalArgumentException e = new IllegalArgumentException("'url' parameter not found in proxy request");
          throw new WebApplicationException(e, createErrorResponse(e, 404));
       }
       try
       {
-         HTTPResponse resp = conn.fetchGet(httpRequest, url);
+         URL url = new URL(urlParam);
+         HTTPConnection conn = new HTTPConnection(url);
+         conn.setTimeout(DEFAULT_CONNECT_TIMEOUT_MS);
+         NVPair[] headerPairs =
+            toNVPair(headers.getRequestHeaders(), Collections.singleton(HttpHeaders.HOST.toLowerCase()));
+         conn.setAllowUserInteraction(false);
+         NVPair credentials = getCredentials(url);
+         if (credentials != null)
+         {
+            conn.addBasicAuthorization(null, credentials.getName(), credentials.getValue());
+         }
+         HTTPResponse resp = conn.Delete(url.getFile(), headerPairs);
+         if (resp.getStatusCode() >= 300)
+         {
+            LOG.warn("DELETE Received : " + resp.getReasonLine());
+            byte[] data = resp.getData();
+            if (data != null)
+            {
+               LOG.warn("DELETE Received : " + new String(data));
+            }
+         }
          return createResponse(resp);
       }
       catch (MalformedURLException mue)
@@ -84,32 +114,39 @@
       {
          throw new WebApplicationException(me, createErrorResponse(me, 500));
       }
-      catch (ParseException pe)
-      {
-         throw new WebApplicationException(pe, createErrorResponse(pe, 400));
-      }
-
    }
 
-   /**
-    * Handles POST proxy request.
-    * 
-    * @param httpRequestHttpServletRequest
-    * @param url the url to request
-    * @return  response Response
-    */
-   @POST
-   public Response doProxyPost(@Context HttpServletRequest httpRequest, @QueryParam("url") String url)
+   @GET
+   public Response doProxyGet(@Context HttpHeaders headers, @Context UriInfo uriInfo, @QueryParam("url") String urlParam)
    {
-      BaseConnector conn = new BaseConnector();
-      if (url == null)
+      if (urlParam == null)
       {
-         Throwable e = new Throwable("Necessary URL parameter not found in proxy request");
+         IllegalArgumentException e = new IllegalArgumentException("'url' parameter not found in proxy request");
          throw new WebApplicationException(e, createErrorResponse(e, 404));
       }
       try
       {
-         HTTPResponse resp = conn.fetchPost(httpRequest, url);
+         URL url = new URL(urlParam);
+         HTTPConnection conn = new HTTPConnection(url);
+         conn.setTimeout(DEFAULT_CONNECT_TIMEOUT_MS);
+         NVPair[] headerPairs =
+            toNVPair(headers.getRequestHeaders(), Collections.singleton(HttpHeaders.HOST.toLowerCase()));
+         conn.setAllowUserInteraction(false);
+         NVPair credentials = getCredentials(url);
+         if (credentials != null)
+         {
+            conn.addBasicAuthorization(null, credentials.getName(), credentials.getValue());
+         }
+         HTTPResponse resp = conn.Get(url.getFile(), (NVPair[])null, headerPairs);
+         if (resp.getStatusCode() >= 300)
+         {
+            LOG.warn("GET Received: " + resp.getReasonLine());
+            byte[] data = resp.getData();
+            if (data != null)
+            {
+               LOG.warn("GET Received: " + new String(data));
+            }
+         }
          return createResponse(resp);
       }
       catch (MalformedURLException mue)
@@ -128,31 +165,58 @@
       {
          throw new WebApplicationException(me, createErrorResponse(me, 500));
       }
-      catch (ParseException pe)
-      {
-         throw new WebApplicationException(pe, createErrorResponse(pe, 400));
-      }
    }
 
-   /**
-    * Handles PUT proxy request.
-    * 
-    * @param httpRequestHttpServletRequest
-    * @param url the url to request
-    * @return  response Response
-    */
-   @PUT
-   public Response doProxyPut(@Context HttpServletRequest httpRequest, @QueryParam("url") String url)
+   @POST
+   public Response doProxyPost(@Context HttpHeaders headers, @Context UriInfo uriInfo,
+      @QueryParam("url") String urlParam, InputStream entity)
    {
-      BaseConnector conn = new BaseConnector();
-      if (url == null)
+      if (urlParam == null)
       {
-         Throwable e = new Throwable("Necessary URL parameter not found in proxy request");
+         IllegalArgumentException e = new IllegalArgumentException("'url' parameter not found in proxy request");
          throw new WebApplicationException(e, createErrorResponse(e, 404));
       }
+
       try
       {
-         HTTPResponse resp = conn.doPut(httpRequest, url);
+         URL url = new URL(urlParam);
+         HTTPConnection conn = new HTTPConnection(url);
+         conn.setTimeout(DEFAULT_CONNECT_TIMEOUT_MS);
+         NVPair[] headerPairs =
+            toNVPair(headers.getRequestHeaders(), Collections.singleton(HttpHeaders.HOST.toLowerCase()));
+         conn.setAllowUserInteraction(false);
+         NVPair credentials = getCredentials(url);
+         if (credentials != null)
+         {
+            conn.addBasicAuthorization(null, credentials.getName(), credentials.getValue());
+         }
+         HTTPResponse resp = null;
+         if (entity != null)
+         {
+            HttpOutputStream stream = new HttpOutputStream();
+            resp = conn.Post(url.getFile(), stream, headerPairs);
+            byte[] buf = new byte[1024];
+            int r = -1;
+            while ((r = entity.read()) != -1)
+            {
+               stream.write(buf, 0, r);
+            }
+            stream.close();
+         }
+         else
+         {
+            resp = conn.Post(url.getFile(), (NVPair[])null, headerPairs);
+         }
+
+         if (resp.getStatusCode() >= 300)
+         {
+            LOG.warn("POST Received: " + resp.getReasonLine());
+            byte[] data = resp.getData();
+            if (data != null)
+            {
+               LOG.warn("POST Received: " + new String(data));
+            }
+         }
          return createResponse(resp);
       }
       catch (MalformedURLException mue)
@@ -171,32 +235,58 @@
       {
          throw new WebApplicationException(me, createErrorResponse(me, 500));
       }
-      catch (ParseException pe)
-      {
-         throw new WebApplicationException(pe, createErrorResponse(pe, 400));
-      }
-
    }
 
-   /**
-    * Handles DELETE proxy request.
-    * 
-    * @param httpRequestHttpServletRequest
-    * @param url the url to request
-    * @return  response Response
-    */
-   @DELETE
-   public Response doProxyDelete(@Context HttpServletRequest httpRequest, @QueryParam("url") String url)
+   @PUT
+   public Response doProxyPut(@Context HttpHeaders headers, @Context UriInfo uriInfo,
+      @QueryParam("url") String urlParam, InputStream entity)
    {
-      BaseConnector conn = new BaseConnector();
-      if (url == null)
+      if (urlParam == null)
       {
-         Throwable e = new Throwable("Necessary URL parameter not found in proxy request");
+         IllegalArgumentException e = new IllegalArgumentException("'url' parameter not found in proxy request");
          throw new WebApplicationException(e, createErrorResponse(e, 404));
       }
+
       try
       {
-         HTTPResponse resp = conn.doDelete(httpRequest, url);
+         URL url = new URL(urlParam);
+         HTTPConnection conn = new HTTPConnection(url);
+         conn.setTimeout(DEFAULT_CONNECT_TIMEOUT_MS);
+         NVPair[] headerPairs =
+            toNVPair(headers.getRequestHeaders(), Collections.singleton(HttpHeaders.HOST.toLowerCase()));
+         conn.setAllowUserInteraction(false);
+         NVPair credentials = getCredentials(url);
+         if (credentials != null)
+         {
+            conn.addBasicAuthorization(null, credentials.getName(), credentials.getValue());
+         }
+         HTTPResponse resp = null;
+         if (entity != null)
+         {
+            HttpOutputStream stream = new HttpOutputStream();
+            resp = conn.Put(url.getFile(), stream, headerPairs);
+            byte[] buf = new byte[1024];
+            int r = -1;
+            while ((r = entity.read()) != -1)
+            {
+               stream.write(buf, 0, r);
+            }
+            stream.close();
+         }
+         else
+         {
+            resp = conn.Put(url.getFile(), new byte[0], headerPairs);
+         }
+
+         if (resp.getStatusCode() >= 300)
+         {
+            LOG.warn("PUT Received : " + resp.getReasonLine());
+            byte[] data = resp.getData();
+            if (data != null)
+            {
+               LOG.warn("PUT Received : " + new String(data));
+            }
+         }
          return createResponse(resp);
       }
       catch (MalformedURLException mue)
@@ -215,16 +305,23 @@
       {
          throw new WebApplicationException(me, createErrorResponse(me, 500));
       }
-      catch (ParseException pe)
-      {
-         throw new WebApplicationException(pe, createErrorResponse(pe, 400));
-      }
+   }
 
+   /**
+    * Creates the error response.
+    *
+    * @param t Throwable
+    * @param status integer response status
+    * @return response Response
+    */
+   private Response createErrorResponse(Throwable t, int status)
+   {
+      return Response.status(status).entity(t.getMessage()).type("text/plain").build();
    }
 
    /**
     * Creates the response from HTTP response.
-    * 
+    *
     * @param httpResponse the http response
     * @return response Response
     */
@@ -236,7 +333,7 @@
          responseBuilder = Response.status(httpResponse.getStatusCode());
          for (Enumeration<String> en = httpResponse.listHeaders(); en.hasMoreElements();)
          {
-            String headerName = (String)en.nextElement();
+            String headerName = en.nextElement();
             responseBuilder.header(headerName, httpResponse.getHeader(headerName));
          }
          return responseBuilder.entity(httpResponse.getInputStream()).build();
@@ -251,15 +348,42 @@
       }
    }
 
-   /**
-    * Creates the error response.
-    * 
-    * @param t Throwable
-    * @param status integer response status
-    * @return response Response
-    */
-   private Response createErrorResponse(Throwable t, int status)
+   private NVPair getCredentials(URL url)
    {
-      return Response.status(status).entity(t.getMessage()).type("text/plain").build();
+      String userInfo = url.getUserInfo();
+      NVPair credentials = null;
+      if (userInfo != null)
+      {
+         int col = userInfo.indexOf(':');
+         if (col == -1)
+         {
+            credentials = new NVPair(userInfo, "");
+         }
+         else if (col == userInfo.length() - 1)
+         {
+            credentials = new NVPair(userInfo.substring(0, userInfo.length() - 1), "");
+         }
+         else
+         {
+            credentials = new NVPair(userInfo.substring(0, col), userInfo.substring(col + 1));
+         }
+      }
+      return credentials;
    }
+
+   private NVPair[] toNVPair(MultivaluedMap<String, String> map, Set<String> skip)
+   {
+      List<NVPair> hds = new ArrayList<NVPair>();
+      for (Entry<String, List<String>> e : map.entrySet())
+      {
+         if (!skip.contains(e.getKey()))
+         {
+            for (String v : e.getValue())
+            {
+               hds.add(new NVPair(e.getKey(), v));
+            }
+         }
+      }
+      return hds.toArray(new NVPair[hds.size()]);
+   }
 }



More information about the exo-jcr-commits mailing list