1 16 package org.apache.axis.transport.http; 17 18 19 import java.io.IOException ; 20 import java.io.InputStream ; 21 22 23 27 28 public class ChunkedInputStream extends java.io.FilterInputStream { 29 30 protected long chunkSize = 0l; 31 protected volatile boolean closed = false; 32 33 private static final int maxCharLong = 34 (Long.toHexString(Long.MAX_VALUE)).toString().length(); 35 36 private byte[] buf = new byte[maxCharLong + 2]; 37 38 private ChunkedInputStream () { 39 super(null); 40 } 41 42 public ChunkedInputStream (InputStream is) { 43 super(is); 44 } 45 46 public synchronized int read() 47 throws IOException { 48 if (closed) { 49 return -1; 50 } 51 try { 52 if (chunkSize < 1L) { 53 if (0l == getChunked()) { 54 return -1; 55 } 56 } 57 int rc = in.read(); 58 if (rc > 0) { 59 chunkSize--; 60 } 61 return rc; 62 } catch (IOException e) { 63 closed = true; 64 throw e; 65 } 66 } 67 68 public int read(byte[] b) 69 throws IOException { 70 return read(b, 0, b.length); 71 } 72 73 public synchronized int read(byte[] b, 74 int off, 75 int len) 76 throws IOException { 77 if (closed) { 78 return -1; 79 } 80 81 int totalread = 0; 82 int bytesread = 0; 83 84 try { 85 do { 86 if (chunkSize < 1L) { 87 if (0l == getChunked()) { 88 if (totalread == 0) return -1; 89 else return totalread; 90 } 91 } 92 bytesread = in.read(b, off + totalread, Math.min(len - totalread, 93 (int) Math.min(chunkSize, Integer.MAX_VALUE))); 94 if (bytesread > 0) { 95 totalread += bytesread; 96 chunkSize -= bytesread; 97 } 98 } 99 while (len - totalread > 0 && bytesread > -1); 100 } catch (IOException e) { 101 closed = true; 102 throw e; 103 } 104 return totalread; 105 } 106 107 public long skip(final long n) 108 throws IOException { 109 if (closed) { 110 return 0; 111 } 112 long skipped = 0l; 113 byte[] b = new byte[1024]; 114 int bread = -1; 115 116 do { 117 bread = read(b, 0, b.length); 118 if (bread > 0) skipped += bread; 119 } 120 while (bread != -1 && skipped < n); 121 return skipped; 122 } 123 124 public int available() 125 throws IOException { 126 if (closed) { 127 return 0; 128 } 129 int rc = (int) Math.min(chunkSize, Integer.MAX_VALUE); 130 131 return Math.min(rc, in.available()); 132 } 133 134 protected long getChunked()throws IOException { 135 int bufsz = 0; 136 chunkSize = -1L; 137 int c = -1; 138 139 do { 140 c = in.read(); 141 if (c > -1) { 142 if (c != '\r' && c != '\n' && c != ' ' && c != '\t') { 143 buf[bufsz++] = ((byte) c); 144 } 145 } 146 } 147 while (c > -1 && (c != '\n' || bufsz == 0) && bufsz < buf.length); 148 if (c < 0) { 149 closed = true; 150 } 151 String sbuf = new String (buf, 0, bufsz); 152 153 if (bufsz > maxCharLong) { 154 closed = true; 155 throw new IOException ("Chunked input stream failed to receive valid chunk size:" + sbuf); 156 } 157 try { 158 chunkSize = Long.parseLong(sbuf, 16); 159 } catch (NumberFormatException ne) { 160 closed = true; 161 throw new IOException ("'" + sbuf + "' " + ne.getMessage()); 162 } 163 if (chunkSize < 0L) { 164 closed = true; 165 } if (chunkSize == 0) { 166 closed = true; 167 if (in.read() != -1) { 169 in.read(); 170 } 171 } 172 if (chunkSize != 0L && c < 0) { 173 throw new IOException ("HTTP Chunked stream closed in middle of chunk."); 175 } 176 if (chunkSize < 0L) { 177 throw new IOException ("HTTP Chunk size received " + 178 chunkSize + " is less than zero."); 179 } 180 return chunkSize; 181 } 182 183 public void close() throws IOException { 184 185 synchronized (this) { 186 if (closed) { 187 return; 188 } 189 closed = true; 190 } 191 192 byte[] b = new byte[1024]; 193 int bread = -1; 194 195 do { 196 bread = read(b, 0, b.length); 197 } 198 while (bread != -1); 199 } 200 201 207 208 public void reset() 209 throws IOException { 210 throw new IOException ("Don't support marked streams"); 211 } 212 213 public boolean markSupported() { 214 return false; 215 } 216 217 } 218 | Popular Tags |