Package org.xlightweb

Source Code of org.xlightweb.HttpProtocolHandlerClientSide

/*
*  Copyright (c) xlightweb.org, 2008 - 2009. All rights reserved.
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2.1 of the License, or (at your option) any later version.
*
*  This library 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.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* Please refer to the LGPL license at: http://www.gnu.org/copyleft/lesser.txt
* The latest copy of this software may be found on http://www.xlightweb.org/
*/
package org.xlightweb;


import java.io.IOException;
import java.nio.BufferUnderflowException;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.xlightweb.AbstractHttpConnection.IMessageHandler;
import org.xsocket.connection.INonBlockingConnection;


/**
* client side http protocol handler
*
* @author grro@xlightweb.org
*/
final class HttpProtocolHandlerClientSide extends AbstractHttpProtocolHandler {

 
  private static final Logger LOG = Logger.getLogger(HttpProtocolHandlerClientSide.class.getName());
 

   
  /**
   * {@inheritDoc}
   */
  protected void onData(AbstractHttpConnection httpConnection, INonBlockingConnection underlyingConnection, ComposedByteBuffer rawData) throws BadMessageException, IOException {
   
    try {
      switch (getState()) {
     
        case INIT:
          setHeaderParser(HttpResponseHeaderParser.newInstance());
          setState(RECEIVING_HEADER);
          onData(httpConnection, underlyingConnection, rawData);
          return;
     
        case RECEIVING_HEADER:
          if (LOG.isLoggable(Level.FINE)) {
            LOG.fine("[" + httpConnection.getId() + "] parsing header (available network data " + rawData.available() + ")");
          }
          parseHeader(httpConnection, underlyingConnection, rawData);
          break;
       
         
        default// RECEIVING_BODY
          if (LOG.isLoggable(Level.FINE)) {
            LOG.fine("[" + httpConnection.getId() + "] parsing body (available network data " + rawData.available() + ")");
          }
          parserBody(rawData);
      }
     
    } catch (BufferUnderflowException ignore) {   }
   
   
    if (LOG.isLoggable(Level.FINE)) {
      LOG.fine("[" + httpConnection.getId() + "] after parse (available network data " + rawData.available() + ")");
    }
  }
 
 
 
