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.util.AbstractReferenceCounted;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.nio.charset.Charset;
25
26 abstract class AbstractMixedHttpData<D extends HttpData> extends AbstractReferenceCounted implements HttpData {
27 final String baseDir;
28 final boolean deleteOnExit;
29 D wrapped;
30
31 private final long limitSize;
32
33 AbstractMixedHttpData(long limitSize, String baseDir, boolean deleteOnExit, D initial) {
34 this.limitSize = limitSize;
35 this.wrapped = initial;
36 this.baseDir = baseDir;
37 this.deleteOnExit = deleteOnExit;
38 }
39
40 abstract D makeDiskData();
41
42 @Override
43 public long getMaxSize() {
44 return wrapped.getMaxSize();
45 }
46
47 @Override
48 public void setMaxSize(long maxSize) {
49 wrapped.setMaxSize(maxSize);
50 }
51
52 @Override
53 public ByteBuf content() {
54 return wrapped.content();
55 }
56
57 @Override
58 public void checkSize(long newSize) throws IOException {
59 wrapped.checkSize(newSize);
60 }
61
62 @Override
63 public long definedLength() {
64 return wrapped.definedLength();
65 }
66
67 @Override
68 public Charset getCharset() {
69 return wrapped.getCharset();
70 }
71
72 @Override
73 public String getName() {
74 return wrapped.getName();
75 }
76
77 @Override
78 public void addContent(ByteBuf buffer, boolean last) throws IOException {
79 if (wrapped instanceof AbstractMemoryHttpData) {
80 try {
81 checkSize(wrapped.length() + buffer.readableBytes());
82 if (wrapped.length() + buffer.readableBytes() > limitSize) {
83 D diskData = makeDiskData();
84 ByteBuf data = ((AbstractMemoryHttpData) wrapped).getByteBuf();
85 if (data != null && data.isReadable()) {
86 diskData.addContent(data.retain(), false);
87 }
88 wrapped.release();
89 wrapped = diskData;
90 }
91 } catch (IOException e) {
92 buffer.release();
93 throw e;
94 }
95 }
96 wrapped.addContent(buffer, last);
97 }
98
99 @Override
100 protected void deallocate() {
101 delete();
102 }
103
104 @Override
105 public void delete() {
106 wrapped.delete();
107 }
108
109 @Override
110 public byte[] get() throws IOException {
111 return wrapped.get();
112 }
113
114 @Override
115 public ByteBuf getByteBuf() throws IOException {
116 return wrapped.getByteBuf();
117 }
118
119 @Override
120 public String getString() throws IOException {
121 return wrapped.getString();
122 }
123
124 @Override
125 public String getString(Charset encoding) throws IOException {
126 return wrapped.getString(encoding);
127 }
128
129 @Override
130 public boolean isInMemory() {
131 return wrapped.isInMemory();
132 }
133
134 @Override
135 public long length() {
136 return wrapped.length();
137 }
138
139 @Override
140 public boolean renameTo(File dest) throws IOException {
141 return wrapped.renameTo(dest);
142 }
143
144 @Override
145 public void setCharset(Charset charset) {
146 wrapped.setCharset(charset);
147 }
148
149 @Override
150 public void setContent(ByteBuf buffer) throws IOException {
151 try {
152 checkSize(buffer.readableBytes());
153 } catch (IOException e) {
154 buffer.release();
155 throw e;
156 }
157 if (buffer.readableBytes() > limitSize) {
158 if (wrapped instanceof AbstractMemoryHttpData) {
159
160 wrapped.release();
161 wrapped = makeDiskData();
162 }
163 }
164 wrapped.setContent(buffer);
165 }
166
167 @Override
168 public void setContent(File file) throws IOException {
169 checkSize(file.length());
170 if (file.length() > limitSize) {
171 if (wrapped instanceof AbstractMemoryHttpData) {
172
173 wrapped.release();
174 wrapped = makeDiskData();
175 }
176 }
177 wrapped.setContent(file);
178 }
179
180 @Override
181 public void setContent(InputStream inputStream) throws IOException {
182 if (wrapped instanceof AbstractMemoryHttpData) {
183
184 wrapped.release();
185 wrapped = makeDiskData();
186 }
187 wrapped.setContent(inputStream);
188 }
189
190 @Override
191 public boolean isCompleted() {
192 return wrapped.isCompleted();
193 }
194
195 @Override
196 public HttpDataType getHttpDataType() {
197 return wrapped.getHttpDataType();
198 }
199
200 @Override
201 public int hashCode() {
202 return wrapped.hashCode();
203 }
204
205 @Override
206 public boolean equals(Object obj) {
207 return wrapped.equals(obj);
208 }
209
210 @Override
211 public int compareTo(InterfaceHttpData o) {
212 return wrapped.compareTo(o);
213 }
214
215 @Override
216 public String toString() {
217 return "Mixed: " + wrapped;
218 }
219
220 @Override
221 public ByteBuf getChunk(int length) throws IOException {
222 return wrapped.getChunk(length);
223 }
224
225 @Override
226 public File getFile() throws IOException {
227 return wrapped.getFile();
228 }
229
230 @SuppressWarnings("unchecked")
231 @Override
232 public D copy() {
233 return (D) wrapped.copy();
234 }
235
236 @SuppressWarnings("unchecked")
237 @Override
238 public D duplicate() {
239 return (D) wrapped.duplicate();
240 }
241
242 @SuppressWarnings("unchecked")
243 @Override
244 public D retainedDuplicate() {
245 return (D) wrapped.retainedDuplicate();
246 }
247
248 @SuppressWarnings("unchecked")
249 @Override
250 public D replace(ByteBuf content) {
251 return (D) wrapped.replace(content);
252 }
253
254 @SuppressWarnings("unchecked")
255 @Override
256 public D touch() {
257 wrapped.touch();
258 return (D) this;
259 }
260
261 @SuppressWarnings("unchecked")
262 @Override
263 public D touch(Object hint) {
264 wrapped.touch(hint);
265 return (D) this;
266 }
267
268 @SuppressWarnings("unchecked")
269 @Override
270 public D retain() {
271 return (D) super.retain();
272 }
273
274 @SuppressWarnings("unchecked")
275 @Override
276 public D retain(int increment) {
277 return (D) super.retain(increment);
278 }
279 }