Author: psharples
Date: Mon Oct 31 14:12:57 2011
New Revision: 1195465

URL: http://svn.apache.org/viewvc?rev=1195465&view=rev
Log:
Updates for WOOKIE-283 - Proxy classes ported from trunk

Modified:
    incubator/wookie/branches/0.9.1/RELEASE_NOTES
    incubator/wookie/branches/0.9.1/src/org/apache/wookie/proxy/ProxyClient.java
    
incubator/wookie/branches/0.9.1/src/org/apache/wookie/proxy/ProxyServlet.java

Modified: incubator/wookie/branches/0.9.1/RELEASE_NOTES
URL: 
http://svn.apache.org/viewvc/incubator/wookie/branches/0.9.1/RELEASE_NOTES?rev=1195465&r1=1195464&r2=1195465&view=diff
==============================================================================
--- incubator/wookie/branches/0.9.1/RELEASE_NOTES (original)
+++ incubator/wookie/branches/0.9.1/RELEASE_NOTES Mon Oct 31 14:12:57 2011
@@ -71,6 +71,7 @@ Improvements
     * WOOKIE-250 - Improve license files
        * WOOKIE-255 - Change file names to not include version numbers in 
features    
     * WOOKIE-257 - Remove JUnit dependency for binary releases
+       * WOOKIE-283 - Logging into admin interface inteferes with API calls
     
 New Features
 ============

Modified: 
incubator/wookie/branches/0.9.1/src/org/apache/wookie/proxy/ProxyClient.java
URL: 
http://svn.apache.org/viewvc/incubator/wookie/branches/0.9.1/src/org/apache/wookie/proxy/ProxyClient.java?rev=1195465&r1=1195464&r2=1195465&view=diff
==============================================================================
--- 
incubator/wookie/branches/0.9.1/src/org/apache/wookie/proxy/ProxyClient.java 
(original)
+++ 
incubator/wookie/branches/0.9.1/src/org/apache/wookie/proxy/ProxyClient.java 
Mon Oct 31 14:12:57 2011
@@ -14,14 +14,11 @@
 
 package org.apache.wookie.proxy;
 
-import java.io.BufferedReader;
 import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
 import java.util.ArrayList;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 
 import javax.servlet.http.HttpServletRequest;
@@ -30,15 +27,14 @@ import org.apache.commons.configuration.
 import org.apache.commons.httpclient.Header;
 import org.apache.commons.httpclient.HttpClient;
 import org.apache.commons.httpclient.HttpMethod;
-import org.apache.commons.httpclient.HttpStatus;
 import org.apache.commons.httpclient.NameValuePair;
 import org.apache.commons.httpclient.UsernamePasswordCredentials;
 import org.apache.commons.httpclient.auth.AuthPolicy;
 import org.apache.commons.httpclient.auth.AuthScope;
-import org.apache.commons.httpclient.auth.AuthenticationException;
 import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
 import org.apache.commons.httpclient.methods.PostMethod;
-import org.apache.commons.httpclient.methods.StringRequestEntity;
+import org.apache.commons.io.IOUtils;
 import org.apache.log4j.Logger;
 
 /**
@@ -48,24 +44,29 @@ public class ProxyClient {
 
        static Logger fLogger = Logger.getLogger(ProxyClient.class.getName());
 
-       private String fContentType = "text/plain";     
        private String fProxyUsername = null;
        private String fProxyPassword = null;
-       private String fBase64Auth = null;
+       //private String fBase64Auth = null;
        private NameValuePair[] parameters = null;
        private boolean fUseProxyAuthentication = false;
 
        @SuppressWarnings("unchecked")
        public ProxyClient(HttpServletRequest request){
+         //
+         // If the request includes authn parameters, create proxy auth headers
+         //
                String proxyUserName = request.getParameter("username");
                String proxyPassword = request.getParameter("password");
-               String base64Auth = request.getHeader("Authorization");  
+               //String base64Auth = request.getHeader("Authorization");  
                if(proxyUserName != null && proxyPassword != null )     
                        this.setProxyAuthConfig(proxyUserName, proxyPassword);
-               if(base64Auth != null)
-                       this.setBase64AuthConfig(base64Auth);
+               //if(base64Auth != null)
+               //      this.setBase64AuthConfig(base64Auth);
+    
+               //
+               // Filter out instructions to the proxy server from the 
original request parameters
+               //
                filterParameters(request.getParameterMap());
-               fContentType = request.getContentType();
        }
 
        private void setProxyAuthConfig(String username, String password){
@@ -74,40 +75,52 @@ public class ProxyClient {
                fProxyPassword = password;
        }
 
-       private void setBase64AuthConfig(String base64Auth){
-               fUseProxyAuthentication = true;
-               fBase64Auth = base64Auth;
-       }
-
-       public String getCType(){
-               return fContentType;
-       }
-
-       public String get(String url, Configuration properties) throws 
Exception {
-               fLogger.debug("GET from " + url); //$NON-NLS-1$
-               GetMethod method = new GetMethod(url);
-               method.setDoAuthentication(true);
-               return executeMethod(method, properties);
-       }
-
-       public String post(String uri, String xmlData, Configuration 
properties) throws Exception {
-               fLogger.debug("POST to " + uri); //$NON-NLS-1$
-               PostMethod method = new PostMethod(uri);
-               method.setDoAuthentication(true);
-               
-               if(this.parameters.length > 0) {
-                       method.addParameters(this.parameters);
-               } else {
-                       method.setRequestEntity(new 
StringRequestEntity(xmlData, "text/xml", "UTF8"));//$NON-NLS-1$  //$NON-NLS-2$
-               }
-               
-               return executeMethod(method, properties);
+       //private void setBase64AuthConfig(String base64Auth){
+       //      fUseProxyAuthentication = true;
+       //      fBase64Auth = base64Auth;
+       //}
+       
+       /**
+        * Process a proxied GET request
+        * @param url the URL to GET
+        * @param request the original request object
+        * @param properties the servlet configuration
+        * @return a ResponseObject from the remote site
+        * @throws Exception
+        */
+       public ResponseObject get(String url, HttpServletRequest request, 
Configuration properties) throws Exception {
+    fLogger.debug("GET from " + url); //$NON-NLS-1$
+    GetMethod method = new GetMethod(url);
+    method.setDoAuthentication(true);
+    return executeMethod(method, request, properties);   
        }
