1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.http.multipart;
17
18 import io.netty.buffer.ByteBuf;
19 import io.netty.buffer.CompositeByteBuf;
20 import io.netty.handler.codec.http.HttpConstants;
21
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.nio.ByteBuffer;
28 import java.nio.channels.FileChannel;
29 import java.nio.charset.Charset;
30
31 import static io.netty.buffer.Unpooled.*;
32
33
34
35
36 public abstract class AbstractMemoryHttpData extends AbstractHttpData {
37
38 private ByteBuf byteBuf;
39 private int chunkPosition;
40 protected boolean isRenamed;
41
42 protected AbstractMemoryHttpData(String name, Charset charset, long size) {
43 super(name, charset, size);
44 }
45
46 @Override
47 public void setContent(ByteBuf buffer) throws IOException {
48 if (buffer == null) {
49 throw new NullPointerException("buffer");
50 }
51 long localsize = buffer.readableBytes();
52 if (definedSize > 0 && definedSize < localsize) {
53 throw new IOException("Out of size: " + localsize + " > " +
54 definedSize);
55 }
56 if (byteBuf != null) {
57 byteBuf.release();
58 }
59 byteBuf = buffer;
60 size = localsize;
61 completed = true;
62 }
63
64 @Override
65 public void setContent(InputStream inputStream) throws IOException {
66 if (inputStream == null) {
67 throw new NullPointerException("inputStream");
68 }
69 ByteBuf buffer = buffer();
70 byte[] bytes = new byte[4096 * 4];
71 int read = inputStream.read(bytes);
72 int written = 0;
73 while (read > 0) {
74 buffer.writeBytes(bytes, 0, read);
75 written += read;
76 read = inputStream.read(bytes);
77 }
78 size = written;
79 if (definedSize > 0 && definedSize < size) {
80 throw new IOException("Out of size: " + size + " > " + definedSize);
81 }
82 if (byteBuf != null) {
83 byteBuf.release();
84 }
85 byteBuf = buffer;
86 completed = true;
87 }
88
89 @Override
90 public void addContent(ByteBuf buffer, boolean last)
91 throws IOException {
92 if (buffer != null) {
93 long localsize = buffer.readableBytes();
94 if (definedSize > 0 && definedSize < size + localsize) {
95 throw new IOException("Out of size: " + (size + localsize) +
96 " > " + definedSize);
97 }
98 size += localsize;
99 if (byteBuf == null) {
100 byteBuf = buffer;
101 } else if (byteBuf instanceof CompositeByteBuf) {
102 CompositeByteBuf cbb = (CompositeByteBuf) byteBuf;
103 cbb.addComponent(true, buffer);
104 } else {
105 CompositeByteBuf cbb = compositeBuffer(Integer.MAX_VALUE);
106 cbb.addComponents(true, byteBuf, buffer);
107 byteBuf = cbb;
108 }
109 }
110 if (last) {
111 completed = true;
112 } else {
113 if (buffer == null) {
114 throw new NullPointerException("buffer");
115 }
116 }
117 }
118
119 @Override
120 public void setContent(File file) throws IOException {
121 if (file == null) {
122 throw new NullPointerException("file");
123 }
124 long newsize = file.length();
125 if (newsize > Integer.MAX_VALUE) {
126 throw new IllegalArgumentException(
127 "File too big to be loaded in memory");
128 }
129 FileInputStream inputStream = new FileInputStream(file);
130 FileChannel fileChannel = inputStream.getChannel();
131 byte[] array = new byte[(int) newsize];
132 ByteBuffer byteBuffer = ByteBuffer.wrap(array);
133 int read = 0;
134 while (read < newsize) {
135 read += fileChannel.read(byteBuffer);
136 }
137 fileChannel.close();
138 inputStream.close();
139 byteBuffer.flip();
140 if (byteBuf != null) {
141 byteBuf.release();
142 }
143 byteBuf = wrappedBuffer(Integer.MAX_VALUE, byteBuffer);
144 size = newsize;
145 completed = true;
146 }
147
148 @Override
149 public void delete() {
150 if (byteBuf != null) {
151 byteBuf.release();
152 byteBuf = null;
153 }
154 }
155
156 @Override
157 public byte[] get() {
158 if (byteBuf == null) {
159 return EMPTY_BUFFER.array();
160 }
161 byte[] array = new byte[byteBuf.readableBytes()];
162 byteBuf.getBytes(byteBuf.readerIndex(), array);
163 return array;
164 }
165
166 @Override
167 public String getString() {
168 return getString(HttpConstants.DEFAULT_CHARSET);
169 }
170
171 @Override
172 public String getString(Charset encoding) {
173 if (byteBuf == null) {
174 return "";
175 }
176 if (encoding == null) {
177 encoding = HttpConstants.DEFAULT_CHARSET;
178 }
179 return byteBuf.toString(encoding);
180 }
181
182
183
184
185
186
187 @Override
188 public ByteBuf getByteBuf() {
189 return byteBuf;
190 }
191
192 @Override
193 public ByteBuf getChunk(int length) throws IOException {
194 if (byteBuf == null || length == 0 || byteBuf.readableBytes() == 0) {
195 chunkPosition = 0;
196 return EMPTY_BUFFER;
197 }
198 int sizeLeft = byteBuf.readableBytes() - chunkPosition;
199 if (sizeLeft == 0) {
200 chunkPosition = 0;
201 return EMPTY_BUFFER;
202 }
203 int sliceLength = length;
204 if (sizeLeft < length) {
205 sliceLength = sizeLeft;
206 }
207 ByteBuf chunk = byteBuf.slice(chunkPosition, sliceLength).retain();
208 chunkPosition += sliceLength;
209 return chunk;
210 }
211
212 @Override
213 public boolean isInMemory() {
214 return true;
215 }
216
217 @Override
218 public boolean renameTo(File dest) throws IOException {
219 if (dest == null) {
220 throw new NullPointerException("dest");
221 }
222 if (byteBuf == null) {
223
224 dest.createNewFile();
225 isRenamed = true;
226 return true;
227 }
228 int length = byteBuf.readableBytes();
229 FileOutputStream outputStream = new FileOutputStream(dest);
230 FileChannel fileChannel = outputStream.getChannel();
231 int written = 0;
232 if (byteBuf.nioBufferCount() == 1) {
233 ByteBuffer byteBuffer = byteBuf.nioBuffer();
234 while (written < length) {
235 written += fileChannel.write(byteBuffer);
236 }
237 } else {
238 ByteBuffer[] byteBuffers = byteBuf.nioBuffers();
239 while (written < length) {
240 written += fileChannel.write(byteBuffers);
241 }
242 }
243
244 fileChannel.force(false);
245 fileChannel.close();
246 outputStream.close();
247 isRenamed = true;
248 return written == length;
249 }
250
251 @Override
252 public File getFile() throws IOException {
253 throw new IOException("Not represented by a file");
254 }
255 }