001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.coyote.http11.filters;
018:
019: import java.io.IOException;
020:
021: import org.apache.tomcat.util.buf.ByteChunk;
022:
023: import org.apache.coyote.InputBuffer;
024: import org.apache.coyote.Request;
025: import org.apache.coyote.http11.InputFilter;
026:
027: /**
028: * Identity input filter.
029: *
030: * @author Remy Maucherat
031: */
032: public class IdentityInputFilter implements InputFilter {
033:
034: // -------------------------------------------------------------- Constants
035:
036: protected static final String ENCODING_NAME = "identity";
037: protected static final ByteChunk ENCODING = new ByteChunk();
038:
039: // ----------------------------------------------------- Static Initializer
040:
041: static {
042: ENCODING.setBytes(ENCODING_NAME.getBytes(), 0, ENCODING_NAME
043: .length());
044: }
045:
046: // ----------------------------------------------------- Instance Variables
047:
048: /**
049: * Content length.
050: */
051: protected long contentLength = -1;
052:
053: /**
054: * Remaining bytes.
055: */
056: protected long remaining = 0;
057:
058: /**
059: * Next buffer in the pipeline.
060: */
061: protected InputBuffer buffer;
062:
063: /**
064: * Chunk used to read leftover bytes.
065: */
066: protected ByteChunk endChunk = new ByteChunk();
067:
068: // ------------------------------------------------------------- Properties
069:
070: /**
071: * Get content length.
072: */
073: public long getContentLength() {
074: return contentLength;
075: }
076:
077: /**
078: * Get remaining bytes.
079: */
080: public long getRemaining() {
081: return remaining;
082: }
083:
084: // ---------------------------------------------------- InputBuffer Methods
085:
086: /**
087: * Read bytes.
088: *
089: * @return If the filter does request length control, this value is
090: * significant; it should be the number of bytes consumed from the buffer,
091: * up until the end of the current request body, or the buffer length,
092: * whichever is greater. If the filter does not do request body length
093: * control, the returned value should be -1.
094: */
095: public int doRead(ByteChunk chunk, Request req) throws IOException {
096:
097: int result = -1;
098:
099: if (contentLength >= 0) {
100: if (remaining > 0) {
101: int nRead = buffer.doRead(chunk, req);
102: if (nRead > remaining) {
103: // The chunk is longer than the number of bytes remaining
104: // in the body; changing the chunk length to the number
105: // of bytes remaining
106: chunk.setBytes(chunk.getBytes(), chunk.getStart(),
107: (int) remaining);
108: result = (int) remaining;
109: } else {
110: result = nRead;
111: }
112: remaining = remaining - nRead;
113: } else {
114: // No more bytes left to be read : return -1 and clear the
115: // buffer
116: chunk.recycle();
117: result = -1;
118: }
119: }
120:
121: return result;
122:
123: }
124:
125: // ---------------------------------------------------- InputFilter Methods
126:
127: /**
128: * Read the content length from the request.
129: */
130: public void setRequest(Request request) {
131: contentLength = request.getContentLengthLong();
132: remaining = contentLength;
133: }
134:
135: /**
136: * End the current request.
137: */
138: public long end() throws IOException {
139:
140: // Consume extra bytes.
141: while (remaining > 0) {
142: int nread = buffer.doRead(endChunk, null);
143: if (nread > 0) {
144: remaining = remaining - nread;
145: } else { // errors are handled higher up.
146: remaining = 0;
147: }
148: }
149:
150: // If too many bytes were read, return the amount.
151: return -remaining;
152:
153: }
154:
155: /**
156: * Set the next buffer in the filter pipeline.
157: */
158: public void setBuffer(InputBuffer buffer) {
159: this .buffer = buffer;
160: }
161:
162: /**
163: * Make the filter ready to process the next request.
164: */
165: public void recycle() {
166: contentLength = -1;
167: remaining = 0;
168: endChunk.recycle();
169: }
170:
171: /**
172: * Return the name of the associated encoding; Here, the value is
173: * "identity".
174: */
175: public ByteChunk getEncodingName() {
176: return ENCODING;
177: }
178:
179: }
|