+       
+       /**
+        * Process a proxied POST request
+        * @param url the URL to POST
+        * @param xmlData the body of the request
+        * @param request the original request object
+        * @param properties the servlet configuration
+        * @return a ResponseObject from the remote site
+        * @throws Exception
+        */
+        public ResponseObject post(String url , HttpServletRequest request, 
Configuration properties) throws Exception {
+           fLogger.debug("POST to " + url); //$NON-NLS-1$
+           PostMethod method = new PostMethod(url);
+           method.setDoAuthentication(true);
+           
+           if(this.parameters.length > 0) {
+             method.addParameters(this.parameters);
+           } else {
+             method.setRequestEntity(new 
InputStreamRequestEntity(request.getInputStream()));
+           }
+           
+           return executeMethod(method, request, properties); 
+         }
 
        /**
         * Processes the parameters passed through to the request,
         * removing the parameters used by the proxy itself
-        * @return
         */
        private void filterParameters(Map<Object,Object> umap){
                Map<Object, Object> map = new HashMap<Object, Object>(umap);
@@ -124,78 +137,102 @@ public class ProxyClient {
                }
                parameters = params.toArray(new NameValuePair[params.size()]);
        }
+       
+       /**
+        * Execute the request and return the components of the response
+        * @param method the method to use, e.g. POST or GET
+        * @param request the original request
+        * @param properties the configuration of the servlet
+        * @return a ResponseObject containing both the response body and all 
headers returned
+        * @throws Exception
+        */
+       private ResponseObject executeMethod(HttpMethod method, 
HttpServletRequest request, Configuration properties) throws Exception{
+         ResponseObject responseObject = new ResponseObject();
 
-       private String executeMethod(HttpMethod method, Configuration 
properties) throws Exception, AuthenticationException {
-               // Execute the method.
-               try {           
-                       HttpClient client = new HttpClient();
-                       // set the clients proxy values if needed
-                       ConnectionsPrefsManager.setProxySettings(client, 
properties);
-
-                       if(fUseProxyAuthentication){
-                               if (fBase64Auth != null) {
-                                       
method.setRequestHeader("Authorization", fBase64Auth);
-                               }
-                               else {
-                                       List<String> authPrefs =  new 
ArrayList<String>(2);
-                                       authPrefs.add(AuthPolicy.DIGEST );
-                                       authPrefs.add(AuthPolicy.BASIC);
-                                       client.getParams().setParameter 
(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
-                                       // send the basic authentication 
response even before the server gives an unauthorized response
-                                       
client.getParams().setAuthenticationPreemptive(true);
-                                       // Pass our credentials to HttpClient
-                                       client.getState().setCredentials(
-                                                       new 
AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM),
-                                                       new 
UsernamePasswordCredentials(fProxyUsername, fProxyPassword));
-                               }
-                       }
-
-                       // Add user language to http request in order to notify 
server of user's language
-                       Locale locale = Locale.getDefault();
-
-                       method.setRequestHeader("Accept-Language", 
locale.getLanguage()); //$NON-NLS-1$ 
-                       method.setRequestHeader("Content-Type", fContentType);
-                       int statusCode = client.executeMethod(method);
-
-                       if (statusCode == HttpStatus.SC_OK || statusCode == 
HttpStatus.SC_CREATED) {
-                               Header hType = 
method.getResponseHeader("Content-Type");        
-                               if (hType != null) fContentType = 
hType.getValue();
-                               // for now we are only expecting Strings        
                                
-                               //return method.getResponseBodyAsString();
-                               return readFully(new 
InputStreamReader(method.getResponseBodyAsStream(), "UTF-8"));
-                       }
-                       else if (statusCode == 
HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED || statusCode == 
HttpStatus.SC_UNAUTHORIZED)
-                               throw new 
AuthenticationException("Authentication failed:"+ method.getStatusLine() + ' ' 
+ method.getURI() + ' ' + method.getStatusText());                              
                                                                                
                                       
-                       else {
-                               throw new Exception("Method failed: " + 
method.getStatusLine() + ' ' + method.getURI() + ' ' + method.getStatusText()); 
//$NON-NLS-1$
-                       }
-               } 
-               catch (IOException e) {
-                       throw e;
-               } 
-               finally {
-                       // Release the connection.
-                       method.releaseConnection();
-               }
+         try {   
+           HttpClient client = new HttpClient();
+           
+           //
+           // set the clients proxy values if needed
+           //
+           ConnectionsPrefsManager.setProxySettings(client, properties);
+           
+           //
+           // Add in original request headers
+           //
+           @SuppressWarnings("unchecked")
+      Enumeration<String> headers = request.getHeaderNames();
+           while(headers.hasMoreElements()){
+             String header = (String) headers.nextElement();
+             
+             //
+             // We can't use content-length headers in case we altered the 
original body when filtering out
+             // the proxy parameters, so exclude them when adding the headers 
to the request
+             //
+             //
+          // We don't want to pass any authz headers along either (see 
WOOKIE-283)
+          //
+             if(!(header.equalsIgnoreCase("Content-Length") || 
header.equalsIgnoreCase("authorization"))){
+                 method.addRequestHeader(header, request.getHeader(header));
+             }
+            
+           }
+
+           //
+           // Include authentication if required
+           //
+           if(fUseProxyAuthentication){
+             //if (fBase64Auth != null) {
+             // method.setRequestHeader("Authorization", fBase64Auth);
+             //}
+             //else {
+               List<String> authPrefs =  new ArrayList<String>(2);
+               authPrefs.add(AuthPolicy.DIGEST );
+               authPrefs.add(AuthPolicy.BASIC);
+               client.getParams().setParameter 
(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
+               
+               //
+               // send the basic authentication response even before the 
server gives an unauthorized response
+               //
+               client.getParams().setAuthenticationPreemptive(true);
+               
+               //
+               // Pass our credentials to HttpClient
+               //
+               client.getState().setCredentials(
+                   new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, 
AuthScope.ANY_REALM),
+                   new UsernamePasswordCredentials(fProxyUsername, 
fProxyPassword));
+             //}
+           }
+
+           //
+           // Excecute request and return response
+           //
+           int statusCode = client.executeMethod(method);
+           responseObject.status = statusCode;
+           responseObject.body = 
IOUtils.toByteArray(method.getResponseBodyAsStream());
+           responseObject.headers = method.getResponseHeaders();
+           return responseObject;
+         } 
+         catch (IOException e) {
+           throw e;
+         } 
+         finally {
+           
+           //
+           // Release the connection.
+           //
+           method.releaseConnection();
+         }
        }
