Author: markt
Date: Fri Nov 20 19:27:11 2009
New Revision: 882690
URL: http://svn.apache.org/viewvc?rev=882690&view=rev
Log:
Complete the FileUpload implementation and use it for the html manager app.
Added:
tomcat/trunk/java/org/apache/catalina/core/StandardPart.java (with props)
Modified:
tomcat/trunk/java/javax/servlet/http/HttpServletRequest.java
tomcat/trunk/java/javax/servlet/http/Part.java
tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties
tomcat/trunk/java/org/apache/catalina/connector/Request.java
tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java
tomcat/trunk/java/org/apache/catalina/startup/WebXml.java
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
Modified: tomcat/trunk/java/javax/servlet/http/HttpServletRequest.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/javax/servlet/http/HttpServletRequest.java?rev=882690&r1=882689&r2=882690&view=diff
==============================================================================
--- tomcat/trunk/java/javax/servlet/http/HttpServletRequest.java (original)
+++ tomcat/trunk/java/javax/servlet/http/HttpServletRequest.java Fri Nov 20
19:27:11 2009
@@ -679,7 +679,11 @@
*
* @param username
* @param password
- * @throws ServletException
+ * @throws ServletException If any of {...@link #getRemoteUser()},
+ * {...@link #getUserPrincipal()} or {...@link #getAuthType()} are
+ * non-null, if the configured authenticator does not support
+ * user name and password authentication or if the authentication
+ * fails
* @since Servlet 3.0
* TODO SERVLET3 - Add comments
*/
@@ -689,7 +693,7 @@
/**
*
- * @throws ServletException
+ * @throws ServletException If the logout fails
* @since Servlet 3.0
* TODO SERVLET3 - Add comments
*/
Modified: tomcat/trunk/java/javax/servlet/http/Part.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/javax/servlet/http/Part.java?rev=882690&r1=882689&r2=882690&view=diff
==============================================================================
--- tomcat/trunk/java/javax/servlet/http/Part.java (original)
+++ tomcat/trunk/java/javax/servlet/http/Part.java Fri Nov 20 19:27:11 2009
@@ -31,6 +31,13 @@
public long getSize();
public void write(String fileName) throws IOException;
public void delete() throws IOException;
+
+ /**
+ * Obtains the value of the specified mime header for the part.
+ * @param name Header name
+ * @return The header value or <code>null</code> if the header is not
+ * present
+ */
public String getHeader(String name);
public Collection<String> getHeaders(String name);
public Collection<String> getHeaderNames();
Modified:
tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties?rev=882690&r1=882689&r2=882690&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties
(original)
+++ tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties Fri
Nov 20 19:27:11 2009
@@ -66,6 +66,7 @@
coyoteRequest.noPasswordLogin=The authentication mechanism configured for this
context does not support user name and password authentication
coyoteRequest.authFail=The authentication of user {0} was not successful
coyoteRequest.authenticate.ise=Cannot call authenticate() after the reponse
has been committed
+coyoteRequest.uploadLocationInvalid=The temporary upload location [{0}] is not
valid
requestFacade.nullRequest=The request object has been recycled and is no
longer associated with this facade
Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=882690&r1=882689&r2=882690&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Fri Nov 20
19:27:11 2009
@@ -20,6 +20,7 @@
import java.io.BufferedReader;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
@@ -31,6 +32,7 @@
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
@@ -65,12 +67,14 @@
import org.apache.catalina.Wrapper;
import org.apache.catalina.core.ApplicationSessionCookieConfig;
import org.apache.catalina.core.AsyncContextImpl;
+import org.apache.catalina.core.StandardPart;
import org.apache.catalina.deploy.LoginConfig;
import org.apache.catalina.realm.GenericPrincipal;
import org.apache.catalina.util.Enumerator;
import org.apache.catalina.util.ParameterMap;
import org.apache.catalina.util.StringParser;
import org.apache.coyote.ActionCode;
+import org.apache.jasper.compiler.ServletWriter;
import org.apache.tomcat.util.buf.B2CConverter;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.MessageBytes;
@@ -79,7 +83,12 @@
import org.apache.tomcat.util.http.FastHttpDateFormat;
import org.apache.tomcat.util.http.Parameters;
import org.apache.tomcat.util.http.ServerCookie;
+import org.apache.tomcat.util.http.fileupload.DiskFileItemFactory;
+import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileUploadBase;
+import org.apache.tomcat.util.http.fileupload.FileUploadException;
+import org.apache.tomcat.util.http.fileupload.ServletFileUpload;
+import
org.apache.tomcat.util.http.fileupload.FileUploadBase.InvalidContentTypeException;
import org.apache.tomcat.util.http.mapper.MappingData;
import org.apache.tomcat.util.res.StringManager;
import org.apache.tools.ant.util.CollectionUtils;
@@ -2335,11 +2344,7 @@
}
/**
- * @throws ServletException If any of {...@link #getRemoteUser()},
- * {...@link #getUserPrincipal()} or {...@link #getAuthType()} are
- * non-null, if the configured authenticator does not support
- * user name and password authentication or if the authentication
- * fails
+ * {...@inheritdoc}
*/
public void login(String username, String password)
throws ServletException {
@@ -2377,31 +2382,63 @@
}
/**
- * @throws ServletException If the logout fails
+ * {...@inheritdoc}
*/
public void logout() throws ServletException {
context.getAuthenticator().register(this, getResponse(), null,
null, null, null);
}
+ /**
+ * {...@inheritdoc}
+ */
public Collection<Part> getParts() throws IOException,
IllegalStateException,
ServletException {
- String contentType = getContentType();
- if (contentType == null ||
- !contentType.startsWith(FileUploadBase.MULTIPART_FORM_DATA)) {
- return Collections.emptyList();
- }
-
MultipartConfigElement mce = getWrapper().getMultipartConfig();
if (mce == null) {
return Collections.emptyList();
}
- // TODO SERVLET3 - file upload
- return Collections.emptyList();
+ File location = new File(mce.getLocation());
+
+ if (!location.isAbsolute() || !location.isDirectory()) {
+ throw new IOException(
+ sm.getString("coyoteRequest.uploadLocationInvalid",
+ location));
+ }
+
+ // Create a new file upload handler
+ DiskFileItemFactory factory = new DiskFileItemFactory();
+ factory.setRepository(location.getCanonicalFile());
+ factory.setSizeThreshold(mce.getFileSizeThreshold());
+
+ ServletFileUpload upload = new ServletFileUpload();
+ upload.setFileItemFactory(factory);
+ upload.setFileSizeMax(mce.getMaxFileSize());
+ upload.setSizeMax(mce.getMaxRequestSize());
+
+ List<Part> result = new ArrayList<Part>();
+ try {
+ List<FileItem> items = upload.parseRequest(this);
+ for (FileItem item : items) {
+ result.add(new StandardPart(item, mce));
+ }
+
+ } catch (InvalidContentTypeException e) {
+ throw new ServletException(e);
+ } catch (FileUploadBase.SizeException e) {
+ throw new IllegalStateException(e);
+ } catch (FileUploadException e) {
+ throw new IOException();
+ }
+
+ return result;
}
+ /**
+ * {...@inheritdoc}
+ */
public Part getPart(String name) throws IOException, IllegalStateException,
ServletException {
Collection<Part> parts = getParts();
Added: tomcat/trunk/java/org/apache/catalina/core/StandardPart.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardPart.java?rev=882690&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/StandardPart.java (added)
+++ tomcat/trunk/java/org/apache/catalina/core/StandardPart.java Fri Nov 20
19:27:11 2009
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.catalina.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import javax.servlet.MultipartConfigElement;
+import javax.servlet.ServletContext;
+import javax.servlet.http.Part;
+
+import org.apache.tomcat.util.http.fileupload.DiskFileItem;
+import org.apache.tomcat.util.http.fileupload.FileItem;
+
+/**
+ * Adaptor to allow {...@link FileItem} objects generated by the package
renamed
+ * commons-upload to be used by the Servlet 3.0 upload API that expects
+ * {...@link Part}s.
+ */
+public class StandardPart implements Part {
+
+ private FileItem fileItem;
+ private MultipartConfigElement mce;
+
+ public StandardPart(FileItem fileItem, MultipartConfigElement mce) {
+ this.fileItem = fileItem;
+ this.mce = mce;
+ }
+
+ @Override
+ public void delete() throws IOException {
+ fileItem.delete();
+ }
+
+ @Override
+ public String getContentType() {
+ return fileItem.getContentType();
+ }
+
+ @Override
+ public String getHeader(String name) {
+ if (fileItem instanceof DiskFileItem) {
+ return ((DiskFileItem) fileItem).getHeaders().getHeader(name);
+ }
+ return null;
+ }
+
+ @Override
+ public Collection<String> getHeaderNames() {
+ if (fileItem instanceof DiskFileItem) {
+ HashSet<String> headerNames = new HashSet<String>();
+ Iterator<String> iter =
+ ((DiskFileItem) fileItem).getHeaders().getHeaderNames();
+ while (iter.hasNext()) {
+ headerNames.add(iter.next());
+ }
+ return headerNames;
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public Collection<String> getHeaders(String name) {
+ if (fileItem instanceof DiskFileItem) {
+ HashSet<String> headers = new HashSet<String>();
+ Iterator<String> iter =
+ ((DiskFileItem) fileItem).getHeaders().getHeaders(name);
+ while (iter.hasNext()) {
+ headers.add(iter.next());
+ }
+ return headers;
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return fileItem.getInputStream();
+ }
+
+ @Override
+ public String getName() {
+ return fileItem.getFieldName();
+ }
+
+ @Override
+ public long getSize() {
+ return fileItem.getSize();
+ }
+
+ @Override
+ public void write(String fileName) throws IOException {
+ File file = new File(fileName);
+ if (!file.isAbsolute()) {
+ file = new File(mce.getLocation(), fileName);
+ }
+ try {
+ fileItem.write(file);
+ } catch (Exception e) {
+ throw new IOException(e);
+ }
+ }
+
+}
Propchange: tomcat/trunk/java/org/apache/catalina/core/StandardPart.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tomcat/trunk/java/org/apache/catalina/core/StandardPart.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision
Modified: tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java?rev=882690&r1=882689&r2=882690&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java Fri
Nov 20 19:27:11 2009
@@ -24,6 +24,7 @@
import java.io.StringWriter;
import java.text.MessageFormat;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
@@ -33,7 +34,6 @@
import java.util.Random;
import java.util.TreeMap;
-import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -50,9 +50,7 @@
import org.apache.catalina.util.RequestUtil;
import org.apache.catalina.util.ServerInfo;
import org.apache.catalina.util.URLEncoder;
-import org.apache.tomcat.util.http.fileupload.DiskFileItemFactory;
-import org.apache.tomcat.util.http.fileupload.ServletFileUpload;
-import org.apache.tomcat.util.http.fileupload.FileItem;
+import org.apache.tomcat.util.http.fileupload.ParameterParser;
/**
* Servlet that enables remote management of the web applications deployed
@@ -263,69 +261,54 @@
throws IOException, ServletException {
String message = "";
- // TODO - Rewrite this to use the Servlet 3 file upload API
- Part part = request.getPart("deployWar");
-
- // Get the tempdir
- File tempdir = (File) getServletContext().getAttribute
- (ServletContext.TEMPDIR);
-
- // Create a new file upload handler
- DiskFileItemFactory factory = new DiskFileItemFactory();
- factory.setRepository(tempdir.getCanonicalFile());
- ServletFileUpload upload = new ServletFileUpload();
- upload.setFileItemFactory(factory);
-
- // Set upload parameters
- upload.setSizeMax(-1);
-
- // Parse the request
+ Part warPart = null;
+ String filename = null;
String basename = null;
- String war = null;
- FileItem warUpload = null;
- try {
- List<FileItem> items = upload.parseRequest(request);
+
+ Collection<Part> parts = request.getParts();
+ Iterator<Part> iter = parts.iterator();
- // Process the uploaded fields
- Iterator<FileItem> iter = items.iterator();
+ try {
while (iter.hasNext()) {
- FileItem item = iter.next();
-
- if (!item.isFormField()) {
- if (item.getFieldName().equals("deployWar") &&
- warUpload == null) {
- warUpload = item;
- } else {
- item.delete();
- }
+ Part part = iter.next();
+ if (part.getName().equals("deployWar") && warPart == null) {
+ warPart = part;
+ } else {
+ part.delete();
}
}
+
while (true) {
- if (warUpload == null) {
- message = sm.getString
- ("htmlManagerServlet.deployUploadNoFile");
+ if (warPart == null) {
+ message =
+ sm.getString("htmlManagerServlet.deployUploadNoFile");
break;
}
- war = warUpload.getName();
- if (!war.toLowerCase().endsWith(".war")) {
- message = sm.getString
- ("htmlManagerServlet.deployUploadNotWar",war);
+ filename =
+ extractFilename(warPart.getHeader("Content-Disposition"));
+ if (!filename.toLowerCase().endsWith(".war")) {
+ message = sm.getString(
+ "htmlManagerServlet.deployUploadNotWar", filename);
break;
}
// Get the filename if uploaded name includes a path
- if (war.lastIndexOf('\\') >= 0) {
- war = war.substring(war.lastIndexOf('\\') + 1);
- }
- if (war.lastIndexOf('/') >= 0) {
- war = war.substring(war.lastIndexOf('/') + 1);
+ if (filename.lastIndexOf('\\') >= 0) {
+ filename =
+ filename.substring(filename.lastIndexOf('\\') + 1);
+ }
+ if (filename.lastIndexOf('/') >= 0) {
+ filename =
+ filename.substring(filename.lastIndexOf('/') + 1);
}
// Identify the appBase of the owning Host of this Context
// (if any)
- basename = war.substring(0, war.toLowerCase().indexOf(".war"));
- File file = new File(getAppBase(), war);
+ basename = filename.substring(0,
+ filename.toLowerCase().indexOf(".war"));
+ File file = new File(getAppBase(), filename);
if (file.exists()) {
- message = sm.getString
- ("htmlManagerServlet.deployUploadWarExists",war);
+ message = sm.getString(
+ "htmlManagerServlet.deployUploadWarExists",
+ filename);
break;
}
String path = null;
@@ -336,15 +319,16 @@
}
if ((host.findChild(path) != null) && !isDeployed(path)) {
- message = sm.getString
- ("htmlManagerServlet.deployUploadInServerXml", war);
+ message = sm.getString(
+ "htmlManagerServlet.deployUploadInServerXml",
+ filename);
break;
}
if (!isServiced(path)) {
addServiced(path);
try {
- warUpload.write(file);
+ warPart.write(file.getAbsolutePath());
// Perform new deployment
check(path);
} finally {
@@ -358,14 +342,43 @@
("htmlManagerServlet.deployUploadFail", e.getMessage());
log(message, e);
} finally {
- if (warUpload != null) {
- warUpload.delete();
+ if (warPart != null) {
+ warPart.delete();
}
- warUpload = null;
+ warPart = null;
}
return message;
}
+ /*
+ * Adapted from FileUploadBase.getFileName()
+ */
+ private String extractFilename(String cd) {
+ String fileName = null;
+ if (cd != null) {
+ String cdl = cd.toLowerCase();
+ if (cdl.startsWith("form-data") || cdl.startsWith("attachment")) {
+ ParameterParser parser = new ParameterParser();
+ parser.setLowerCaseNames(true);
+ // Parameter parser can handle null input
+ Map<String,String> params =
+ parser.parse(cd, ';');
+ if (params.containsKey("filename")) {
+ fileName = params.get("filename");
+ if (fileName != null) {
+ fileName = fileName.trim();
+ } else {
+ // Even if there is no value, the parameter is present,
+ // so we return an empty file name rather than no file
+ // name.
+ fileName = "";
+ }
+ }
+ }
+ }
+ return fileName;
+ }
+
/**
* Deploy an application for the specified path from the specified
* web application archive.
Modified: tomcat/trunk/java/org/apache/catalina/startup/WebXml.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/WebXml.java?rev=882690&r1=882689&r2=882690&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/WebXml.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/WebXml.java Fri Nov 20
19:27:11 2009
@@ -18,6 +18,7 @@
package org.apache.catalina.startup;
+import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
@@ -29,6 +30,7 @@
import java.util.Set;
import javax.servlet.MultipartConfigElement;
+import javax.servlet.ServletContext;
import org.apache.catalina.Context;
import org.apache.catalina.Wrapper;
@@ -566,18 +568,23 @@
wrapper.setServletClass(servlet.getServletClass());
MultipartDef multipartdef = servlet.getMultipartDef();
if (multipartdef != null) {
+ String location = multipartdef.getLocation();
+ if (location == null || location.length() == 0) {
+ location = ((File)
context.getServletContext().getAttribute(
+ ServletContext.TEMPDIR)).getAbsolutePath();
+ }
if (multipartdef.getMaxFileSize() != null &&
multipartdef.getMaxRequestSize()!= null &&
multipartdef.getFileSizeThreshold() != null) {
wrapper.setMultipartConfig(new MultipartConfigElement(
- multipartdef.getLocation(),
+ location,
Long.parseLong(multipartdef.getMaxFileSize()),
Long.parseLong(multipartdef.getMaxRequestSize()),
Integer.parseInt(
multipartdef.getFileSizeThreshold())));
} else {
wrapper.setMultipartConfig(new MultipartConfigElement(
- multipartdef.getLocation()));
+ location));
}
}
context.addChild(wrapper);
Modified:
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java?rev=882690&r1=882689&r2=882690&view=diff
==============================================================================
---
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
(original)
+++
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
Fri Nov 20 19:27:11 2009
@@ -851,6 +851,7 @@
currentItem = new FileItemStreamImpl(fileName,
fieldName, headers.getHeader(CONTENT_TYPE),
fileName == null, getContentLength(headers));
+ currentItem.setHeaders(headers);
notifier.noteItem();
itemValid = true;
return true;
@@ -862,6 +863,7 @@
currentFieldName,
headers.getHeader(CONTENT_TYPE),
false, getContentLength(headers));
+ currentItem.setHeaders(headers);
notifier.noteItem();
itemValid = true;
return true;
@@ -1015,7 +1017,7 @@
/** This exception is thrown, if a requests permitted size
* is exceeded.
*/
- protected abstract static class SizeException extends FileUploadException {
+ public abstract static class SizeException extends FileUploadException {
private static final long serialVersionUID = 1L;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]