  private void parseHeader(AbstractHttpConnection httpConnection, INonBlockingConnection underlyingConnection, ComposedByteBuffer rawData) throws BadMessageException, IOException {
    HttpResponseHeader responseHeader = null;
   
    try {
      responseHeader = (HttpResponseHeader) getHeaderParser().parse(underlyingConnection, rawData);
     
    } catch (SimpleResponseMessageException sre) {
     
      httpConnection.setLastTimeHeaderReceivedMillis(System.currentTimeMillis());
      httpConnection.incCountMessageReceived();
     
      responseHeader = new HttpResponseHeader(200);
      responseHeader.setProtocolVersionSilence("0.9");
      responseHeader.setSimpleResponse(true);
     
      setBodyParser(new SimpleMessageBodyParser(httpConnection, responseHeader));
     
      HttpResponse response = new HttpResponse(responseHeader);
      response.setBodyDataSourceSilence(getBodyParser().getDataSource());
     
      setState(RECEIVING_BODY);
     
      parserBody(rawData);

      IMessageHandler messageHandler = httpConnection.getMessageHandler();
      if (messageHandler == null) {
        throw new IOException("no message handler set");
      }

      messageHandler.onMessage(response);
      return;
    }

   
    if (responseHeader != null) {

      httpConnection.setLastTimeHeaderReceivedMillis(System.currentTimeMillis());
      httpConnection.incCountMessageReceived();
       
      IMessageHandler messageHandler = httpConnection.getMessageHandler();
      if (messageHandler == null) {
        throw new IOException("no message handler set");
      }

      try {
       
        HttpResponse response = null;
       
        switch (getBodyType(httpConnection, responseHeader,  messageHandler.isBodylessMessageExpected())) {
         
          case BODY_TYPE_EMTPY:
            response = new HttpResponse(responseHeader);
            reset();
            break;

           
          case BODY_TYPE_BOUND:
            setBodyParser(new FullMessageBodyParser(httpConnection, responseHeader));
            response = new HttpResponse(responseHeader);
            response.setBodyDataSourceSilence(getBodyParser().getDataSource());
            setState(RECEIVING_BODY);
           
            response.getNonBlockingBody().setBodyDataReceiveTimeoutMillis(httpConnection.getBodyDataReceiveTimeoutMillis());
            parserBody(rawData);
            break;
           
          case BODY_TYPE_SIMPLE:
            setBodyParser(new SimpleMessageBodyParser(httpConnection, responseHeader));
            response = new HttpResponse(responseHeader);
            response.setBodyDataSourceSilence(getBodyParser().getDataSource());
            setState(RECEIVING_BODY);
           
            response.getNonBlockingBody().setBodyDataReceiveTimeoutMillis(httpConnection.getBodyDataReceiveTimeoutMillis());
            parserBody(rawData);
            break;
           
          case BODY_TYPE_MULTIPART_BYTERANGE:
            setBodyParser(new MultipartByteRangeMessageBodyParser(httpConnection, responseHeader));
            response = new HttpResponse(responseHeader);
            response.setBodyDataSourceSilence(getBodyParser().getDataSource());
            setState(RECEIVING_BODY);
           
            response.getNonBlockingBody().setBodyDataReceiveTimeoutMillis(httpConnection.getBodyDataReceiveTimeoutMillis());
            parserBody(rawData);
            break;
           
           
          default// BODY_TYPE_CHUNKED
            setBodyParser(new FullMessageChunkedBodyParser(httpConnection, responseHeader));
            response = new HttpResponse(responseHeader);
            response.setBodyDataSourceSilence(getBodyParser().getDataSource());
            setState(RECEIVING_BODY);

            response.getNonBlockingBody().setBodyDataReceiveTimeoutMillis(httpConnection.getBodyDataReceiveTimeoutMillis());
            parserBody(rawData);
           
            break;
        }
       
        messageHandler.onMessage(response);
        return;
     
      } catch (BadMessageException bme) {
        throw bme;
       
      } catch (IOException ioe) {
        messageHandler.onException(ioe);
        throw ioe;
      }
    }
  }
 
 
 
 
  private static int getBodyType(AbstractHttpConnection httpConnection, HttpResponseHeader responseHeader, boolean isBodylessMessageExcpected) throws BadMessageException {
   
    if (isBodylessMessageExcpected) {
      return BODY_TYPE_EMTPY;
    }
   
   
    int status = responseHeader.getStatus();
    if ((status == 304) ||      // not modified
      (status == 204) ||      // no content 
      (status == 100) ||      // continue
      (status == 101)) {      // Switching Protocols

      return BODY_TYPE_EMTPY;
    }
   
   
    // contains a non-zero Content-Length header  -> bound body
    if ((responseHeader.getContentLength() != -1)) {
      if (responseHeader.getContentLength() > 0) {
        return BODY_TYPE_BOUND;
      }
      return BODY_TYPE_EMTPY;
    }
 
   
    //  transfer encoding header is set with chunked -> chunked body
    String transferEncoding = responseHeader.getTransferEncoding();
    if ((transferEncoding != null) && (transferEncoding.equalsIgnoreCase("chunked"))) {
      return BODY_TYPE_CHUNKED;
    }
   
   
    // multipart/byteranges response?
    if ((responseHeader.getStatus() == 206) && (responseHeader.getContentType() != null) && (responseHeader.getContentType().toLowerCase().startsWith("multipart/byteranges"))) {
      return BODY_TYPE_MULTIPART_BYTERANGE;
    }
   
   
    // is connection header set with close?
    if ((responseHeader.getConnection() != null) && (responseHeader.getConnection().equalsIgnoreCase("close"))) {
      httpConnection.setPersistent(false);
      return BODY_TYPE_SIMPLE;
    }
   
    // is content-type set?
    if (responseHeader.getContentType() != null) {
      httpConnection.setPersistent(false);
      return BODY_TYPE_SIMPLE;
    }
 
   
    throw new BadMessageException(responseHeader.toString());
  }
}

TOP

Related Classes of org.xlightweb.HttpProtocolHandlerClientSide

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.