View Javadoc

1   /**
2    * Copyright (C) 2005-2009 Alfresco Software Limited.
3    *
4    * This file is part of the Spring Surf Extension project.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *  http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.springframework.extensions.webscripts.connector;
20  
21  import java.io.InputStream;
22  import java.io.OutputStream;
23  import java.util.HashMap;
24  import java.util.Map;
25  
26  import javax.servlet.http.HttpServletRequest;
27  import javax.servlet.http.HttpServletResponse;
28  
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  import org.springframework.extensions.config.RemoteConfigElement.ConnectorDescriptor;
32  
33  /**
34   * Basic Connector implementation that can be used to perform simple HTTP and
35   * HTTP communication with a remote endpoint. This connector supports basic HTTP
36   * authentication via the RemoteClient.
37   * 
38   * @author muzquiano
39   * @author kevinr
40   */
41  public class HttpConnector extends AbstractConnector
42  {
43      private static Log logger = LogFactory.getLog(HttpConnector.class);
44      
45      
46      /**
47       * Instantiates a new http connector.
48       * 
49       * @param descriptor the descriptor
50       * @param endpoint the endpoint
51       */
52      public HttpConnector(ConnectorDescriptor descriptor, String endpoint)
53      {
54          super(descriptor, endpoint);
55          EndpointManager.registerEndpoint(endpoint);
56      }
57  
58  
59      public Response call(String uri, ConnectorContext context)
60      {
61          Response response;
62          if (EndpointManager.allowConnect(this.endpoint))
63          {
64              RemoteClient remoteClient = initRemoteClient(context);
65              
66              // call client and process response
67              response = remoteClient.call(uri);
68              processResponse(remoteClient, response);
69          }
70          else
71          {
72              ResponseStatus status = new ResponseStatus();
73              status.setCode(ResponseStatus.STATUS_INTERNAL_SERVER_ERROR);
74              response = new Response(status);
75          }
76          return response;
77      }
78  
79      public Response call(String uri, ConnectorContext context, InputStream in)
80      {
81          Response response;
82          if (EndpointManager.allowConnect(this.endpoint))
83          {
84              RemoteClient remoteClient = initRemoteClient(context);
85              
86              // call client and process response
87              response = remoteClient.call(uri, in);
88              processResponse(remoteClient, response);
89          }
90          else
91          {
92              ResponseStatus status = new ResponseStatus();
93              status.setCode(ResponseStatus.STATUS_INTERNAL_SERVER_ERROR);
94              response = new Response(status);
95          }
96          return response;
97      }
98  
99      public Response call(String uri, ConnectorContext context, InputStream in, OutputStream out)
100     {
101         Response response;
102         if (EndpointManager.allowConnect(this.endpoint))
103         {
104             RemoteClient remoteClient = initRemoteClient(context);
105             
106             // call client and process response
107             response = remoteClient.call(uri, in, out);
108             processResponse(remoteClient, response);
109         }
110         else
111         {
112             ResponseStatus status = new ResponseStatus();
113             status.setCode(ResponseStatus.STATUS_INTERNAL_SERVER_ERROR);
114             response = new Response(status);
115         }
116         
117         return response;
118     }
119     
120     public Response call(String uri, ConnectorContext context, HttpServletRequest req, HttpServletResponse res)
121     {
122         Response response;
123         if (EndpointManager.allowConnect(this.endpoint))
124         {
125             RemoteClient remoteClient = initRemoteClient(context);
126                     
127             // call client and process response
128             response = remoteClient.call(uri, req, res);
129             processResponse(remoteClient, response);
130         }
131         else
132         {
133             ResponseStatus status = new ResponseStatus();
134             status.setCode(ResponseStatus.STATUS_INTERNAL_SERVER_ERROR);
135             response = new Response(status);
136         }
137         
138         return response;
139     }
140     
141     /**
142      * Stamps headers onto the remote client
143      * 
144      * @param remoteClient
145      * @param context
146      */
147     private void applyRequestHeaders(RemoteClient remoteClient, ConnectorContext context)
148     {
149         // copy in cookies that have been stored back as part of the connector session
150         ConnectorSession connectorSession = getConnectorSession();
151         if (connectorSession != null)
152         {
153             Map<String, String> cookies = new HashMap<String, String>(8);
154             for (String cookieName : connectorSession.getCookieNames())
155             {
156                 cookies.put(cookieName, connectorSession.getCookie(cookieName));
157             }
158             remoteClient.setCookies(cookies);
159         }
160         
161         // get the headers
162         Map<String, String> headers = new HashMap<String, String>(8);
163         if (context != null)
164         {
165             headers.putAll(context.getHeaders());
166         }
167         
168         // Proxy the authenticated user name if we have password-less credentials (indicates SSO auth over a secure
169         // connection)
170         if (getCredentials() != null)
171         {
172             String user = (String) getCredentials().getProperty(Credentials.CREDENTIAL_USERNAME);
173             String pass = (String) getCredentials().getProperty(Credentials.CREDENTIAL_PASSWORD);
174             if (pass == null)
175             {
176                 headers.put("X-Alfresco-Remote-User", user);
177             }
178         }
179         
180         // stamp all headers onto the remote client
181         if (headers.size() != 0)
182         {
183             remoteClient.setRequestProperties(headers);
184         }
185     }
186     
187     /**
188      * Stamps Credentials values onto the remote client
189      * 
190      * @param remoteClient
191      */
192     protected void applyRequestAuthentication(RemoteClient remoteClient, ConnectorContext context)
193     {
194         // support for basic authentication (HTTP basic auth is performed by the RemoteClient)
195         if (getCredentials() != null)
196         {
197             String user = (String) getCredentials().getProperty(Credentials.CREDENTIAL_USERNAME);
198             String pass = (String) getCredentials().getProperty(Credentials.CREDENTIAL_PASSWORD);
199             if (pass != null)
200             {
201                 remoteClient.setUsernamePassword(user, pass);
202             }
203         }
204     }
205     
206     /**
207      * Retrieves headers from response and stores back onto Credentials
208      * 
209      * @param response
210      */
211     protected void processResponse(RemoteClient remoteClient, Response response)
212     {
213         ConnectorSession connectorSession = getConnectorSession();
214         if (EndpointManager.processResponseCode(this.endpoint, response.getStatus().getCode())
215                 && connectorSession != null)
216         {
217             Map<String, String> cookies = remoteClient.getCookies();
218             for (Map.Entry<String, String> cookie : cookies.entrySet())
219             {
220                 // store cookie back
221                 if (logger.isDebugEnabled())
222                     logger.debug("Connector found set-cookie: " + cookie.getKey() + " = " + cookie.getValue());
223 
224                 connectorSession.setCookie(cookie.getKey(), cookie.getValue());
225             }
226         }
227     }
228     
229     /**
230      * Init the RemoteClient object based on the Connector Context.
231      * Applies Request headers and authentication as required.
232      * 
233      * @return RemoteClient
234      */
235     protected RemoteClient initRemoteClient(ConnectorContext context)
236     {
237         // create a remote client
238         RemoteClient remoteClient = new RemoteClient(getEndpoint());
239         
240         // configure the client
241         if (context != null)
242         {
243             remoteClient.setRequestContentType(context.getContentType());
244             remoteClient.setRequestMethod(context.getMethod());
245         }
246         
247         // stamp headers onto the remote client
248         applyRequestHeaders(remoteClient, context);
249         
250         // stamp credentials onto the remote client
251         applyRequestAuthentication(remoteClient, context);
252         
253         return remoteClient;
254     }
255 }