1 36 package org.columba.ristretto.parser; 37 38 import java.io.IOException ; 39 import java.util.Iterator ; 40 import java.util.List ; 41 import java.util.regex.Matcher ; 42 import java.util.regex.Pattern ; 43 44 import org.columba.ristretto.io.Source; 45 import org.columba.ristretto.message.Header; 46 import org.columba.ristretto.message.LocalMimePart; 47 import org.columba.ristretto.message.MimeHeader; 48 import org.columba.ristretto.message.MimeType; 49 50 55 public class BodyParser { 56 57 private static final Pattern headerEndPattern = Pattern.compile("\r\n\r\n"); 58 59 private static final Pattern lineEndPattern = Pattern 60 .compile("\r?\n|\r\n?"); 61 62 private BodyParser() { 63 } 64 65 73 public static void skipHeader(Source source) throws IOException { 74 Matcher matcher = headerEndPattern.matcher(source); 75 if (matcher.find()) { 76 source.seek(matcher.end()); 77 } 78 } 79 80 101 public static LocalMimePart parseMimePart(MimeHeader header, Source message) 102 throws IOException , ParserException { 103 104 boolean endBoundaryFound = false; 105 106 MimeType type = header.getMimeType(); 107 if (!type.getType().equals("multipart")) { 109 return new LocalMimePart(header, message.fromActualPosition()); 110 } 111 112 LocalMimePart multipart = new LocalMimePart(header, message 115 .fromActualPosition()); 116 String boundary = header.getContentParameter("boundary"); 117 if (boundary == null) 118 throw new ParserException( 119 "Content-Type is multipart, but no boundary specified!"); 120 121 CharSequenceSearcher boundarySearcher = new CharSequenceSearcher("--" 122 + boundary); 123 List foundBoundaries = boundarySearcher.match(message); 124 125 Iterator it = foundBoundaries.iterator(); 127 while (it.hasNext()) { 128 char suffix = message.charAt(((Integer ) it.next()).intValue() 129 + boundary.length() + 2); 130 if (suffix != '\r' && suffix != '\n' && suffix != '-') { 131 it.remove(); 132 } 133 } 134 135 if (foundBoundaries.size() == 0) { 137 throw new ParserException("No startboundary found: " + boundary, 138 message); 139 } 140 141 it = foundBoundaries.iterator(); 142 143 int boundaryStart, boundaryEnd; 144 145 int start = ((Integer ) it.next()).intValue() + boundary.length() + 2; 146 147 switch (message.charAt(start)) { 149 case '\r': { 150 start++; 151 if (message.charAt(start) == '\n') { 152 start++; 153 } 154 break; 155 } 156 157 case '\n': { 158 start++; 159 break; 160 } 161 } 162 163 while (it.hasNext()) { 165 boundaryStart = ((Integer ) it.next()).intValue(); 166 boundaryEnd = boundaryStart + boundary.length() + 2; 168 switch (message.charAt(boundaryStart - 1)) { 170 case '\n': { 171 boundaryStart--; 172 if (message.charAt(boundaryStart) == '\n') { 173 boundaryStart--; 174 } 175 break; 176 } 177 178 case '\r': { 179 boundaryStart--; 180 } 181 } 182 183 switch (message.charAt(boundaryEnd)) { 185 case '-': { 186 boundaryEnd += 4; 189 endBoundaryFound = true; 190 break; 191 } 192 193 case '\r': { 194 boundaryEnd++; 195 if (message.length() > boundaryEnd 196 && message.charAt(boundaryEnd) == '\n') { 197 boundaryEnd++; 198 } 199 break; 200 } 201 202 case '\n': { 203 boundaryEnd++; 204 break; 205 } 206 207 } 208 209 Source subSource = message.subSource(start, boundaryStart); 211 212 Header subHeader = HeaderParser.parse(subSource); 214 215 LocalMimePart subPart = BodyParser.parseMimePart(new MimeHeader( 217 subHeader), subSource); 218 219 subPart.setSource(subSource); 221 multipart.addChild(subPart); 222 start = boundaryEnd; 223 } 224 225 int end; 226 if (!endBoundaryFound) { 227 end = message.length(); 229 230 Source subSource = message.subSource(start, end); 232 233 Header subHeader = HeaderParser.parse(subSource); 235 236 LocalMimePart subPart = BodyParser.parseMimePart(new MimeHeader( 238 subHeader), subSource); 239 240 subPart.setSource(subSource); 242 multipart.addChild(subPart); 243 } 244 245 return multipart; 246 } 247 248 }
| Popular Tags
|