/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.libraries.pensol;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.api.client.ClientRequest;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.filter.ClientFilter;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.WeakHashMap;
public class CookiesHandlerFilter extends ClientFilter {
private static final Log logger = LogFactory.getLog( CookiesHandlerFilter.class );
// Use WeakHashMap as cache. It's not synchronized, so use "class"
// synchronized get/setters.
private static WeakHashMap<String, List<Object>> cookiesByAuth = new WeakHashMap<String, List<Object>>();
// "class" synchronized get/setters:
private static synchronized List<Object> getCachedCookiesByAuthToken( String authToken ) {
return cookiesByAuth.get( authToken );
}
private static synchronized void setCookiesByAuthToken( String authToken, List<Object> cookiesList ) {
cookiesByAuth.put( authToken, cookiesList );
}
@Override
public ClientResponse handle( ClientRequest request ) throws ClientHandlerException {
List<Object> authorizationHeader = request.getHeaders().get( "Authorization" );
String authToken = (String) authorizationHeader.get( 0 );
// If we have cookies, inject them. When session is expired, basic auth
// header is not used instead of the expired cookies, so we just use
// them as a token.
List<Object> cookiesList = getCachedCookiesByAuthToken( authToken );
if ( cookiesList != null ) {
request.getHeaders().put( "Cookie", cookiesList );
request.getHeaders().remove( "Authorization" );
}
ClientResponse response = getNext().handle( request );
// If session has expired, remove cookies, put back basic auth header,
// try one more time and save new cookies.
if ( response.getStatus() == HttpStatus.SC_UNAUTHORIZED ) {
logger.warn( "Request to" + request.getURI() + "returned Unauthorized." );
if ( logger.isDebugEnabled() ) {
logger.debug( "http status=" + response.getStatus() + " response=" + response.getEntity( String.class ) );
}
request.getHeaders().remove( "Cookie" );
request.getHeaders().put( "Authorization", authorizationHeader );
logger.warn( "Trying one more time" );
response = getNext().handle( request );
if ( response.getStatus() == HttpStatus.SC_UNAUTHORIZED ) {
logger.error( "Request to" + request.getURI() + "returned Unauthorized 2nd time." );
logger.error( "http status=" + response.getStatus() + " response=" + response.getEntity( String.class ) );
}
}
// always use the new cookies.
if ( response.getCookies() != null && response.getCookies().isEmpty() == false ) {
cookiesList = new ArrayList<Object>();
cookiesList.addAll( response.getCookies() );
setCookiesByAuthToken( authToken, cookiesList );
}
return response;
}
}