1 17 18 package org.apache.coyote.http11.filters; 19 20 import java.io.IOException ; 21 22 import org.apache.tomcat.util.buf.ByteChunk; 23 import org.apache.tomcat.util.buf.HexUtils; 24 25 import org.apache.coyote.InputBuffer; 26 import org.apache.coyote.Request; 27 import org.apache.coyote.http11.Constants; 28 import org.apache.coyote.http11.InputFilter; 29 30 37 public class ChunkedInputFilter implements InputFilter { 38 39 40 42 43 protected static final String ENCODING_NAME = "chunked"; 44 protected static final ByteChunk ENCODING = new ByteChunk(); 45 46 47 49 50 static { 51 ENCODING.setBytes(ENCODING_NAME.getBytes(), 0, ENCODING_NAME.length()); 52 } 53 54 55 57 58 61 protected InputBuffer buffer; 62 63 64 67 protected int remaining = 0; 68 69 70 73 protected int pos = 0; 74 75 76 79 protected int lastValid = 0; 80 81 82 85 protected byte[] buf = null; 86 87 88 91 protected ByteChunk readChunk = new ByteChunk(); 92 93 94 97 protected boolean endChunk = false; 98 99 103 protected boolean needCRLFParse = false; 104 105 107 108 110 111 120 public int doRead(ByteChunk chunk, Request req) 121 throws IOException { 122 123 if (endChunk) 124 return -1; 125 126 if(needCRLFParse) { 127 needCRLFParse = false; 128 parseCRLF(); 129 } 130 131 if (remaining <= 0) { 132 if (!parseChunkHeader()) { 133 throw new IOException ("Invalid chunk header"); 134 } 135 if (endChunk) { 136 parseEndChunk(); 137 return -1; 138 } 139 } 140 141 int result = 0; 142 143 if (pos >= lastValid) { 144 readBytes(); 145 } 146 147 if (remaining > (lastValid - pos)) { 148 result = lastValid - pos; 149 remaining = remaining - result; 150 chunk.setBytes(buf, pos, result); 151 pos = lastValid; 152 } else { 153 result = remaining; 154 chunk.setBytes(buf, pos, remaining); 155 pos = pos + remaining; 156 remaining = 0; 157 needCRLFParse = true; 158 } 159 160 return result; 161 162 } 163 164 165 167 168 171 public void setRequest(Request request) { 172 } 173 174 175 178 public long end() 179 throws IOException { 180 181 while (doRead(readChunk, null) >= 0) { 183 } 184 185 return (lastValid - pos); 187 188 } 189 190 191 194 public void setBuffer(InputBuffer buffer) { 195 this.buffer = buffer; 196 } 197 198 199 202 public void recycle() { 203 remaining = 0; 204 pos = 0; 205 lastValid = 0; 206 endChunk = false; 207 } 208 209 210 214 public ByteChunk getEncodingName() { 215 return ENCODING; 216 } 217 218 219 221 222 225 protected int readBytes() 226 throws IOException { 227 228 int nRead = buffer.doRead(readChunk, null); 229 pos = readChunk.getStart(); 230 lastValid = pos + nRead; 231 buf = readChunk.getBytes(); 232 233 return nRead; 234 235 } 236 237 238 247 protected boolean parseChunkHeader() 248 throws IOException { 249 250 int result = 0; 251 boolean eol = false; 252 boolean readDigit = false; 253 boolean trailer = false; 254 255 while (!eol) { 256 257 if (pos >= lastValid) { 258 if (readBytes() <= 0) 259 return false; 260 } 261 262 if (buf[pos] == Constants.CR) { 263 } else if (buf[pos] == Constants.LF) { 264 eol = true; 265 } else if (buf[pos] == Constants.SEMI_COLON) { 266 trailer = true; 267 } else if (!trailer) { 268 if (HexUtils.DEC[buf[pos]] != -1) { 270 readDigit = true; 271 result *= 16; 272 result += HexUtils.DEC[buf[pos]]; 273 } else { 274 return false; 277 } 278 } 279 280 pos++; 281 282 } 283 284 if (!readDigit) 285 return false; 286 287 if (result == 0) 288 endChunk = true; 289 290 remaining = result; 291 if (remaining < 0) 292 return false; 293 294 return true; 295 296 } 297 298 299 302 protected boolean parseCRLF() 303 throws IOException { 304 305 boolean eol = false; 306 307 while (!eol) { 308 309 if (pos >= lastValid) { 310 if (readBytes() <= 0) 311 throw new IOException ("Invalid CRLF"); 312 } 313 314 if (buf[pos] == Constants.CR) { 315 } else if (buf[pos] == Constants.LF) { 316 eol = true; 317 } else { 318 throw new IOException ("Invalid CRLF"); 319 } 320 321 pos++; 322 323 } 324 325 return true; 326 327 } 328 329 330 334 protected boolean parseEndChunk() 335 throws IOException { 336 337 return parseCRLF(); 339 } 340 341 342 } 343 | Popular Tags |