View Javadoc

1   /*
2    * Copyright 2009 Red Hat, Inc.
3    *
4    * Red Hat licenses this file to you under the Apache License, version 2.0
5    * (the "License"); you may not use this file except in compliance with the
6    * 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 org.jboss.netty.handler.codec.http2;
17  
18  import java.io.IOException;
19  import java.nio.charset.Charset;
20  import java.util.ArrayList;
21  import java.util.List;
22  import java.util.concurrent.ConcurrentHashMap;
23  
24  /**
25   * Default factory giving Attribute and FileUpload according to constructor
26   *
27   * Attribute and FileUpload could be :<br>
28   * - MemoryAttribute, DiskAttribute or MixedAttribute<br>
29   * - MemoryFileUpload, DiskFileUpload or MixedFileUpload<br>
30   * according to the constructor.
31   *
32   * @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
33   * @author Andy Taylor (andy.taylor@jboss.org)
34   * @author <a href="http://gleamynode.net/">Trustin Lee</a>
35   * @author <a href="http://openr66.free.fr/">Frederic Bregier</a>
36   *
37   */
38  public class DefaultHttpDataFactory implements HttpDataFactory {
39      /**
40       * Proposed default MINSIZE as 16 KB.
41       */
42      public static long MINSIZE = 0x4000;
43  
44      private boolean useDisk = false;
45  
46      private boolean checkSize = false;
47  
48      private long minSize = 0L;
49  
50      /**
51       * Keep all HttpDatas until cleanAllHttpDatas() is called.
52       */
53      private final ConcurrentHashMap<HttpRequest, List<HttpData>> requestFileDeleteMap =
54      	new ConcurrentHashMap<HttpRequest, List<HttpData>>();
55      /**
56       * HttpData will be in memory if less than default size (16KB).
57       * The type will be Mixed.
58       */
59      public DefaultHttpDataFactory() {
60          useDisk = false;
61          checkSize = true;
62          this.minSize = MINSIZE;
63      }
64  
65      /**
66       * HttpData will be always on Disk if useDisk is True, else always in Memory if False
67       * @param useDisk
68       */
69      public DefaultHttpDataFactory(boolean useDisk) {
70          this.useDisk = useDisk;
71          checkSize = false;
72      }
73  
74      /**
75       * HttpData will be on Disk if the size of the file is greater than minSize, else it
76       * will be in memory. The type will be Mixed.
77       * @param minSize
78       */
79      public DefaultHttpDataFactory(long minSize) {
80          useDisk = false;
81          checkSize = true;
82          this.minSize = minSize;
83      }
84  
85      /**
86       * 
87       * @param request
88       * @return the associated list of Files for the request
89       */
90      private List<HttpData> getList(HttpRequest request) {
91      	List<HttpData> list = requestFileDeleteMap.get(request);
92          if (list == null) {
93          	list = new ArrayList<HttpData>();
94          	requestFileDeleteMap.put(request, list);
95          }
96          return list;
97      }
98      
99      public Attribute createAttribute(HttpRequest request, String name) throws NullPointerException,
100             IllegalArgumentException {
101         if (useDisk) {
102             Attribute attribute = new DiskAttribute(name);
103             List<HttpData> fileToDelete = getList(request);
104             fileToDelete.add(attribute);
105             return attribute;
106         } else if (checkSize) {
107             Attribute attribute = new MixedAttribute(name, minSize);
108             List<HttpData> fileToDelete = getList(request);
109             fileToDelete.add(attribute);
110             return attribute;
111         }
112         return new MemoryAttribute(name);
113     }
114 
115     /* (non-Javadoc)
116      * @see org.jboss.netty.handler.codec.http2.HttpDataFactory#createAttribute(java.lang.String, java.lang.String)
117      */
118     public Attribute createAttribute(HttpRequest request, String name, String value)
119             throws NullPointerException, IllegalArgumentException {
120         if (useDisk) {
121             Attribute attribute;
122             try {
123                 attribute = new DiskAttribute(name, value);
124             } catch (IOException e) {
125                 // revert to Mixed mode
126                 attribute = new MixedAttribute(name, value, minSize);
127             }
128             List<HttpData> fileToDelete = getList(request);
129             fileToDelete.add(attribute);
130             return attribute;
131         } else if (checkSize) {
132             Attribute attribute = new MixedAttribute(name, value, minSize);
133             List<HttpData> fileToDelete = getList(request);
134             fileToDelete.add(attribute);
135             return attribute;
136         }
137         try {
138             return new MemoryAttribute(name, value);
139         } catch (IOException e) {
140             throw new IllegalArgumentException(e);
141         }
142     }
143 
144     /* (non-Javadoc)
145      * @see org.jboss.netty.handler.codec.http2.HttpDataFactory#createFileUpload(java.lang.String, java.lang.String, java.lang.String)
146      */
147     public FileUpload createFileUpload(HttpRequest request, String name, String filename,
148             String contentType, String contentTransferEncoding, Charset charset,
149             long size) throws NullPointerException, IllegalArgumentException {
150         if (useDisk) {
151             FileUpload fileUpload = new DiskFileUpload(name, filename, contentType,
152                     contentTransferEncoding, charset, size);
153             List<HttpData> fileToDelete = getList(request);
154             fileToDelete.add(fileUpload);
155             return fileUpload;
156         } else if (checkSize) {
157             FileUpload fileUpload = new MixedFileUpload(name, filename, contentType,
158                     contentTransferEncoding, charset, size, minSize);
159             List<HttpData> fileToDelete = getList(request);
160             fileToDelete.add(fileUpload);
161             return fileUpload;
162         }
163         return new MemoryFileUpload(name, filename, contentType,
164                 contentTransferEncoding, charset, size);
165     }
166 
167     public void removeHttpDataFromClean(HttpRequest request, InterfaceHttpData data) {
168         if (data instanceof HttpData) {
169         	List<HttpData> fileToDelete = getList(request);
170             fileToDelete.remove(data);
171         }
172     }
173 
174     public void cleanRequestHttpDatas(HttpRequest request) {
175     	List<HttpData> fileToDelete = requestFileDeleteMap.remove(request);
176     	if (fileToDelete != null) {
177 	        for (HttpData data: fileToDelete) {
178 	            data.delete();
179 	        }
180 	        fileToDelete.clear();
181     	}
182     }
183 
184     public void cleanAllHttpDatas() {
185     	for (HttpRequest request : requestFileDeleteMap.keySet()) {
186     		List<HttpData> fileToDelete = requestFileDeleteMap.get(request);
187         	if (fileToDelete != null) {
188     	        for (HttpData data: fileToDelete) {
189     	            data.delete();
190     	        }
191     	        fileToDelete.clear();
192         	}
193         	requestFileDeleteMap.remove(request);
194     	}
195     }
196 }