1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.coyote.http11.filters;
18
19 import java.io.IOException;
20 import java.nio.ByteBuffer;
21
22 import org.apache.coyote.Response;
23 import org.apache.coyote.http11.HttpOutputBuffer;
24 import org.apache.coyote.http11.OutputFilter;
25
26 /**
27 * Identity output filter.
28 *
29 * @author Remy Maucherat
30 */
31 public class IdentityOutputFilter implements OutputFilter {
32
33 // ----------------------------------------------------- Instance Variables
34
35 /**
36 * Content length.
37 */
38 protected long contentLength = -1;
39
40
41 /**
42 * Remaining bytes.
43 */
44 protected long remaining = 0;
45
46
47 /**
48 * Next buffer in the pipeline.
49 */
50 protected HttpOutputBuffer buffer;
51
52
53 // --------------------------------------------------- OutputBuffer Methods
54
55 @Override
56 public int doWrite(ByteBuffer chunk) throws IOException {
57
58 int result = -1;
59
60 if (contentLength >= 0) {
61 if (remaining > 0) {
62 result = chunk.remaining();
63 if (result > remaining) {
64 // The chunk is longer than the number of bytes remaining
65 // in the body; changing the chunk length to the number
66 // of bytes remaining
67 chunk.limit(chunk.position() + (int) remaining);
68 result = (int) remaining;
69 remaining = 0;
70 } else {
71 remaining = remaining - result;
72 }
73 buffer.doWrite(chunk);
74 } else {
75 // No more bytes left to be written : return -1 and clear the
76 // buffer
77 chunk.position(0);
78 chunk.limit(0);
79 result = -1;
80 }
81 } else {
82 // If no content length was set, just write the bytes
83 result = chunk.remaining();
84 buffer.doWrite(chunk);
85 result -= chunk.remaining();
86 }
87
88 return result;
89
90 }
91
92
93 @Override
94 public long getBytesWritten() {
95 return buffer.getBytesWritten();
96 }
97
98
99 // --------------------------------------------------- OutputFilter Methods
100
101 @Override
102 public void setResponse(Response response) {
103 contentLength = response.getContentLengthLong();
104 remaining = contentLength;
105 }
106
107
108 @Override
109 public void setBuffer(HttpOutputBuffer buffer) {
110 this.buffer = buffer;
111 }
112
113
114 @Override
115 public void flush() throws IOException {
116 // No data buffered in this filter. Flush next buffer.
117 buffer.flush();
118 }
119
120
121 @Override
122 public void end() throws IOException {
123 buffer.end();
124 }
125
126
127 @Override
128 public void recycle() {
129 contentLength = -1;
130 remaining = 0;
131 }
132 }
133