001 package railo.runtime.net.http; 002 003 import java.io.ByteArrayInputStream; 004 import java.io.ByteArrayOutputStream; 005 import java.io.IOException; 006 import java.io.UnsupportedEncodingException; 007 import java.util.Arrays; 008 009 import org.apache.commons.fileupload.MultipartStream; 010 import org.apache.commons.lang.StringUtils; 011 012 import railo.commons.io.IOUtil; 013 import railo.commons.lang.StringUtil; 014 import railo.runtime.exp.PageException; 015 import railo.runtime.type.Array; 016 import railo.runtime.type.ArrayImpl; 017 import railo.runtime.type.Struct; 018 import railo.runtime.type.StructImpl; 019 import railo.runtime.type.util.KeyConstants; 020 import railo.runtime.type.util.ListUtil; 021 022 023 public class MultiPartResponseUtils { 024 025 public static boolean isMultipart(String mimetype) { 026 return !StringUtil.isEmpty(extractBoundary(mimetype,null)) 027 && StringUtil.startsWithIgnoreCase(mimetype, "multipart/"); 028 } 029 030 public static Array getParts(byte[] barr,String contentTypeHeader) throws IOException, PageException { 031 String boundary = extractBoundary(contentTypeHeader,""); 032 ByteArrayInputStream bis = new ByteArrayInputStream(barr); 033 MultipartStream stream; 034 Array result = new ArrayImpl(); 035 stream = new MultipartStream(bis,getBytes(boundary,"UTF-8"));// 036 037 boolean hasNextPart = stream.skipPreamble(); 038 while (hasNextPart) { 039 result.append(getPartData(stream)); 040 hasNextPart = stream.readBoundary(); 041 } 042 return result; 043 } 044 045 private static String extractBoundary(String contentTypeHeader, String defaultValue) { 046 if (contentTypeHeader == null) return defaultValue; 047 String[] headerSections = ListUtil.listToStringArray(contentTypeHeader, ';'); 048 for (String section: headerSections) { 049 String[] subHeaderSections = ListUtil.listToStringArray(section,'='); 050 String headerName = subHeaderSections[0].trim(); 051 if (headerName.toLowerCase().equals("boundary")) { 052 return subHeaderSections[1]; 053 } 054 055 } 056 return defaultValue; 057 } 058 059 private static Struct getPartData(MultipartStream stream) throws IOException, PageException { 060 Struct headers = extractHeaders(stream.readHeaders()); 061 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 062 stream.readBodyData(baos); 063 Struct fileStruct = new StructImpl(); 064 fileStruct.set(KeyConstants._content, baos.toByteArray()); 065 fileStruct.set(KeyConstants._headers, headers); 066 IOUtil.closeEL(baos); 067 return fileStruct; 068 } 069 070 private static Struct extractHeaders(String rawHeaders) throws PageException { 071 Struct result = new StructImpl(); 072 String[] headers = ListUtil.listToStringArray(rawHeaders,'\n'); 073 for(String rawHeader :headers) { 074 String[] headerArray = ListUtil.listToStringArray(rawHeader,':'); 075 String headerName = headerArray[0]; 076 if (!StringUtil.isEmpty(headerName,true)) { 077 String value = StringUtils.join(Arrays.copyOfRange(headerArray, 1, headerArray.length),":").trim(); 078 result.set(headerName, value); 079 } 080 } 081 return result; 082 } 083 084 private static byte[] getBytes(String string, String charset) { 085 byte[] bytes; 086 try { 087 bytes = string.getBytes(charset); 088 } catch (UnsupportedEncodingException e) { 089 bytes = string.getBytes(); 090 } 091 return bytes; 092 } 093 094 095 }