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