1 64 65 package com.jcorporate.expresso.core.misc.upload; 66 67 import com.jcorporate.expresso.core.controller.ControllerException; 68 import com.jcorporate.expresso.core.db.DBException; 69 import com.jcorporate.expresso.core.misc.StringUtil; 70 import com.jcorporate.expresso.services.dbobj.Setup; 71 import org.apache.log4j.Logger; 72 import org.apache.struts.action.ActionMapping; 73 import org.apache.struts.action.ActionServlet; 74 import org.apache.struts.upload.MultipartRequestHandler; 75 76 import javax.servlet.ServletException ; 77 import javax.servlet.http.HttpServletRequest ; 78 import java.io.IOException ; 79 import java.io.InputStream ; 80 import java.io.OutputStream ; 81 import java.util.Enumeration ; 82 import java.util.Hashtable ; 83 84 85 98 public class Uploader 99 implements MultipartRequestHandler { 100 101 105 public static final int MAX_HEADER_SIZE = 1024; 106 107 110 private Hashtable headers; 111 private DefaultParameterParser myParser = null; 112 private ActionMapping myMapping = null; 113 private ActionServlet myActionServlet = null; 114 private static Logger log = Logger.getLogger(Uploader.class); 115 116 public Uploader() { 117 118 } 119 120 131 public void parseRequest(HttpServletRequest req, ParameterParser params, 132 String path) 133 throws ControllerException { 134 log.debug("Parse request begins"); 135 136 String contentType = req.getHeader("Content-type"); 137 138 if (!contentType.startsWith("multipart/form-data")) { 139 throw new ControllerException("Request doesn't contain multipart/form-data stream"); 140 } 141 142 int requestSize = req.getContentLength(); 143 144 if (requestSize == -1) { 145 throw new ControllerException("Request was rejected because it's size is unknown"); 146 } 147 try { 148 byte[] boundary = contentType.substring(contentType.indexOf("boundary=") + 9).getBytes(); 149 InputStream input = req.getInputStream(); 150 MultipartStream multi = new MultipartStream(input, boundary); 151 boolean nextPart = multi.skipPreamble(); 152 153 while (nextPart) { 154 parseHeaders(multi.readHeaders()); 155 156 String fieldName = getFieldName(); 157 158 if (fieldName != null) { 159 String subContentType = getHeader("Content-type"); 160 161 if (subContentType != null && 162 subContentType.startsWith("multipart/mixed")) { 163 164 byte[] subBoundary = subContentType.substring(subContentType.indexOf("boundary=") + 9).getBytes(); 166 multi.setBoundary(subBoundary); 167 168 boolean nextSubPart = multi.skipPreamble(); 169 170 while (nextSubPart) { 171 parseHeaders(multi.readHeaders()); 172 173 if (getFileName() != null) { 174 FileItem item = createItem(path, requestSize, 175 true); 176 OutputStream ops = item.getOutputStream(); 177 multi.readBodyData(ops); 178 ops.close(); 179 params.append(getFieldName(), item); 180 } else { 181 182 multi.discardBodyData(); 185 } 186 187 nextSubPart = multi.readBoundary(); 188 } 189 190 multi.setBoundary(boundary); 191 } else { 192 if (getFileName() != null) { 193 194 FileItem item = createItem(path, requestSize, true); 196 OutputStream ops = item.getOutputStream(); 197 multi.readBodyData(ops); 198 ops.close(); 199 params.append(getFieldName(), item); 200 log.debug("Read a file " + getFileName()); 201 } else { 202 203 205 FileItem item = createItem(path, requestSize, 206 false); 207 OutputStream ops = item.getOutputStream(); 208 multi.readBodyData(ops); 209 ops.close(); 210 211 String fieldData = new String (item.get()); 212 params.append(getFieldName(), fieldData); 213 log.debug("Read a Field:" + getFieldName() + 214 ", value:" + fieldData); 215 } 216 } 217 } else { 218 219 multi.discardBodyData(); 221 } 222 223 nextPart = multi.readBoundary(); 224 } 225 } catch (IOException e) { 226 log.error("I/O Exception parsing upload", e); 227 throw new ControllerException("Processing of multipart/form-data request failed", 228 e); 229 } 230 231 log.debug("Finished parsing"); 232 } 233 234 240 protected String getFieldName() { 241 String cd = getHeader("Content-disposition"); 242 243 if (cd == null || !cd.startsWith("form-data")) { 244 return null; 245 } 246 247 int start = cd.indexOf("name=\""); 248 int end = cd.indexOf('"', start + 6); 249 250 if (start == -1 || end == -1) { 251 return null; 252 } 253 254 return cd.substring(start + 6, end); 255 } 256 257 263 protected String getFileName() { 264 String cd = getHeader("Content-disposition"); 265 266 if (log.isDebugEnabled()) { 267 log.debug("Disposition says " + cd); 268 } 269 if (!cd.startsWith("form-data") && !cd.startsWith("attachment")) { 270 return null; 271 } 272 273 int start = cd.indexOf("filename=\""); 274 275 276 int end = cd.indexOf('"', start + 10); 277 278 if (start == -1 || end == -1 || ((start + 10) == end)) { 279 return null; 280 } 281 282 String str = cd.substring(start + 10, end).trim(); 283 284 if (str.length() == 0) { 285 return null; 286 } else { 287 if (log.isDebugEnabled()) { 288 log.debug("Got a filename '" + str + "'"); 289 } 290 291 return str; 292 } 293 } 294 295 302 protected FileItem createItem(String path, int requestSize, 303 boolean storeAsFile) { 304 return FileItem.newInstance(path, getFileName(), 305 getHeader("Content-type"), requestSize, 306 storeAsFile); 307 } 308 309 319 protected void parseHeaders(String headerPart) { 320 if (headers == null) { 321 headers = new Hashtable (); 322 } else { 323 headers.clear(); 324 } 325 326 char[] buffer = new char[MAX_HEADER_SIZE]; 327 boolean done = false; 328 int j = 0; 329 int i; 330 String header; 331 String headerName; 332 String headerValue; 333 334 try { 335 while (!done) { 336 i = 0; 337 338 while (i < 2 || buffer[i - 2] != '\r' || buffer[i - 1] != '\n') { 341 buffer[i++] = headerPart.charAt(j++); 342 } 343 344 header = new String (buffer, 0, i - 2); 345 346 if (header.equals("")) { 347 done = true; 348 } else { 349 if (header.indexOf(':') == -1) { 350 351 continue; 353 } 354 355 headerName = header.substring(0, header.indexOf(':')).trim().toLowerCase(); 356 headerValue = header.substring(header.indexOf(':') + 1).trim(); 357 358 if (headers.get(headerName) != null) { 359 360 headers.put(headerName, 363 (String ) headers.get(headerName) + "," + 364 headerValue); 365 } else { 366 headers.put(headerName, headerValue); 367 } 368 } 369 } 370 } catch (IndexOutOfBoundsException e) { 371 372 } 375 } 376 377 384 protected String getHeader(String name) { 385 return (String ) headers.get(name.toLowerCase()); 386 } 387 388 392 public void setServlet(ActionServlet servlet) { 393 myActionServlet = servlet; 394 } 395 396 400 public void setMapping(ActionMapping mapping) { 401 myMapping = mapping; 402 } 403 404 407 public ActionServlet getServlet() { 408 return myActionServlet; 409 } 410 411 414 public ActionMapping getMapping() { 415 return myMapping; 416 } 417 418 425 public void handleRequest(HttpServletRequest request) 426 throws ServletException { 427 myParser = new DefaultParameterParser(); 428 429 String tempDir = null; 430 431 try { 432 tempDir = Setup.getValueRequired("default", "TempDir"); 433 } catch (DBException de) { 434 log.error(de); 435 throw new ServletException ("Unable to get temp dir:" + 436 de.getMessage()); 437 } 438 try { 439 if (log.isDebugEnabled()) { 440 log.debug("About to parse request - tempDir is " + tempDir); 441 log.debug("Username in request is '" + 442 StringUtil.notNull((String ) request.getAttribute("UserName"))); 443 } 444 445 parseRequest(request, myParser, tempDir); 446 } catch (ControllerException ce) { 447 log.error(ce); 448 throw new ServletException (ce.getMessage()); 449 } 450 } 451 452 458 public Hashtable getTextElements() { 459 Hashtable textElements = new Hashtable (); 460 String oneKey = null; 461 462 for (Enumeration ee = myParser.keys(); ee.hasMoreElements();) { 463 oneKey = (String ) ee.nextElement(); 464 465 if (!myParser.hasFileItem(oneKey)) { 466 textElements.put(oneKey, StringUtil.notNull(myParser.get(oneKey))); 467 } 468 } 469 470 return textElements; 471 } 472 473 480 public Hashtable getFileElements() { 481 Hashtable fileElements = new Hashtable (); 482 String oneKey = null; 483 484 for (Enumeration ee = myParser.keys(); ee.hasMoreElements();) { 485 oneKey = (String ) ee.nextElement(); 486 487 if (myParser.hasFileItem(oneKey)) { 488 fileElements.put(oneKey, myParser.getFileItem(oneKey)); 489 } 490 } 491 492 return fileElements; 493 } 494 495 500 public Hashtable getAllElements() { 501 if (myParser == null) { 502 throw new IllegalArgumentException ("Parser not set"); 503 } 504 505 Hashtable allElements = new Hashtable (); 506 String oneKey = null; 507 508 for (Enumeration ee = myParser.keys(); ee.hasMoreElements();) { 509 oneKey = (String ) ee.nextElement(); 510 511 Object o = myParser.get(oneKey); 512 513 if (o != null) { 514 allElements.put(oneKey, o); 515 } 516 } 517 518 return allElements; 519 } 520 521 532 public void rollback() { 533 534 535 } 536 537 543 public void finish() { 544 545 546 } 547 548 } | Popular Tags |