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.handler.codec.http.HttpConstants;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.nio.charset.Charset;
25
26
27
28
29 public class MixedAttribute implements Attribute {
30 private final String baseDir;
31 private final boolean deleteOnExit;
32 private Attribute attribute;
33
34 private final long limitSize;
35 private long maxSize = DefaultHttpDataFactory.MAXSIZE;
36
37 public MixedAttribute(String name, long limitSize) {
38 this(name, limitSize, HttpConstants.DEFAULT_CHARSET);
39 }
40
41 public MixedAttribute(String name, long definedSize, long limitSize) {
42 this(name, definedSize, limitSize, HttpConstants.DEFAULT_CHARSET);
43 }
44
45 public MixedAttribute(String name, long limitSize, Charset charset) {
46 this(name, limitSize, charset, DiskAttribute.baseDirectory, DiskAttribute.deleteOnExitTemporaryFile);
47 }
48
49 public MixedAttribute(String name, long limitSize, Charset charset, String baseDir, boolean deleteOnExit) {
50 this.limitSize = limitSize;
51 attribute = new MemoryAttribute(name, charset);
52 this.baseDir = baseDir;
53 this.deleteOnExit = deleteOnExit;
54 }
55
56 public MixedAttribute(String name, long definedSize, long limitSize, Charset charset) {
57 this(name, definedSize, limitSize, charset,
58 DiskAttribute.baseDirectory, DiskAttribute.deleteOnExitTemporaryFile);
59 }
60
61 public MixedAttribute(String name, long definedSize, long limitSize, Charset charset,
62 String baseDir, boolean deleteOnExit) {
63 this.limitSize = limitSize;
64 attribute = new MemoryAttribute(name, definedSize, charset);
65 this.baseDir = baseDir;
66 this.deleteOnExit = deleteOnExit;
67 }
68
69 public MixedAttribute(String name, String value, long limitSize) {
70 this(name, value, limitSize, HttpConstants.DEFAULT_CHARSET,
71 DiskAttribute.baseDirectory, DiskFileUpload.deleteOnExitTemporaryFile);
72 }
73
74 public MixedAttribute(String name, String value, long limitSize, Charset charset) {
75 this(name, value, limitSize, charset,
76 DiskAttribute.baseDirectory, DiskFileUpload.deleteOnExitTemporaryFile);
77 }
78
79 public MixedAttribute(String name, String value, long limitSize, Charset charset,
80 String baseDir, boolean deleteOnExit) {
81 this.limitSize = limitSize;
82 if (value.length() > this.limitSize) {
83 try {
84 attribute = new DiskAttribute(name, value, charset, baseDir, deleteOnExit);
85 } catch (IOException e) {
86
87 try {
88 attribute = new MemoryAttribute(name, value, charset);
89 } catch (IOException ignore) {
90 throw new IllegalArgumentException(e);
91 }
92 }
93 } else {
94 try {
95 attribute = new MemoryAttribute(name, value, charset);
96 } catch (IOException e) {
97 throw new IllegalArgumentException(e);
98 }
99 }
100 this.baseDir = baseDir;
101 this.deleteOnExit = deleteOnExit;
102 }
103
104 @Override
105 public long getMaxSize() {
106 return maxSize;
107 }
108
109 @Override
110 public void setMaxSize(long maxSize) {
111 this.maxSize = maxSize;
112 attribute.setMaxSize(maxSize);
113 }
114
115 @Override
116 public void checkSize(long newSize) throws IOException {
117 if (maxSize >= 0 && newSize > maxSize) {
118 throw new IOException("Size exceed allowed maximum capacity");
119 }
120 }
121
122 @Override
123 public void addContent(ByteBuf buffer, boolean last) throws IOException {
124 if (attribute instanceof MemoryAttribute) {
125 try {
126 checkSize(attribute.length() + buffer.readableBytes());
127 if (attribute.length() + buffer.readableBytes() > limitSize) {
128 DiskAttribute diskAttribute = new DiskAttribute(attribute
129 .getName(), attribute.definedLength(), baseDir, deleteOnExit);
130 diskAttribute.setMaxSize(maxSize);
131 if (((MemoryAttribute) attribute).getByteBuf() != null) {
132 diskAttribute.addContent(((MemoryAttribute) attribute)
133 .getByteBuf(), false);
134 }
135 attribute = diskAttribute;
136 }
137 } catch (IOException e) {
138 buffer.release();
139 throw e;
140 }
141 }
142 attribute.addContent(buffer, last);
143 }
144
145 @Override
146 public void delete() {
147 attribute.delete();
148 }
149
150 @Override
151 public byte[] get() throws IOException {
152 return attribute.get();
153 }
154
155 @Override
156 public ByteBuf getByteBuf() throws IOException {
157 return attribute.getByteBuf();
158 }
159
160 @Override
161 public Charset getCharset() {
162 return attribute.getCharset();
163 }
164
165 @Override
166 public String getString() throws IOException {
167 return attribute.getString();
168 }
169
170 @Override
171 public String getString(Charset encoding) throws IOException {
172 return attribute.getString(encoding);
173 }
174
175 @Override
176 public boolean isCompleted() {
177 return attribute.isCompleted();
178 }
179
180 @Override
181 public boolean isInMemory() {
182 return attribute.isInMemory();
183 }
184
185 @Override
186 public long length() {
187 return attribute.length();
188 }
189
190 @Override
191 public long definedLength() {
192 return attribute.definedLength();
193 }
194
195 @Override
196 public boolean renameTo(File dest) throws IOException {
197 return attribute.renameTo(dest);
198 }
199
200 @Override
201 public void setCharset(Charset charset) {
202 attribute.setCharset(charset);
203 }
204
205 @Override
206 public void setContent(ByteBuf buffer) throws IOException {
207 try {
208 checkSize(buffer.readableBytes());
209 } catch (IOException e) {
210 buffer.release();
211 throw e;
212 }
213 if (buffer.readableBytes() > limitSize) {
214 if (attribute instanceof MemoryAttribute) {
215
216 attribute = new DiskAttribute(attribute.getName(), attribute.definedLength(), baseDir, deleteOnExit);
217 attribute.setMaxSize(maxSize);
218 }
219 }
220 attribute.setContent(buffer);
221 }
222
223 @Override
224 public void setContent(File file) throws IOException {
225 checkSize(file.length());
226 if (file.length() > limitSize) {
227 if (attribute instanceof MemoryAttribute) {
228
229 attribute = new DiskAttribute(attribute.getName(), attribute.definedLength(), baseDir, deleteOnExit);
230 attribute.setMaxSize(maxSize);
231 }
232 }
233 attribute.setContent(file);
234 }
235
236 @Override
237 public void setContent(InputStream inputStream) throws IOException {
238 if (attribute instanceof MemoryAttribute) {
239
240 attribute = new DiskAttribute(attribute.getName(), attribute.definedLength(), baseDir, deleteOnExit);
241 attribute.setMaxSize(maxSize);
242 }
243 attribute.setContent(inputStream);
244 }
245
246 @Override
247 public HttpDataType getHttpDataType() {
248 return attribute.getHttpDataType();
249 }
250
251 @Override
252 public String getName() {
253 return attribute.getName();
254 }
255
256 @Override
257 public int hashCode() {
258 return attribute.hashCode();
259 }
260
261 @Override
262 public boolean equals(Object obj) {
263 return attribute.equals(obj);
264 }
265
266 @Override
267 public int compareTo(InterfaceHttpData o) {
268 return attribute.compareTo(o);
269 }
270
271 @Override
272 public String toString() {
273 return "Mixed: " + attribute;
274 }
275
276 @Override
277 public String getValue() throws IOException {
278 return attribute.getValue();
279 }
280
281 @Override
282 public void setValue(String value) throws IOException {
283 attribute.setValue(value);
284 }
285
286 @Override
287 public ByteBuf getChunk(int length) throws IOException {
288 return attribute.getChunk(length);
289 }
290
291 @Override
292 public File getFile() throws IOException {
293 return attribute.getFile();
294 }
295
296 @Override
297 public Attribute copy() {
298 return attribute.copy();
299 }
300
301 @Override
302 public Attribute duplicate() {
303 return attribute.duplicate();
304 }
305
306 @Override
307 public Attribute retainedDuplicate() {
308 return attribute.retainedDuplicate();
309 }
310
311 @Override
312 public Attribute replace(ByteBuf content) {
313 return attribute.replace(content);
314 }
315
316 @Override
317 public ByteBuf content() {
318 return attribute.content();
319 }
320
321 @Override
322 public int refCnt() {
323 return attribute.refCnt();
324 }
325
326 @Override
327 public Attribute retain() {
328 attribute.retain();
329 return this;
330 }
331
332 @Override
333 public Attribute retain(int increment) {
334 attribute.retain(increment);
335 return this;
336 }
337
338 @Override
339 public Attribute touch() {
340 attribute.touch();
341 return this;
342 }
343
344 @Override
345 public Attribute touch(Object hint) {
346 attribute.touch(hint);
347 return this;
348 }
349
350 @Override
351 public boolean release() {
352 return attribute.release();
353 }
354
355 @Override
356 public boolean release(int decrement) {
357 return attribute.release(decrement);
358 }
359 }