Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * JBoss, Home of Professional Open Source.
   * Copyright 2012 Red Hat, Inc., and individual contributors
   * as indicated by the @author tags.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package org.apache.coyote.http11;
 
 import static org.jboss.web.CoyoteMessages.MESSAGES;
 
 import  java.nio.channels.CompletionHandler;
 
InternalNioInputBuffer

Implementation of InputBuffer which provides HTTP request header parsing as well as transfer decoding.

Created on Dec 14, 2011 at 9:06:18 AM

Author(s):
Nabil Benothman
 
Underlying channel.
 
 	protected NioChannel channel;

Non blocking mode.
 
 	protected boolean nonBlocking = false;

Non blocking mode.
 
 	protected boolean available = true;

NIO end point.
 
 	protected NioEndpoint endpoint = null;

    
NIO processor.
 
     protected Http11NioProcessor processor;

The completion handler used for asynchronous read operations
 
 	private CompletionHandler<IntegerNioChannelcompletionHandler;

    
Semaphore used for waiting for completion handler.
 
     private Semaphore semaphore = new Semaphore(1);
    
    
Create a new instance of InternalNioInputBuffer

Parameters:
request
headerBufferSize
endpoint
 
 	public InternalNioInputBuffer(Http11NioProcessor processorRequest requestint headerBufferSizeNioEndpoint endpoint) {
 		super(requestheaderBufferSize);
 		this. = endpoint;
         this. = processor;
 		this.init();
 	}

	protected void init() {
		// Initialize the completion handler
		this. = new CompletionHandler<IntegerNioChannel>() {
			public synchronized void completed(Integer nBytesNioChannel attachment) {
			    if (nBytes < 0) {
			        failed(new ClosedChannelException(), attachment);
			        return;
			    }
			    if (nBytes > 0) {
			        .flip();
	                if (nBytes > (. - )) {
	                    // An alternative is to bbuf.limit(buf.length - end) before the read,
	                    // which may be less efficient
	                     = new byte[.];
	                     = 0;
	                     = ;
	                     = ;
	                }
			        .get(nBytes);
			         =  + nBytes;
			        .release();
			        if (/*!processor.isProcessing() && */.getReadNotifications()
			                && ) {
			             = false;
			            if (!.processChannel(attachment.)) {
			                .closeChannel(attachment);
			            }
			        }
			    }
			}
			public void failed(Throwable excNioChannel attachment) {
			    .removeEventChannel(attachment);
                .release();
			    if (!.processChannel(attachment.)) {
			        .closeChannel(attachment);
			    }
			}
		};
	}

Set the underlying channel.

Parameters:
channel
	public void setChannel(NioChannel channel) {
		this. = channel;
	}

Get the underlying socket input stream.

Returns:
the channel
	public NioChannel getChannel() {
		return ;
	}

Set the non blocking flag.

Parameters:
nonBlocking
	public void setNonBlocking(boolean nonBlocking) {
		this. = nonBlocking;
	}

Get the non blocking flag value.

