001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.coyote.http11.filters;
019:
020: import java.io.IOException;
021: import org.apache.coyote.Request;
022: import org.apache.coyote.InputBuffer;
023: import org.apache.coyote.http11.InputFilter;
024: import org.apache.tomcat.util.buf.ByteChunk;
025:
026: /**
027: * Input filter responsible for reading and buffering the request body, so that
028: * it does not interfere with client SSL handshake messages.
029: */
030: public class BufferedInputFilter implements InputFilter {
031:
032: // -------------------------------------------------------------- Constants
033:
034: private static final String ENCODING_NAME = "buffered";
035: private static final ByteChunk ENCODING = new ByteChunk();
036:
037: // ----------------------------------------------------- Instance Variables
038:
039: private ByteChunk buffered = null;
040: private ByteChunk tempRead = new ByteChunk(1024);
041: private InputBuffer buffer;
042: private boolean hasRead = false;
043:
044: // ----------------------------------------------------- Static Initializer
045:
046: static {
047: ENCODING.setBytes(ENCODING_NAME.getBytes(), 0, ENCODING_NAME
048: .length());
049: }
050:
051: // --------------------------------------------------------- Public Methods
052:
053: /**
054: * Set the buffering limit. This should be reset every time the buffer is
055: * used.
056: */
057: public void setLimit(int limit) {
058: if (buffered == null) {
059: buffered = new ByteChunk(4048);
060: buffered.setLimit(limit);
061: }
062: }
063:
064: // ---------------------------------------------------- InputBuffer Methods
065:
066: /**
067: * Reads the request body and buffers it.
068: */
069: public void setRequest(Request request) {
070: // save off the Request body
071: try {
072: while (buffer.doRead(tempRead, request) >= 0) {
073: buffered.append(tempRead);
074: tempRead.recycle();
075: }
076: } catch (IOException iex) {
077: // Ignore
078: }
079: }
080:
081: /**
082: * Fills the given ByteChunk with the buffered request body.
083: */
084: public int doRead(ByteChunk chunk, Request request)
085: throws IOException {
086: if (hasRead || buffered.getLength() <= 0) {
087: return -1;
088: } else {
089: chunk.setBytes(buffered.getBytes(), buffered.getStart(),
090: buffered.getLength());
091: hasRead = true;
092: }
093: return chunk.getLength();
094: }
095:
096: public void setBuffer(InputBuffer buffer) {
097: this .buffer = buffer;
098: }
099:
100: public void recycle() {
101: if (buffered.getBuffer().length > 65536) {
102: buffered = null;
103: } else {
104: buffered.recycle();
105: }
106: tempRead.recycle();
107: hasRead = false;
108: buffer = null;
109: }
110:
111: public ByteChunk getEncodingName() {
112: return ENCODING;
113: }
114:
115: public long end() throws IOException {
116: return 0;
117: }
118:
119: public int available() {
120: return buffered.getLength();
121: }
122:
123: }
|