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 boolean renameTo(File dest) throws IOException {
156         return fileUpload.renameTo(dest);
157     }
158 
159     @Override
160     public void setCharset(Charset charset) {
161         fileUpload.setCharset(charset);
162     }
163 
164     @Override
165     public void setContent(ByteBuf buffer) throws IOException {
166         checkSize(buffer.readableBytes());
167         if (buffer.readableBytes() > limitSize) {
168             if (fileUpload instanceof MemoryFileUpload) {
169                 FileUpload memoryUpload = fileUpload;
170                 // change to Disk
171                 fileUpload = new DiskFileUpload(memoryUpload
172                         .getName(), memoryUpload.getFilename(), memoryUpload
173                         .getContentType(), memoryUpload
174                         .getContentTransferEncoding(), memoryUpload.getCharset(),
175                         definedSize);
176                 fileUpload.setMaxSize(maxSize);
177 
178                 // release old upload
179                 memoryUpload.release();
180             }
181         }
182         fileUpload.setContent(buffer);
183     }
184 
185     @Override
186     public void setContent(File file) throws IOException {
187         checkSize(file.length());
188         if (file.length() > limitSize) {
189             if (fileUpload instanceof MemoryFileUpload) {
190                 FileUpload memoryUpload = fileUpload;
191 
192                 // change to Disk
193                 fileUpload = new DiskFileUpload(memoryUpload
194                         .getName(), memoryUpload.getFilename(), memoryUpload
195                         .getContentType(), memoryUpload
196                         .getContentTransferEncoding(), memoryUpload.getCharset(),
197                         definedSize);
198                 fileUpload.setMaxSize(maxSize);
199 
200                 // release old upload
201                 memoryUpload.release();
202             }
203         }
204         fileUpload.setContent(file);
205     }
206 
207     @Override
208     public void setContent(InputStream inputStream) throws IOException {
209         if (fileUpload instanceof MemoryFileUpload) {
210             FileUpload memoryUpload = fileUpload;
211 
212             // change to Disk
213             fileUpload = new DiskFileUpload(fileUpload
214                     .getName(), fileUpload.getFilename(), fileUpload
215                     .getContentType(), fileUpload
216                     .getContentTransferEncoding(), fileUpload.getCharset(),
217                     definedSize);
218             fileUpload.setMaxSize(maxSize);
219 
220             // release old upload
221             memoryUpload.release();
222         }
223         fileUpload.setContent(inputStream);
224     }
225 
226     @Override
227     public void setContentType(String contentType) {
228         fileUpload.setContentType(contentType);
229     }
230 
231     @Override
232     public void setContentTransferEncoding(String contentTransferEncoding) {
233         fileUpload.setContentTransferEncoding(contentTransferEncoding);
234     }
235 
236     @Override
237     public void setFilename(String filename) {
238         fileUpload.setFilename(filename);
239     }
240 
241     @Override
242     public HttpDataType getHttpDataType() {
243         return fileUpload.getHttpDataType();
244     }
245 
246     @Override
247     public String getName() {
248         return fileUpload.getName();
249     }
250 
251     @Override
252     public int hashCode() {
253         return fileUpload.hashCode();
254     }
255 
256     @Override
257     public boolean equals(Object obj) {
258         return fileUpload.equals(obj);
259     }
260 
261     @Override
262     public int compareTo(InterfaceHttpData o) {
263         return fileUpload.compareTo(o);
264     }
265 
266     @Override
267     public String toString() {
268         return "Mixed: " + fileUpload;
269     }
270 
271     @Override
272     public ByteBuf getChunk(int length) throws IOException {
273         return fileUpload.getChunk(length);
274     }
275 
276     @Override
277     public File getFile() throws IOException {
278         return fileUpload.getFile();
279     }
280 
281     @Override
282     public FileUpload copy() {
283         return fileUpload.copy();
284     }
285 
286     @Override
287     public FileUpload duplicate() {
288         return fileUpload.duplicate();
289     }
290 
291     @Override
292     public ByteBuf content() {
293         return fileUpload.content();
294     }
295 
296     @Override
297     public int refCnt() {
298         return fileUpload.refCnt();
299     }
300 
301     @Override
302     public FileUpload retain() {
303         fileUpload.retain();
304         return this;
305     }
306 
307     @Override
308     public FileUpload retain(int increment) {
309         fileUpload.retain(increment);
310         return this;
311     }
312 
313     @Override
314     public FileUpload touch() {
315         fileUpload.touch();
316         return this;
317     }
318 
319     @Override
320     public FileUpload touch(Object hint) {
321         fileUpload.touch(hint);
322         return this;
323     }
324 
325     @Override
326     public boolean release() {
327         return fileUpload.release();
328     }
329 
330     @Override
331     public boolean release(int decrement) {
332         return fileUpload.release(decrement);
333     }
334 }