-
+       
        /**
-        * This is supposed to be the correct way to read the response instead 
of using getResponseBody() - which gives a runtime warning;
-        * 
-        * See - 
http://mail-archives.apache.org/mod_mbox/jakarta-httpclient-user/200411.mbox/%[email protected]%3e
-        * @param input
-        * @return
-        * @throws IOException
+        * Inner class used to pass response parts back to the servlet
         */
-       private String readFully(Reader input) throws IOException {
-               BufferedReader bufferedReader = input instanceof BufferedReader 
? (BufferedReader) input
-                               : new BufferedReader(input);
-               StringBuffer result = new StringBuffer();
-               char[] buffer = new char[4 * 1024];
-               int charsRead;
-               while ((charsRead = bufferedReader.read(buffer)) != -1) {
-                       result.append(buffer, 0, charsRead);
-               }
-               return result.toString();
+       class ResponseObject{
+         public int status;
+         public byte[] body;
+         public Header[] headers;
+         
        }
 }

Modified: 
incubator/wookie/branches/0.9.1/src/org/apache/wookie/proxy/ProxyServlet.java
URL: 
http://svn.apache.org/viewvc/incubator/wookie/branches/0.9.1/src/org/apache/wookie/proxy/ProxyServlet.java?rev=1195465&r1=1195464&r2=1195465&view=diff
==============================================================================
--- 
incubator/wookie/branches/0.9.1/src/org/apache/wookie/proxy/ProxyServlet.java 
(original)
+++ 
incubator/wookie/branches/0.9.1/src/org/apache/wookie/proxy/ProxyServlet.java 
Mon Oct 31 14:12:57 2011
@@ -15,7 +15,6 @@
 package org.apache.wookie.proxy;
 
 import java.io.IOException;