Returns:
true if the buffer is non-blocking else false
	public boolean getNonBlocking() {
		return ;
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.coyote.http11.AbstractInternalInputBuffer#recycle()
	 */
	public void recycle() {
		super.recycle();
		 = null;
		 = true;
         = (.getSoTimeout() > 0 ? .getSoTimeout()
                : .);
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.coyote.http11.AbstractInternalInputBuffer#nextRequest()
	 */
	public boolean nextRequest() {
		boolean result = super.nextRequest();
		 = true;
        if () {
            .release();
        }
         = false;
		return result;
	}

Read the request line. This function is meant to be used during the HTTP request header parsing. Do NOT attempt to read the request body using it.

Parameters:
useAvailableData
Returns:
true if data is properly fed; false if no data is available immediately and thread should be freed
Throws:
IOException If an exception occurs during the underlying socket read operations, or if the given buffer is not big enough to accommodate the whole line.
	public boolean parseRequestLine(boolean useAvailableDatathrows IOException {
		int start = 0;
		// Skipping blank lines
		byte chr = 0;
		do {
			// Read new bytes if needed
			if ( >= ) {
				if (useAvailableData) {
					return false;
				}
				if (!fill()) {
				}
			}
			chr = [++];
while ((chr == .) || (chr == .));
		--;
		// Mark the current buffer position
		start = ;
		if ( >= ) {
			if (useAvailableData) {
				return false;
			}
			if (!fill()) {
			}
		}
		// Reading the method name
		// Method name is always US-ASCII
		boolean space = false;
		while (!space) {
			// Read new bytes if needed
			if ( >= ) {
				if (!fill()) {
				}
			}
			// Spec says single SP but it also says be tolerant of HT
			if ([] == . || [] == .) {
				space = true;
				.method().setBytes(start - start);
			}
			++;
		}
		// Spec says single SP but also says be tolerant of multiple and/or HT
		while (space) {
			// Read new bytes if needed
			if ( >= ) {
				if (!fill()) {
				}
			}
			if ([] == . || [] == .) {
				++;
else {
				space = false;
			}
		}
		// Mark the current buffer position
		start = ;
		int end = 0;
		int questionPos = -1;
		// Reading the URI
		boolean eol = false;
		while (!space) {
			// Read new bytes if needed
			if ( >= ) {
				if (!fill())
			}
			// Spec says single SP but it also says be tolerant of HT
			if ([] == . || [] == .) {
				space = true;
				end = ;
else if (([] == .) || ([] == .)) {
				// HTTP/0.9 style request
				eol = true;
				space = true;
				end = ;
else if (([] == .) && (questionPos == -1)) {
				questionPos = ;
			}
			++;
		}
		.unparsedURI().setBytes(startend - start);
		if (questionPos >= 0) {
			.queryString().setBytes(questionPos + 1, end - questionPos - 1);
			.requestURI().setBytes(startquestionPos - start);
else {
			.requestURI().setBytes(startend - start);
		}
		// Spec says single SP but also says be tolerant of multiple and/or HT
		while (space) {
			// Read new bytes if needed
			if ( >= ) {
				if (!fill())
			}
			if ([] == . || [] == .) {
				++;
else {
				space = false;
			}
		}
		// Mark the current buffer position
		start = ;
		end = 0;
		//
		// Reading the protocol
		// Protocol is always US-ASCII
		//
		while (!eol) {
			// Read new bytes if needed
			if ( >= ) {
				if (!fill()) {
				}
			}
			if ([] == .) {
				end = ;
else if ([] == .) {
				if (end == 0)
					end = ;
				eol = true;
			}
			++;
		}
		if ((end - start) > 0) {
			.protocol().setBytes(startend - start);
else {
		}
		return true;
	}

Available bytes (note that due to encoding, this may not correspond )
	public void useAvailable() {
		 = true;
	}

Available bytes in the buffer ? (these may not translate to application readable data)

Returns:
the number of available bytes in the buffer
	public boolean available() {
		return ( -  > 0);
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.apache.coyote.InputBuffer#doRead(org.apache.tomcat.util.buf.ByteChunk
	 * , org.apache.coyote.Request)
	 */
	public int doRead(ByteChunk chunkRequest reqthrows IOException {
		return ( == -1) ? .doRead(chunkreq)
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.coyote.http11.AbstractInternalInputBuffer#fill()
	 */
	protected boolean fill() throws IOException {
		return (fill0() >= 0);
	}
    private int fill0() throws IOException {
        int nRead = 0;
        // Reading from client
        if () {
            if (.tryAcquire()) {
                synchronized () {
                    // Prepare the internal input buffer for reading
                    prepare();
                    boolean available0 = available;
                    available = false;
                    try {
                        channel.read(bbuf, readTimeout, TimeUnit.MILLISECONDS, channel, this.completionHandler);
                    } catch (Exception e) {
                        processor.getResponse().setErrorException(e);
                        if (CoyoteLogger.HTTP_LOGGER.isDebugEnabled()) {
                            CoyoteLogger.HTTP_LOGGER.errorWithNonBlockingRead(e);
                        }
                    }
                    nRead = lastValid - pos;
                    if (nRead > 0) {
                        available = false;
                    } else {
                        available = available0;
                    }
                }
            } else {
                synchronized () {
                    if (nRead == 0 && !available) {
                        // If there's nothing and flow control is not used, autoblock 
                        try {
                            if (semaphore.tryAcquire(readTimeout, unit))
                                semaphore.release();
                        } catch (InterruptedException e) {
                            // Ignore
                        }
                        nRead = lastValid - pos;
                    }
                }
            }
        } else {
            // Prepare the internal input buffer for reading
            prepare();
            try {
                nRead = .readBytes();
            } catch (Exception e) {
                if (..isDebugEnabled()) {
                    ..errorWithBlockingRead(e);
                }
            }
            if (nRead > 0) {
                .flip();
                if (nRead > (. - )) {
                    // An alternative is to bbuf.limit(buf.length - end) before the read,
                    // which may be less efficient
                     = new byte[.];
                     = 0;
                     = ;
                     = ;
                }
                .get(nRead);
                 =  + nRead;
            } else if (nRead == .) {
                throw new EOFException(.failedRead());
            } else if (nRead == .) {
                throw new SocketTimeoutException(.failedRead());
            } else if (nRead == 0) {
                throw new EOFException(.failedRead());
            }
        }
        return nRead;
    }

    
Prepare the input buffer for reading
	private void prepare() {
			if ( == .) {
			}
else {
		    // Alternative to buffer reallocation
		    // bbuf.limit(buf.length - end);
			 = ;
		}
	}

This class is an input buffer which will read its data from an input stream.
	protected class InputBufferImpl implements InputBuffer {

Read bytes into the specified chunk.
		public int doRead(ByteChunk chunkRequest reqthrows IOException {
            if ( >= ) {
                int nRead = fill0();
                if (nRead < 0) {
                    return -1;
                } else if (nRead == 0) {
                    return 0;
                }
            }
            if () {
                synchronized () {
                    int length = lastValid - pos;
                    chunk.setBytes(buf, pos, length);
                    pos = lastValid;
                    return (length);
                }
		    } else {
		        int length =  - ;
		        chunk.setBytes(length);
		         = ;
		        return (length);
		    }
		}
	}
New to GrepCode? Check out our FAQ X