FileDocCategorySizeDatePackage
Redirector.javaAPI DocGlassfish v2 API10353Tue Jun 19 06:12:04 BST 2007com.sun.enterprise.web.portunif.util

Redirector

public class Redirector extends Object
Utility class used to redirect an HTTP(s) request to another protocol and endpoint. The following scenarios are supported: (1) http://host:port1 to https://host:port1 (2) https://host:port1 to http://host:port1 (3) http://host:port2 to https://host:port1 (4) https://host:port2 to https://host:port1 (5) http://host:port2 to http://host:port1 (6) https://host:port2 to http://host:port1 This class internally start an NIO Selector listening on an 'external' port to a 'redirect' port. All requests to the external port, independently of the protocol are redirected to the 'redirect' port.
author
Jeanfrancois Arcand

Fields Summary
private static final String
NEWLINE
HTTP end line.
private static String
ipAddress
The IP address the server is running on.
private static final String
headers
Header String.
private static final ByteBuffer
SC_FOUND
HTTP SC_FOUND header.
Constructors Summary
public Redirector()

    
    
    // --------------------------------------------------------- Constructor --/
    
    
     
    
Methods Summary
private voidlog(java.lang.Throwable ex)
Log an exception.

        Logger logger = SSLSelectorThread.logger();
        if ( logger.isLoggable(Level.WARNING) ){
            logger.log(Level.WARNING,"Redirector",ex);
        }
    
private java.lang.StringparseHost(java.nio.ByteBuffer byteBuffer)
Return the host value, or null if not found.

param
byteBuffer the request bytes.

         boolean isFound = false;
                          
        int curPosition = byteBuffer.position();
        int curLimit = byteBuffer.limit();

        // Rule a - If nothing, return to the Selector.
        if (byteBuffer.position() == 0)
            return ipAddress;
       
        byteBuffer.position(0);
        byteBuffer.limit(curPosition);
        

        int state =0;
        int start =0;
        int end = 0;        
        
        try {                         
            byte c;            
            
            // Rule b - try to determine the host header
            while(byteBuffer.hasRemaining()) {
                c = (byte)Ascii.toLower(byteBuffer.get());
                switch(state) {
                    case 0: // Search for first 'h'
                        if (c == 0x68){
                            state = 1;      
                        } else {
                            state = 0;
                        }
                        break;
                    case 1: // Search for next 'o'
                        if (c == 0x6f){
                            state = 2;
                        } else {
                            state = 0;
                        }
                        break;
                    case 2: // Search for next 's'
                        if (c == 0x73){
                            state = 3;
                        } else {
                            state = 0;
                        }
                        break;
                    case 3: // Search for next 't'
                        if (c == 0x74){
                            state = 4;
                        } else {
                            state = 0;
                        }
                        break; 
                    case 4: // Search for next ':'
                        if (c == 0x3a){
                            state = 5;
                        } else {
                            state = 0;
                        }
                        break;     
                    case 5: // Get the Host                  
                        StringBuilder sb = new StringBuilder();
                        while (c != 0x0d && c != 0x0a) {
                            sb.append((char) c);
                            c = byteBuffer.get();
                        }
                        return sb.toString().trim();                        
                    default:
                        throw new IllegalArgumentException("Unexpected state");
                }      
            }
            return null;
        } catch (BufferUnderflowException bue) {
            return null;
        } finally {     
            if ( end > 0 ){
                byteBuffer.position(start);
                byteBuffer.limit(end);
            } else {
                byteBuffer.limit(curLimit);
                byteBuffer.position(curPosition);                               
            }
        }       
    
public final voidredirect(ProtocolInfo protocolInfo)
Redirect a un-secure request (http) to http or https.

param
protocolInfo the ProtocolInfo that contains the information about the current protocol state.

        String host = parseHost(protocolInfo.byteBuffer);
        if (host == null){
            host = ipAddress + ":" + 
                    protocolInfo.socketChannel.socket().getLocalPort();
        }
        redirect(protocolInfo,protocolInfo.isRequestedTransportSecure 
                    ? new String("Location: https://" + host)
                    : new String("Location: http://" + host));
    
private final voidredirect(ProtocolInfo protocolInfo, java.lang.String httpHeaders)
Redirect a secure request (http) to http or https.

param
protocolInfo the ProtocolInfo that contains the information about the current protocol state.
param
byteBuffer the bytes response.


        OutputWriter.flushChannel(protocolInfo.socketChannel,SC_FOUND.slice());
        OutputWriter.flushChannel(protocolInfo.socketChannel,
                ByteBuffer.wrap((httpHeaders 
                    + protocolInfo.requestURI + headers).getBytes()));
    
public final voidredirectSSL(ProtocolInfo protocolInfo)
Redirect a secure request (https) to http or https.

param
protocolInfo the ProtocolInfo that contains the information about the current protocol state.

        String host = parseHost(protocolInfo.byteBuffer);
        if (host == null){
            host = ipAddress + ":" + 
                    protocolInfo.socketChannel.socket().getLocalPort();
        }      
        redirectSSL(protocolInfo,
                protocolInfo.isRequestedTransportSecure ? 
                    new String("Location: https://" + host): 
                    new String("Location: http://" + host));
    
private final voidredirectSSL(ProtocolInfo protocolInfo, java.lang.String httpHeaders)
Redirect a secure request (https) to http or https.

param
protocolInfo the ProtocolInfo that contains the information about the current protocol state.
param
byteBuffer the bytes response.


        SSLOutputWriter.flushChannel(protocolInfo.socketChannel,
                SC_FOUND.slice(),
                protocolInfo.outputBB,
                protocolInfo.sslEngine);
        SSLOutputWriter.flushChannel(protocolInfo.socketChannel,
                ByteBuffer.wrap((httpHeaders + protocolInfo.requestURI + headers)
                    .getBytes()),
                protocolInfo.outputBB,
                protocolInfo.sslEngine);