-import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
 import java.net.URI;
@@ -29,6 +28,7 @@ import javax.servlet.http.HttpServletReq
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.commons.configuration.Configuration;
+import org.apache.commons.httpclient.Header;
 import org.apache.commons.httpclient.auth.AuthenticationException;
 import org.apache.log4j.Logger;
 import org.apache.wookie.beans.IAccessRequest;
@@ -68,13 +68,17 @@ public class ProxyServlet extends HttpSe
                try {
                        Configuration properties = (Configuration) 
request.getSession().getServletContext().getAttribute("properties");
 
+                       //
                        // Check that the request is coming from the same 
domain (i.e. from a widget served by this server)
+                       //
                        if (properties.getBoolean("widget.proxy.checkdomain") 
&& !isSameDomain(request)){
                                
response.sendError(HttpServletResponse.SC_FORBIDDEN,"<error>"+UNAUTHORISED_MESSAGE+"</error>");
 
                                return;                         
                        }
 
+                       //
                        // Check that the request is coming from a valid widget
+                       //
                        IPersistenceManager persistenceManager = 
PersistenceManagerFactory.getPersistenceManager();
                        IWidgetInstance instance = 
persistenceManager.findWidgetInstanceByIdKey(request.getParameter("instanceid_key"));
        
                        if(instance == null && !isDefaultGadget(request)){
@@ -82,7 +86,9 @@ public class ProxyServlet extends HttpSe
                                return;
                        }
 
+                       //
                        // Create the proxy bean for the request
+                       //
                        ProxyURLBean bean;
                        try {
                                bean = new ProxyURLBean(request);
@@ -91,24 +97,50 @@ public class ProxyServlet extends HttpSe
                                return;
                        }               
 
+                       //
                        // should we filter urls?
+                       //
                        if (properties.getBoolean("widget.proxy.usewhitelist") 
&& !isAllowed(bean.getNewUrl().toURI(), instance)){
                                
response.sendError(HttpServletResponse.SC_FORBIDDEN,"<error>URL 
Blocked</error>");
                                fLogger.warn("URL " + 
bean.getNewUrl().toExternalForm() + " Blocked");
                                return;
                        }       
 
+                       //
+                       // Create a ProxyClient instance for the request
+                       //
                        ProxyClient proxyclient = new ProxyClient(request);
-                       PrintWriter out = response.getWriter(); 
+                       ProxyClient.ResponseObject responseObject = null;
+
                        //TODO - find all the links etc & make them absolute - 
to make request come thru this servlet
-                       String output = "";
+
+                       //
+                       // Execute the request and populate the ResponseObject
+                       //
                        if(httpMethod.equals("get")){
-                               output = 
proxyclient.get(bean.getNewUrl().toExternalForm(), properties);
-                       }else{  
-                               output = 
proxyclient.post(bean.getNewUrl().toExternalForm(),getXmlData(request), 
properties);
+                         responseObject = 
proxyclient.get(bean.getNewUrl().toExternalForm(), request, properties);
+                       } else {        
+                         responseObject = 
proxyclient.post(bean.getNewUrl().toExternalForm(), request, properties);
+                       }
+                       
+                       //
+                       // Set Status
+                       //
+           response.setStatus(responseObject.status);
+            
+                       //
+                       // Set Headers
+                       //
+                       for (Header header:responseObject.headers){
+                         response.setHeader(header.getName(), 
header.getValue());
+                       }
+                       
+                       //
+                       // Set Body
+                       //
+                       if(responseObject.body != null && 
responseObject.body.length > 0){
+                         response.getOutputStream().write(responseObject.body);
                        }
-                       response.setContentType(proxyclient.getCType());
-                       out.print(output);
                }
                catch (Exception ex) {
                        try {
@@ -127,22 +159,6 @@ public class ProxyServlet extends HttpSe
        }
 
        /**
-        * Gets the content of the request
-        * @param request
-        * @return
-        * @throws IOException
-        */
-       private String getXmlData(HttpServletRequest request) throws 
IOException{
-               // Note that we cannot use a Reader for this as we already
-               // call getParameter() which works on an InputStream - and you
-               // can only use an InputStream OR a Reader, not both.
-               byte[] b = new byte[request.getContentLength()];
-               request.getInputStream().read(b, 0, request.getContentLength());
-               String xml = new String(b);
-               return xml;
-       }
-
-       /**
         * Checks that the request is from the same domain as this service
         * @param request
         * @param checkDomain


Reply via email to