001 package org.apache.myfaces.tobago.webapp; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one or more 005 * contributor license agreements. See the NOTICE file distributed with 006 * this work for additional information regarding copyright ownership. 007 * The ASF licenses this file to You under the Apache License, Version 2.0 008 * (the "License"); you may not use this file except in compliance with 009 * the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019 020 import org.apache.commons.fileupload.DiskFileUpload; 021 import org.apache.commons.fileupload.FileItem; 022 import org.apache.commons.fileupload.FileUploadException; 023 import org.apache.commons.logging.Log; 024 import org.apache.commons.logging.LogFactory; 025 import static org.apache.myfaces.tobago.TobagoConstants.FORM_ACCEPT_CHARSET; 026 027 import javax.faces.FacesException; 028 import javax.servlet.http.HttpServletRequest; 029 import javax.servlet.http.HttpServletRequestWrapper; 030 import java.io.UnsupportedEncodingException; 031 import java.util.Collections; 032 import java.util.Enumeration; 033 import java.util.HashMap; 034 import java.util.Iterator; 035 import java.util.List; 036 import java.util.Map; 037 import java.util.Locale; 038 039 public class TobagoMultipartFormdataRequest extends HttpServletRequestWrapper { 040 041 private static final Log LOG 042 = LogFactory.getLog(TobagoMultipartFormdataRequest.class); 043 044 public static final long ONE_KB = 1024; 045 public static final long ONE_MB = ONE_KB * ONE_KB; 046 public static final long ONE_GB = ONE_KB * ONE_MB; 047 048 private Map parameters; 049 050 private Map fileItems; 051 052 053 054 public TobagoMultipartFormdataRequest(HttpServletRequest request) { 055 this(request, System.getProperty("java.io.tmpdir"), ONE_MB); 056 } 057 058 public TobagoMultipartFormdataRequest(HttpServletRequest request, String repositoryPath, long maxSize) { 059 super(request); 060 init(request, repositoryPath, maxSize); 061 } 062 063 private void init(HttpServletRequest request, String repositoryPath, long maxSize) { 064 String contentType = request.getContentType(); 065 if (contentType == null 066 || !contentType.toLowerCase(Locale.ENGLISH).startsWith("multipart/form-data")) { 067 String errorText = "contentType is not multipart/form-data but '" 068 + contentType + "'"; 069 LOG.error(errorText); 070 throw new FacesException(errorText); 071 } else { 072 parameters = new HashMap(); 073 fileItems = new HashMap(); 074 DiskFileUpload fileUpload = new DiskFileUpload(); 075 fileUpload.setSizeMax(maxSize); 076 fileUpload.setRepositoryPath(repositoryPath); 077 List itemList; 078 try { 079 itemList = fileUpload.parseRequest(request); 080 } catch (FileUploadException e) { 081 //LOG.error(e); 082 throw new FacesException(e); 083 } 084 if (LOG.isDebugEnabled()) { 085 LOG.debug("parametercount = " + itemList.size()); 086 } 087 Iterator items = itemList.iterator(); 088 while (items.hasNext()) { 089 FileItem item = (FileItem) items.next(); 090 String key = item.getFieldName(); 091 if (LOG.isDebugEnabled()) { 092 String value = item.getString(); 093 if (value.length() > 100) { 094 value = value.substring(0, 100) + " [...]"; 095 } 096 LOG.debug( 097 "Parameter : '" + key + "'='" + value + "' isFormField=" 098 + item.isFormField() + " contentType='" + item.getContentType() + "'"); 099 100 } 101 if (item.isFormField()) { 102 Object inStock = parameters.get(key); 103 if (inStock == null) { 104 String[] values; 105 try { 106 // TODO: enable configuration of 'accept-charset' 107 values = new String[] {item.getString(FORM_ACCEPT_CHARSET)}; 108 } catch (UnsupportedEncodingException e) { 109 LOG.error("Catched: " + e.getMessage(), e); 110 values = new String[] {item.getString()}; 111 } 112 parameters.put(key, values); 113 } else if (inStock instanceof String[]) { // double (or more) parameter 114 String[] oldValues = (String[]) inStock; 115 String[] values = new String[oldValues.length + 1]; 116 int i = 0; 117 for (; i < oldValues.length; i++) { 118 values[i] = oldValues[i]; 119 } 120 try { 121 // TODO: enable configuration of 'accept-charset' 122 values[i] = item.getString(FORM_ACCEPT_CHARSET); 123 } catch (UnsupportedEncodingException e) { 124 LOG.error("Catched: " + e.getMessage(), e); 125 values[i] = item.getString(); 126 } 127 parameters.put(key, values); 128 } else { 129 LOG.error( 130 "Program error. Unsupported class: " 131 + inStock.getClass().getName()); 132 } 133 } else { 134 fileItems.put(key, item); 135 } 136 } 137 } 138 } 139 140 public FileItem getFileItem(String key) { 141 if (fileItems != null) { 142 return (FileItem) fileItems.get(key); 143 } 144 return null; 145 } 146 147 public String getParameter(String key) { 148 String parameter = null; 149 String[] values = (String[]) parameters.get(key); 150 if (values != null) { 151 parameter = values[0]; 152 } 153 return parameter; 154 } 155 156 public Enumeration getParameterNames() { 157 return Collections.enumeration(parameters.keySet()); 158 } 159 160 public String[] getParameterValues(String key) { 161 return (String[]) parameters.get(key); 162 } 163 164 public Map getParameterMap() { 165 return parameters; 166 } 167 168 public static long getMaxSize(String param) { 169 if (param != null) { 170 String number = param.toLowerCase(Locale.ENGLISH); 171 long factor = 1; 172 if (number.endsWith("g")) { 173 factor = ONE_GB; 174 number = number.substring(0, number.length() - 1); 175 } else if (number.endsWith("m")) { 176 factor = ONE_MB; 177 number = number.substring(0, number.length() - 1); 178 } else if (number.endsWith("k")) { 179 factor = ONE_KB; 180 number = number.substring(0, number.length() - 1); 181 } 182 try { 183 return Long.parseLong(number.trim()) * factor; 184 } catch (NumberFormatException e) { 185 LOG.error("Given max file size for " 186 + TobagoMultipartFormdataRequest.class.getName() + " " +param + " couldn't parsed to a number"); 187 } 188 } 189 return ONE_MB; 190 } 191 }