1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.internal.webapp;
21
22 import org.apache.commons.fileupload.FileItem;
23 import org.apache.commons.fileupload.FileUploadException;
24 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
25 import org.apache.commons.fileupload.servlet.ServletFileUpload;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28 import org.apache.myfaces.tobago.internal.component.AbstractUIPage;
29
30 import javax.faces.FacesException;
31 import javax.servlet.http.HttpServletRequest;
32 import javax.servlet.http.HttpServletRequestWrapper;
33 import java.io.File;
34 import java.io.UnsupportedEncodingException;
35 import java.util.Arrays;
36 import java.util.Collections;
37 import java.util.Enumeration;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Locale;
41 import java.util.Map;
42
43 public class TobagoMultipartFormdataRequest extends HttpServletRequestWrapper {
44
45 private static final Logger LOG = LoggerFactory.getLogger(TobagoMultipartFormdataRequest.class);
46
47 public static final long ONE_KB = 1024;
48 public static final long ONE_MB = ONE_KB * ONE_KB;
49 public static final long ONE_GB = ONE_KB * ONE_MB;
50
51 private Map<String, String[]> parameters;
52
53 private Map<String, FileItem> fileItems;
54
55 public TobagoMultipartFormdataRequest(HttpServletRequest request) {
56 this(request, System.getProperty("java.io.tmpdir"), ONE_MB);
57 }
58
59 public TobagoMultipartFormdataRequest(HttpServletRequest request, String repositoryPath, long maxSize) {
60 super(request);
61 init(request, repositoryPath, maxSize);
62 }
63
64 private void init(HttpServletRequest request, String repositoryPath, long maxSize) {
65 if (!ServletFileUpload.isMultipartContent(request)) {
66 String errorText = "contentType is not multipart/form-data but '" + request.getContentType() + "'";
67 LOG.error(errorText);
68 throw new FacesException(errorText);
69 } else {
70 parameters = new HashMap<String, String[]>();
71 fileItems = new HashMap<String, FileItem>();
72 DiskFileItemFactory factory = new DiskFileItemFactory();
73
74 factory.setRepository(new File(repositoryPath));
75
76 ServletFileUpload upload = new ServletFileUpload(factory);
77
78 upload.setSizeMax(maxSize);
79
80 if (upload.getHeaderEncoding() != null) {
81
82 upload.setHeaderEncoding(AbstractUIPage.FORM_ACCEPT_CHARSET);
83 }
84 List<FileItem> itemList;
85 try {
86 itemList = (List<FileItem>) upload.parseRequest(request);
87 } catch (FileUploadException e) {
88
89 throw new FacesException(e);
90 }
91 if (LOG.isDebugEnabled()) {
92 LOG.debug("parametercount = " + itemList.size() + " + " + request.getParameterMap().size());
93 }
94 for (FileItem item : itemList) {
95 String key = item.getFieldName();
96 if (LOG.isDebugEnabled()) {
97 String value = item.getString();
98 if (value.length() > 100) {
99 value = value.substring(0, 100) + " [...]";
100 }
101 LOG.debug("Parameter: '" + key + "'='" + value + "' isFormField=" + item.isFormField()
102 + " contentType='" + item.getContentType() + "'");
103 }
104 if (item.isFormField()) {
105 String newValue;
106 try {
107
108 newValue = item.getString(AbstractUIPage.FORM_ACCEPT_CHARSET);
109 } catch (UnsupportedEncodingException e) {
110 LOG.error("Caught: " + e.getMessage(), e);
111 newValue = item.getString();
112 }
113
114 addParameter(key, newValue);
115 } else {
116 fileItems.put(key, item);
117 }
118 }
119
120
121 Enumeration e = request.getParameterNames();
122 while(e.hasMoreElements()) {
123 final String name = (String) e.nextElement();
124 final String[] newValues = request.getParameterValues(name);
125 if (LOG.isDebugEnabled()) {
126 LOG.debug("Parameter: '" + name + "'='" + Arrays.toString(newValues) + "' (GET)");
127 }
128 for (String newValue : newValues) {
129 addParameter(name, newValue);
130 }
131 }
132 }
133 }
134
135 private void addParameter(String key, String newValue) {
136 final String[] inStock = parameters.get(key);
137 final String[] values;
138 if (inStock == null) {
139 values = new String[]{newValue};
140 } else {
141 values = new String[inStock.length + 1];
142 System.arraycopy(inStock, 0, values, 0, inStock.length);
143 values[inStock.length] = newValue;
144 }
145 parameters.put(key, values);
146 }
147
148 public FileItem getFileItem(String key) {
149 if (fileItems != null) {
150 return fileItems.get(key);
151 }
152 return null;
153 }
154
155 public String getParameter(String key) {
156 String parameter = null;
157 String[] values = (String[]) parameters.get(key);
158 if (values != null) {
159 parameter = values[0];
160 }
161 return parameter;
162 }
163
164 public Enumeration getParameterNames() {
165 return Collections.enumeration(parameters.keySet());
166 }
167
168 public String[] getParameterValues(String key) {
169 return (String[]) parameters.get(key);
170 }
171
172 public Map getParameterMap() {
173 return parameters;
174 }
175
176 public static long getMaxSize(String param) {
177 if (param != null) {
178 String number = param.toLowerCase(Locale.ENGLISH);
179 long factor = 1;
180 if (number.endsWith("g")) {
181 factor = ONE_GB;
182 number = number.substring(0, number.length() - 1);
183 } else if (number.endsWith("m")) {
184 factor = ONE_MB;
185 number = number.substring(0, number.length() - 1);
186 } else if (number.endsWith("k")) {
187 factor = ONE_KB;
188 number = number.substring(0, number.length() - 1);
189 }
190 try {
191 return Long.parseLong(number.trim()) * factor;
192 } catch (NumberFormatException e) {
193 LOG.error("Given max file size for "
194 + TobagoMultipartFormdataRequest.class.getName() + " " + param + " couldn't parsed to a number");
195 }
196 }
197 return ONE_MB;
198 }
199 }