1 55 package org.jboss.axis.transport.http; 56 57 58 import java.io.IOException ; 59 import java.io.InputStream ; 60 61 62 65 66 public class ChunkedInputStream extends java.io.FilterInputStream 67 { 68 protected long chunkSize = 0l; 69 protected volatile boolean closed = false; 70 private static final int maxCharLong = (Long.toHexString(Long.MAX_VALUE)) 71 .toString().length(); 72 73 private ChunkedInputStream() 74 { 75 super(null); 76 } 77 78 public ChunkedInputStream(InputStream is) 79 { 80 super(is); 81 } 82 83 public int read() 84 throws IOException 85 { 86 byte[] d = new byte[1]; 87 int rc = read(d, 0, 1); 88 89 return rc > 0 ? (d[0] & 0xFF) : rc; 90 } 91 92 public int read(byte[] b) 93 throws IOException 94 { 95 return read(b, 0, b.length); 96 } 97 98 public synchronized int read(byte[] b, 99 int off, 100 int len) 101 throws IOException 102 { 103 if (closed) return -1; 104 int cs = (int)Math.min(Integer.MAX_VALUE, chunkSize); 105 int totalread = 0; 106 int bytesread = 0; 107 108 try 109 { 110 do 111 { 112 if (chunkSize < 1L) 113 { 114 if (0l == getChunked()) 115 { 116 if (totalread == 0) 117 return -1; 118 else 119 return totalread; 120 } 121 } 122 bytesread = in.read(b, off + totalread, Math.min(len - totalread, 123 (int)Math.min(chunkSize, Integer.MAX_VALUE))); 124 if (bytesread > 0) 125 { 126 totalread += bytesread; 127 chunkSize -= bytesread; 128 } 129 } 130 while (len - totalread > 0 && bytesread > -1); 131 } 132 catch (IOException e) 133 { 134 closed = true; 135 throw e; 136 } 137 return totalread; 138 } 139 140 public long skip(final long n) 141 throws IOException 142 { 143 if (closed) return 0; 144 long skipped = 0l; 145 byte[] b = new byte[1024]; 146 int bread = -1; 147 148 do 149 { 150 bread = read(b, 0, b.length); 151 if (bread > 0) skipped += bread; 152 } 153 while (bread != -1 && skipped < n); 154 return skipped; 155 } 156 157 public int available() 158 throws IOException 159 { 160 if (closed) return 0; 161 int rc = (int)Math.min(chunkSize, Integer.MAX_VALUE); 162 163 return Math.min(rc, in.available()); 164 } 165 166 protected long getChunked() throws IOException 167 { 168 byte[] buf = new byte[maxCharLong + 2]; 170 int bufsz = 0; 171 172 chunkSize = -1L; 173 int c = -1; 174 175 do 176 { 177 c = in.read(); 178 if (c > -1) 179 { 180 if (c != '\r' && c != '\n' && c != ' ' && c != '\t') 181 { 182 buf[bufsz++] = ((byte)c); 183 } 184 } 185 } 186 while (c > -1 && (c != '\n' || bufsz == 0) && bufsz < buf.length); 187 if (c < 0) 188 { 189 closed = true; 190 } 191 String sbuf = new String (buf, 0, bufsz); 192 193 if (bufsz > maxCharLong) 194 { 195 closed = true; 196 throw new IOException ("Chunked input stream failed to receive valid chunk size:" + sbuf); 197 } 198 try 199 { 200 chunkSize = Long.parseLong(sbuf, 16); 201 } 202 catch (NumberFormatException ne) 203 { 204 closed = true; 205 throw new IOException ("'" + sbuf + "' " + ne.getMessage()); 206 } 207 if (chunkSize < 1L) closed = true; 208 if (chunkSize != 0L && c < 0) 209 { 210 throw new IOException ("HTTP Chunked stream closed in middle of chunk."); 212 } 213 if (chunkSize < 0L) 214 throw new IOException ("HTTP Chunk size received " + 215 chunkSize + " is less than zero."); 216 return chunkSize; 217 } 218 219 public void close() throws IOException 220 { 221 222 synchronized (this) 223 { 224 if (closed) return; 225 closed = true; 226 } 227 228 byte[] b = new byte[1024]; 229 int bread = -1; 230 231 do 232 { 233 bread = read(b, 0, b.length); 234 } 235 while (bread != -1); 236 } 237 238 244 245 public void reset() 246 throws IOException 247 { 248 throw new IOException ("Don't support marked streams"); 249 } 250 251 public boolean markSupported() 252 { 253 return false; 254 } 255 256 } 257 | Popular Tags |