Package de.netseeker.ejoe.http

Examples of de.netseeker.ejoe.http.HttpHeaderParser


            // something strange happened - at least the handshake data must be written in one operation
            if ( hBuffer.hasRemaining() ) return null;
        }

        // read and parse the HTTP header - this can also preread one or more bytes of none-header-data (content)
        HttpHeaderParser parser = readHttpHeader( channel, prereadHead, timeout, header.isClient() );

        // little bit paranoia
        if ( parser == null )
        {
            return null;
        }

        // get the read ByteBuffer
        magicBuf = parser.getByteHeader();

        if ( header.isClient() )
        {
            // did the HTTP parser already read the content? if so the ByteBuffer has already the required size.
            if ( magicBuf == null )
            {
                // allocate an appropiate ByteBuffer
                magicBuf = ByteBufferAllocator.allocate( parser.getContentLength() );
            }

            // did the HTTP parser already read the complete content (the eight bits of the header byte)?
            if ( magicBuf.position() < (parser.getContentLength() - 1) )
            {
                // read the data part
                semiBlockingRead( channel, magicBuf, timeout );
                if ( magicBuf.hasRemaining() ) return null;
            }

            magicBuf.flip();

            if ( logger.isLoggable( Level.FINEST ) )
            {
                logger.log( Level.FINEST, "HTTP-Header read: "
                        + IOUtil.bBitsToSBits( IOUtil.byteToBBits( magicBuf.get() ) ) );
                magicBuf.rewind();
            }

            receiverHeader = new ConnectionHeader( channel, host, header.isClient(), magicBuf.get() );
        }
        // shall we act as server side and answer to the handshake request?
        else
        {
            receiverHeader = new ConnectionHeader( channel, host, header.isClient() );
            // the HTTP header must contain the eight header bits in the requested URI
            receiverHeader.fromString( ((HttpRequestParser) parser).getUri() );

            // does the http header overwrite the compression setting?
            receiverHeader.setCompression( header.hasCompression() && parser.hasCompression() );

            // does the http header overwrite the setting for using a persistent connection?
            receiverHeader.setPersistent( parser.isPersistentConnection() && header.isPersistent() );

            // answer to the client request and send our serverside headerbyte
            // clients as browsers (IE, Firefox, Opera) or similiar doesn't understand our handshake
            // hence we send our handshake response only when the client tells us that it is able
            // to parse our response
            if ( receiverHeader.isHandshakeResponseAware() )
            {
                // create a HTTP response with just our server header byte as content
                HttpResponse response = new HttpResponse( header, HttpResponse.HTTP_OK );
                response.addData( header.toByte() );
                logger.log( Level.FINEST, "Sending server headerbyte: " + header );
                hBuffer = response.toByteBuffer();
                semiBlockingWrite( channel, hBuffer, timeout );
                if ( hBuffer.hasRemaining() ) return null;
            }
            // ok, a unknown client which might have already send some content with it's first request
            else if ( parser.hasPrereadContent() )
            {
                receiverHeader.setWaitingBuffer( parser.getByteHeader() );
            }
        }

        receiverHeader.setHttp( true );
        receiverHeader.setConnected( true );
View Full Code Here


     * @throws ConnectionTimeoutException
     */
    private HttpHeaderParser readHttpHeader( SocketChannel channel, byte[] preReadData, long timeout, boolean isRequest )
            throws IOException, ParseException
    {
        HttpHeaderParser httpHeaderParser = null;
        // prepare a byte buffer which will receive the HTTP header [ + preread content ]
        ByteBuffer headerBuf = ByteBufferAllocator.allocate( EJConstants.HTTP_BYTEBUFFER_PREALLOC );

        // do we already have some preread content?
        if ( preReadData != null )
        {
            // if so put it at the beginning of the byte buffer
            headerBuf.put( preReadData );
        }

        int readControl = 0;
        int limit = -1;

        long timestamp = System.currentTimeMillis();
        long timePeriod = -1;
        do
        {
            limit = headerBuf.limit();
            // increase the byte buffer if it's free memory falls below 20 percent
            if ( headerBuf.remaining() <= (limit / 5) )
            {
                logger.log( Level.FINEST, "Allocating additional " + (limit / 2) + "b for buffer with " + limit + "b" );
                headerBuf = ByteBufferAllocator.reAllocate( headerBuf, limit + (limit / 2) );
            }

            readControl = channel.read( headerBuf );
            timePeriod = System.currentTimeMillis() - timestamp;
        }
        while ( readControl > -1 && !HttpHeaderParser.isComplete( headerBuf ) && (timePeriod < timeout) );

        // timeout occured?
        if ( timePeriod >= timeout )
        {
            throw new SocketTimeoutException();
        }
        else if ( readControl == -1 && headerBuf.position() == 0 )
        {
            throw new ClosedChannelException();
        }
        // stream ended but HTTP header isn't complete?
        else if ( !HttpHeaderParser.isComplete( headerBuf ) )
        {
            throw new ParseException( "Received HTTP Header missing finalizing line terminators (\\r\\n\\r\\n)!",
                                      readControl );
        }

        if ( logger.isLoggable( Level.FINEST ) )
        {
            logger.log( Level.FINEST, "HTTP Header read: complete=" + HttpHeaderParser.isComplete( headerBuf )
                    + ", readControl=" + readControl + ", bytes read: " + headerBuf.position() );
        }

        headerBuf.flip();

        if ( logger.isLoggable( Level.FINE ) )
        {
            logger.log( Level.FINE, IOUtil.decodeToString( headerBuf ) );
            headerBuf.position( 0 );
        }

        // instantiate an appropiate HTTP header parser depending on whether the data are a HTTP request or a response
        if ( isRequest )
        {
            httpHeaderParser = new HttpResponseParser( headerBuf );
        }
        else
        {
            httpHeaderParser = new HttpRequestParser( headerBuf );
        }

        // validate the data
        if ( !httpHeaderParser.isValid() )
        {
            headerBuf.rewind();
            throw new ParseException( httpHeaderParser.getClass().getName() + ": Invalid HTTP header detected!!!\n"
                    + IOUtil.decodeToString( headerBuf ), 0 );
        }

        return httpHeaderParser;
    }
View Full Code Here

     *
     * @see de.netseeker.ejoe.io.DataChannel#readHeader(de.netseeker.ejoe.ConnectionHeader, long)
     */
    public int readHeader( ConnectionHeader header, long timeout ) throws IOException
    {
        HttpHeaderParser parser = null;
        try
        {
            parser = readHttpHeader( header.getChannel(), null, timeout, header.isClient() );
        }
        catch ( ParseException e )
        {
            throw new IOException( e.getMessage() );
        }

        if ( parser.hasPrereadContent() )
        {
            header.setWaitingBuffer( parser.getByteHeader() );
        }

        return parser.getContentLength();
    }
View Full Code Here

TOP

Related Classes of de.netseeker.ejoe.http.HttpHeaderParser

Copyright © 2018 www.massapicom. 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.