View Javadoc
1   /*
2    * Copyright 2012 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.handler.codec.http.multipart;
17  
18  import io.netty.buffer.ByteBuf;
19  
20  import java.io.File;
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.nio.charset.Charset;
24  
25  /**
26   * Mixed implementation using both in Memory and in File with a limit of size
27   */
28  public class MixedFileUpload implements FileUpload {
29  
30      private FileUpload fileUpload;
31  
32      private final long limitSize;
33  
34      private final long definedSize;
35      private long maxSize = DefaultHttpDataFactory.MAXSIZE;
36  
37      public MixedFileUpload(String name, String filename, String contentType,
38              String contentTransferEncoding, Charset charset, long size,
39              long limitSize) {
40          this.limitSize = limitSize;
41          if (size > this.limitSize) {
42              fileUpload = new DiskFileUpload(name, filename, contentType,
43                      contentTransferEncoding, charset, size);
44          } else {
45              fileUpload = new MemoryFileUpload(name, filename, contentType,
46                      contentTransferEncoding, charset, size);
47          }
48          definedSize = size;
49      }
50  
51      @Override
52      public long getMaxSize() {
53          return maxSize;
54      }
55  
56      @Override
57      public void setMaxSize(long maxSize) {
58          this.maxSize = maxSize;
59          fileUpload.setMaxSize(maxSize);
60      }
61  
62      @Override
63      public void checkSize(long newSize) throws IOException {
64          if (maxSize >= 0 && newSize > maxSize) {
65              throw new IOException("Size exceed allowed maximum capacity");
66          }
67      }
68  
69      @Override
70      public void addContent(ByteBuf buffer, boolean last)
71              throws IOException {
72          if (fileUpload instanceof MemoryFileUpload) {
73              checkSize(fileUpload.length() + buffer.readableBytes());
74              if (fileUpload.length() + buffer.readableBytes() > limitSize) {
75                  DiskFileUpload diskFileUpload = new DiskFileUpload(fileUpload
76                          .getName(), fileUpload.getFilename(), fileUpload
77                          .getContentType(), fileUpload
78                          .getContentTransferEncoding(), fileUpload.getCharset(),
79                          definedSize);
80                  diskFileUpload.setMaxSize(maxSize);
81                  ByteBuf data = fileUpload.getByteBuf();
82                  if (data != null && data.isReadable()) {
83                      diskFileUpload.addContent(data.retain(), false);
84                  }
85                  // release old upload
86                  fileUpload.release();
87  
88                  fileUpload = diskFileUpload;
89              }
90          }
91          fileUpload.addContent(buffer, last);
92      }
93  
94      @Override
95      public void delete() {
96          fileUpload.delete();
97      }
98  
99      @Override
100     public byte[] get() throws IOException {
101         return fileUpload.get();
102     }
103 
104     @Override
105     public ByteBuf getByteBuf() throws IOException {
106         return fileUpload.getByteBuf();
107     }
108 
109     @Override
110     public Charset getCharset() {
111         return fileUpload.getCharset();
112     }
113 
114     @Override
115     public String getContentType() {
116         return fileUpload.getContentType();
117     }
118 
119     @Override
120     public String getContentTransferEncoding() {
121         return fileUpload.getContentTransferEncoding();
122     }
123 
124     @Override
125     public String getFilename() {
126         return fileUpload.getFilename();
127     }
128 
129     @Override
130     public String getString() throws IOException {
131         return fileUpload.getString();
132     }
133 
134     @Override
135     public String getString(Charset encoding) throws IOException {
136         return fileUpload.getString(encoding);
137     }
138 
139     @Override
140     public boolean isCompleted() {
141         return fileUpload.isCompleted();
142     }
143 
144     @Override
145     public boolean isInMemory() {
146         return fileUpload.isInMemory();
147     }
148 
149     @Override
150     public long length() {
151         return fileUpload.length();
152     }
153 
154     @Override
155     public long definedLength() {
156         return fileUpload.definedLength();
157     }
158 
159     @Override
160     public boolean renameTo(File dest) throws IOException {
161         return fileUpload.renameTo(dest);
162     }
163 
164     @Override
165     public void setCharset(Charset charset) {
166         fileUpload.setCharset(charset);
167     }
168 
169     @Override
170     public void setContent(ByteBuf buffer) throws IOException {
171         checkSize(buffer.readableBytes());
172         if (buffer.readableBytes() > limitSize) {
173             if (fileUpload instanceof MemoryFileUpload) {
174                 FileUpload memoryUpload = fileUpload;
175                 // change to Disk
176                 fileUpload = new DiskFileUpload(memoryUpload
177                         .getName(), memoryUpload.getFilename(), memoryUpload
178                         .getContentType(), memoryUpload
179                         .getContentTransferEncoding(), memoryUpload.getCharset(),
180                         definedSize);
181                 fileUpload.setMaxSize(maxSize);
182 
183                 // release old upload
184                 memoryUpload.release();
185             }
186         }
187         fileUpload.setContent(buffer);
188     }
189 
190     @Override
191     public void setContent(File file) throws IOException {
192         checkSize(file.length());
193         if (file.length() > limitSize) {
194             if (fileUpload instanceof MemoryFileUpload) {
195                 FileUpload memoryUpload = fileUpload;
196 
197                 // change to Disk
198                 fileUpload = new DiskFileUpload(memoryUpload
199                         .getName(), memoryUpload.getFilename(), memoryUpload
200                         .getContentType(), memoryUpload
201                         .getContentTransferEncoding(), memoryUpload.getCharset(),
202                         definedSize);
203                 fileUpload.setMaxSize(maxSize);
204 
205                 // release old upload
206                 memoryUpload.release();
207             }
208         }
209         fileUpload.setContent(file);
210     }
211 
212     @Override
213     public void setContent(InputStream inputStream) throws IOException {
214         if (fileUpload instanceof MemoryFileUpload) {
215             FileUpload memoryUpload = fileUpload;
216 
217             // change to Disk
218             fileUpload = new DiskFileUpload(fileUpload
219                     .getName(), fileUpload.getFilename(), fileUpload
220                     .getContentType(), fileUpload
221                     .getContentTransferEncoding(), fileUpload.getCharset(),
222                     definedSize);
223             fileUpload.setMaxSize(maxSize);
224 
225             // release old upload
226             memoryUpload.release();
227         }
228         fileUpload.setContent(inputStream);
229     }
230 
231     @Override
232     public void setContentType(String contentType) {
233         fileUpload.setContentType(contentType);
234     }
235 
236     @Override
237     public void setContentTransferEncoding(String contentTransferEncoding) {
238         fileUpload.setContentTransferEncoding(contentTransferEncoding);
239     }
240 
241     @Override
242     public void setFilename(String filename) {
243         fileUpload.setFilename(filename);
244     }
245 
246     @Override
247     public HttpDataType getHttpDataType() {
248         return fileUpload.getHttpDataType();
249     }
250 
251     @Override
252     public String getName() {
253         return fileUpload.getName();
254     }
255 
256     @Override
257     public int hashCode() {
258         return fileUpload.hashCode();
259     }
260 
261     @Override
262     public boolean equals(Object obj) {
263         return fileUpload.equals(obj);
264     }
265 
266     @Override
267     public int compareTo(InterfaceHttpData o) {
268         return fileUpload.compareTo(o);
269     }
270 
271     @Override
272     public String toString() {
273         return "Mixed: " + fileUpload;
274     }
275 
276     @Override
277     public ByteBuf getChunk(int length) throws IOException {
278         return fileUpload.getChunk(length);
279     }
280 
281     @Override
282     public File getFile() throws IOException {
283         return fileUpload.getFile();
284     }
285 
286     @Override
287     public FileUpload copy() {
288         return fileUpload.copy();
289     }
290 
291     @Override
292     public FileUpload duplicate() {
293         return fileUpload.duplicate();
294     }
295 
296     @Override
297     public FileUpload retainedDuplicate() {
298         return fileUpload.retainedDuplicate();
299     }
300 
301     @Override
302     public FileUpload replace(ByteBuf content) {
303         return fileUpload.replace(content);
304     }
305 
306     @Override
307     public ByteBuf content() {
308         return fileUpload.content();
309     }
310 
311     @Override
312     public int refCnt() {
313         return fileUpload.refCnt();
314     }
315 
316     @Override
317     public FileUpload retain() {
318         fileUpload.retain();
319         return this;
320     }
321 
322     @Override
323     public FileUpload retain(int increment) {
324         fileUpload.retain(increment);
325         return this;
326     }
327 
328     @Override
329     public FileUpload touch() {
330         fileUpload.touch();
331         return this;
332     }
333 
334     @Override
335     public FileUpload touch(Object hint) {
336         fileUpload.touch(hint);
337         return this;
338     }
339 
340     @Override
341     public boolean release() {
342         return fileUpload.release();
343     }
344 
345     @Override
346     public boolean release(int decrement) {
347         return fileUpload.release(decrement);
348     }
349 }