dlr 01/05/18 13:15:58
Modified: src/java/org/apache/turbine/services/upload
TurbineUploadService.java
Log:
Refactored to remove multi-threading issues (hopefully, heh).
* Import Map and HashMap instead of Hashtable.
* Used HTTP header constants now defined in the UploadService
interface.
* Refactored parseHeaders() and getHeader() to no longer use headers
instance member which would wreak havoc for multiple threads using the
service at the same time. A Map of HTTP headers is now passed in
instead.
* The createItem(), getFieldName(), and getFileName() methods needed
an interface change so that it would have a Map of headers to pass to
getHeader().
Revision Changes Path
1.16 +58 -63
jakarta-turbine/src/java/org/apache/turbine/services/upload/TurbineUploadService.java
Index: TurbineUploadService.java
===================================================================
RCS file:
/home/cvs/jakarta-turbine/src/java/org/apache/turbine/services/upload/TurbineUploadService.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- TurbineUploadService.java 2001/05/18 18:25:57 1.15
+++ TurbineUploadService.java 2001/05/18 20:15:55 1.16
@@ -57,7 +57,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.util.Hashtable;
+import java.util.Map;
+import java.util.HashMap;
import java.util.Properties;
import javax.servlet.ServletContext;
import javax.servlet.ServletInputStream;
@@ -89,7 +90,7 @@
*
* @author <a href="mailto:[EMAIL PROTECTED]">Rafal Krzewski</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Daniel Rall</a>
- * @version $Id: TurbineUploadService.java,v 1.15 2001/05/18 18:25:57 dlr Exp $
+ * @version $Id: TurbineUploadService.java,v 1.16 2001/05/18 20:15:55 dlr Exp $
*/
public class TurbineUploadService
extends BaseUploadService
@@ -110,11 +111,11 @@
String path )
throws TurbineException
{
- String contentType = req.getHeader("Content-type");
- if(!contentType.startsWith("multipart/form-data"))
+ String contentType = req.getHeader(CONTENT_TYPE);
+ if(!contentType.startsWith(MULTIPART_FORM_DATA))
{
- throw new TurbineException("the request doesn't contain " +
- "multipart/form-data stream");
+ throw new TurbineException("the request doesn't contain a " +
+ MULTIPART_FORM_DATA + " stream");
}
int requestSize = req.getContentLength();
if(requestSize == -1)
@@ -138,13 +139,13 @@
boolean nextPart = multi.skipPreamble();
while(nextPart)
{
- parseHeaders(multi.readHeaders());
- String fieldName = getFieldName();
+ Map headers = parseHeaders(multi.readHeaders());
+ String fieldName = getFieldName(headers);
if (fieldName != null)
{
- String subContentType = getHeader("Content-type");
+ String subContentType = getHeader(headers, CONTENT_TYPE);
if (subContentType != null && subContentType
- .startsWith("multipart/mixed"))
+ .startsWith(MULTIPART_MIXED))
{
// Multiple files.
byte[] subBoundary =
@@ -155,10 +156,11 @@
boolean nextSubPart = multi.skipPreamble();
while (nextSubPart)
{
- parseHeaders(multi.readHeaders());
- if (getFileName() != null)
+ headers = parseHeaders(multi.readHeaders());
+ if (getFileName(headers) != null)
{
- FileItem item = createItem(path, requestSize);
+ FileItem item = createItem(path, headers,
+ requestSize);
OutputStream os = item.getOutputStream();
try
{
@@ -168,7 +170,7 @@
{
os.close();
}
- params.append(getFieldName(), item);
+ params.append(getFieldName(headers), item);
}
else
{
@@ -182,10 +184,11 @@
}
else
{
- if (getFileName() != null)
+ if (getFileName(headers) != null)
{
// A single file.
- FileItem item = createItem(path, requestSize);
+ FileItem item = createItem(path, headers,
+ requestSize);
OutputStream os = item.getOutputStream();
try
{
@@ -195,12 +198,13 @@
{
os.close();
}
- params.append(getFieldName(), item);
+ params.append(getFieldName(headers), item);
}
else
{
// A form field.
- FileItem item = createItem(path, requestSize);
+ FileItem item = createItem(path, headers,
+ requestSize);
OutputStream os = item.getOutputStream();
try
{
@@ -210,8 +214,8 @@
{
os.close();
}
- params.append(getFieldName(),
- new String(item.get()));
+ params.append(getFieldName(headers),
+ new String(item.get()));
}
}
}
@@ -225,22 +229,22 @@
}
catch(IOException e)
{
- throw new TurbineException("Processing of multipart/form-data " +
- "request failed", e);
+ throw new TurbineException("Processing of " + MULTIPART_FORM_DATA
+ + " request failed", e);
}
}
/**
- * <p> Retrieves file name from 'Content-disposition' header.
+ * <p> Retrieves file name from <code>Content-disposition</code> header.
*
- * @return A String with the file name for the current
- * <code>encapsulation</code>.
+ * @param headers The HTTP request headers.
+ * @return A the file name for the current <code>encapsulation</code>.
*/
- protected String getFileName()
+ protected String getFileName(Map headers)
{
String fileName = null;
- String cd = getHeader("Content-disposition");
- if(cd.startsWith("form-data") || cd.startsWith("attachment"))
+ String cd = getHeader(headers, CONTENT_DISPOSITION);
+ if(cd.startsWith(FORM_DATA) || cd.startsWith("attachment"))
{
int start = cd.indexOf("filename=\"");
int end = cd.indexOf('"', start + 10);
@@ -257,19 +261,19 @@
}
/**
- * <p> Retrieves field name from 'Content-disposition' header.
+ * <p> Retrieves field name from <code>Content-disposition</code> header.
*
- * @return A String with the field name for the current
- * <code>encapsulation</code>.
+ * @param headers The HTTP request headers.
+ * @return The field name for the current <code>encapsulation</code>.
*/
- protected String getFieldName()
+ protected String getFieldName(Map headers)
{
String fieldName = null;
- String cd = getHeader("Content-disposition");
- if(cd != null && cd.startsWith("form-data"))
+ String cd = getHeader(headers, CONTENT_DISPOSITION);
+ if(cd != null && cd.startsWith(FORM_DATA))
{
int start = cd.indexOf("name=\"");
- int end = cd.indexOf('"', start+6);
+ int end = cd.indexOf('"', start + 6);
if(start != -1 && end != -1)
{
fieldName = cd.substring(start + 6, end);
@@ -283,46 +287,34 @@
* org.apache.turbine.util.upload.FileItem}.
*
* @param path The path for the FileItem.
+ * @param headers The HTTP request headers.
* @param requestSize The size of the request.
* @return A newly created <code>FileItem</code>.
*/
protected FileItem createItem( String path,
+ Map headers,
int requestSize )
{
return FileItem.newInstance(path,
- getFileName(),
- getHeader("Content-type"),
+ getFileName(headers),
+ getHeader(headers, CONTENT_TYPE),
requestSize);
}
- /**
- * Stores parsed headers as key - value pairs.
- * <p>
- * <b>TODO: Correct this multi-threading nightmare.</b>
- */
- Hashtable headers;
-
/**
- * <p> Parses the <code>header-part</code> and stores as key -
- * value pairs.
+ * <p> Parses the <code>header-part</code> and returns as key/value
+ * pairs.
*
* <p> If there are multiple headers of the same names, the name
* will map to a comma-separated list containing the values.
*
* @param headerPart The <code>header-part</code> of the current
* <code>encapsulation</code>.
+ * @return The parsed HTTP request headers.
*/
- protected void parseHeaders( String headerPart )
+ protected Map parseHeaders( String headerPart )
{
- if (headers == null)
- {
- headers = new Hashtable();
- }
- else
- {
- headers.clear();
- }
-
+ Map headers = new HashMap();
char buffer[] = new char[MAX_HEADER_SIZE];
boolean done = false;
int j = 0;
@@ -351,16 +343,17 @@
// This header line is malformed, skip it.
continue;
}
- headerName = header
- .substring(0, header.indexOf(':')).trim().toLowerCase();
+ headerName = header.substring(0, header.indexOf(':'))
+ .trim().toLowerCase();
headerValue =
- header.substring(header.indexOf(':')+1).trim();
- if (headers.get(headerName) != null)
+ header.substring(header.indexOf(':') + 1).trim();
+ if (getHeader(headers, headerName) != null)
{
// More that one heder of that name exists,
// append to the list.
- headers.put(headerName,
- (String)headers.get(headerName)+","+headerValue);
+ headers.put(headerName,
+ getHeader(headers, headerName) + ',' +
+ headerValue);
}
else
{
@@ -374,16 +367,18 @@
// Headers were malformed. continue with all that was
// parsed.
}
+ return headers;
}
/**
* <p> Returns a header with specified name.
*
+ * @param headers The HTTP request headers.
* @param name The name of the header to fetch.
* @return The value of specified header, or a comma-separated
* list if there were multiple headers of that name.
*/
- protected String getHeader( String name )
+ protected final String getHeader( Map headers, String name )
{
return (String)headers.get(name.toLowerCase());
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]