MultipartUtil.java
- /*
- * Copyright (c) 2002-2022, City of Paris
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice
- * and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice
- * and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * 3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * License 1.0
- */
- package fr.paris.lutece.util.http;
- import fr.paris.lutece.portal.service.html.EncodingService;
- import fr.paris.lutece.portal.service.util.AppLogService;
- import fr.paris.lutece.portal.web.upload.MultipartHttpServletRequest;
- import fr.paris.lutece.portal.web.upload.NormalizeFileItem;
- import org.apache.commons.fileupload.FileItem;
- import org.apache.commons.fileupload.FileItemIterator;
- import org.apache.commons.fileupload.FileItemStream;
- import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
- import org.apache.commons.fileupload.FileUploadException;
- import org.apache.commons.fileupload.disk.DiskFileItemFactory;
- import org.apache.commons.fileupload.servlet.ServletFileUpload;
- import org.apache.commons.lang3.StringUtils;
- import java.io.UnsupportedEncodingException;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Optional;
- import javax.servlet.http.HttpServletRequest;
- /**
- *
- * MultipartUtil
- *
- */
- public final class MultipartUtil
- {
- /**
- * Private constructor
- */
- private MultipartUtil( )
- {
- }
- /**
- * Check if the given HTTP request has multipart content
- *
- * @param request
- * the HTTP request
- * @return true if it has multipart content, false otherwise
- */
- public static boolean isMultipart( HttpServletRequest request )
- {
- return ServletFileUpload.isMultipartContent( request );
- }
- /**
- * Convert a HTTP request to a {@link MultipartHttpServletRequest}
- *
- * @param nSizeThreshold
- * the size threshold
- * @param nRequestSizeMax
- * the request size max
- * @param bActivateNormalizeFileName
- * true if the file name must be normalized, false otherwise
- * @param request
- * the HTTP request
- * @return a {@link MultipartHttpServletRequest}, null if the request does not have a multipart content
- * @throws SizeLimitExceededException
- * exception if the file size is too big
- * @throws FileUploadException
- * exception if an unknown error has occurred
- */
- public static MultipartHttpServletRequest convert( int nSizeThreshold, long nRequestSizeMax, boolean bActivateNormalizeFileName,
- HttpServletRequest request ) throws FileUploadException
- {
- if ( !isMultipart( request ) )
- {
- return null;
- }
- // Create a factory for disk-based file items
- DiskFileItemFactory factory = new DiskFileItemFactory( );
- // Set factory constraints
- factory.setSizeThreshold( nSizeThreshold );
- // Create a new file upload handler
- ServletFileUpload upload = new ServletFileUpload( factory );
- // Set overall request size constraint
- upload.setSizeMax( nRequestSizeMax );
- // get encoding to be used
- String strEncoding = Optional.ofNullable( request.getCharacterEncoding( ) ).orElse( EncodingService.getEncoding( ) );
- Map<String, List<FileItem>> mapFiles = new HashMap<>( );
- Map<String, String [ ]> mapParameters = new HashMap<>( );
- List<FileItem> listItems;
- try {
- listItems = upload.parseRequest(request);
- }
- catch( SizeLimitExceededException e )
- {
- closeInputStream( upload, request );
- throw e;
- }
- // Process the uploaded items
- for ( FileItem item : listItems )
- {
- processItem( item, strEncoding, bActivateNormalizeFileName, mapFiles, mapParameters );
- }
- return new MultipartHttpServletRequest( request, mapFiles, mapParameters );
- }
- /**
- * Close the inputStream of the request
- * @param upload
- * @param request
- */
- private static void closeInputStream( ServletFileUpload upload, HttpServletRequest request)
- {
- try {
- upload.setSizeMax(-1);
- FileItemIterator fileiterator = upload.getItemIterator(request);
- while (fileiterator.hasNext())
- {
- FileItemStream item = fileiterator.next();
- item.openStream().close();
- }
- }
- catch (Exception e)
- {
- AppLogService.error( "error occured during closing the stream" , e);
- }
- }
- private static void processItem( FileItem item, String strEncoding, boolean bActivateNormalizeFileName, Map<String, List<FileItem>> mapFiles,
- Map<String, String [ ]> mapParameters )
- {
- if ( item.isFormField( ) )
- {
- String strValue = StringUtils.EMPTY;
- if ( item.getSize( ) > 0 )
- {
- try
- {
- strValue = item.getString( strEncoding );
- }
- catch( UnsupportedEncodingException ex )
- {
- // if encoding problem, try with system encoding
- strValue = item.getString( );
- }
- }
- // check if item of same name already in map
- String [ ] curParam = mapParameters.get( item.getFieldName( ) );
- if ( curParam == null )
- {
- // simple form field
- mapParameters.put( item.getFieldName( ), new String [ ] {
- strValue
- } );
- }
- else
- {
- // array of simple form fields
- String [ ] newArray = new String [ curParam.length + 1];
- System.arraycopy( curParam, 0, newArray, 0, curParam.length );
- newArray [curParam.length] = strValue;
- mapParameters.put( item.getFieldName( ), newArray );
- }
- }
- else
- {
- // multipart file field, if the parameter filter ActivateNormalizeFileName is
- // set to true
- // all file name will be normalize
- FileItem fileItem = bActivateNormalizeFileName ? new NormalizeFileItem( item ) : item;
- List<FileItem> listFileItem = mapFiles.get( fileItem.getFieldName( ) );
- if ( listFileItem != null )
- {
- listFileItem.add( fileItem );
- }
- else
- {
- listFileItem = new ArrayList<>( 1 );
- listFileItem.add( fileItem );
- mapFiles.put( fileItem.getFieldName( ), listFileItem );
- }
- }
- }
- }