blob: b46d2bcc4fa4f5b9a29c0abc44f2b8bdbf707db6 [file] [log] [blame]
// ========================================================================
// Copyright (c) 2008-2009 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.client;
import java.io.IOException;
import org.eclipse.jetty.http.HttpHeaders;
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.io.Buffer;
/**
* RedirectListener
*
* Detect and handle the redirect responses
*/
public class RedirectListener extends HttpEventListenerWrapper
{
private final HttpExchange _exchange;
private HttpDestination _destination;
private String _location;
private int _attempts;
private boolean _requestComplete;
private boolean _responseComplete;
private boolean _redirected;
public RedirectListener(HttpDestination destination, HttpExchange ex)
{
// Start of sending events through to the wrapped listener
// Next decision point is the onResponseStatus
super(ex.getEventListener(),true);
_destination = destination;
_exchange = ex;
}
@Override
public void onResponseStatus( Buffer version, int status, Buffer reason )
throws IOException
{
_redirected = ((status == HttpStatus.MOVED_PERMANENTLY_301 ||
status == HttpStatus.MOVED_TEMPORARILY_302) &&
_attempts < _destination.getHttpClient().maxRedirects());
if (_redirected)
{
setDelegatingRequests(false);
setDelegatingResponses(false);
}
super.onResponseStatus(version,status,reason);
}
@Override
public void onResponseHeader( Buffer name, Buffer value )
throws IOException
{
if (_redirected)
{
int header = HttpHeaders.CACHE.getOrdinal(name);
switch (header)
{
case HttpHeaders.LOCATION_ORDINAL:
_location = value.toString();
break;
}
}
super.onResponseHeader(name,value);
}
@Override
public void onRequestComplete() throws IOException
{
_requestComplete = true;
if (checkExchangeComplete())
{
super.onRequestComplete();
}
}
@Override
public void onResponseComplete() throws IOException
{
_responseComplete = true;
if (checkExchangeComplete())
{
super.onResponseComplete();
}
}
public boolean checkExchangeComplete()
throws IOException
{
if (_redirected && _requestComplete && _responseComplete)
{
if (_location != null)
{
if (_location.indexOf("://")>0)
_exchange.setURL(_location);
else
_exchange.setRequestURI(_location);
// destination may have changed
HttpDestination destination=_destination.getHttpClient().getDestination(_exchange.getAddress(),HttpSchemes.HTTPS.equals(String.valueOf(_exchange.getScheme())));
if (_destination==destination)
_destination.resend(_exchange);
else
{
// unwrap to find ultimate listener.
HttpEventListener listener=this;
while(listener instanceof HttpEventListenerWrapper)
listener=((HttpEventListenerWrapper)listener).getEventListener();
//reset the listener
_exchange.getEventListener().onRetry();
_exchange.reset();
_exchange.setEventListener(listener);
destination.send(_exchange);
}
return false;
}
else
{
setDelegationResult(false);
}
}
return true;
}
public void onRetry()
{
_redirected=false;
_attempts++;
setDelegatingRequests(true);
setDelegatingResponses(true);
_requestComplete=false;
_responseComplete=false;
super.onRetry();
}
}