diff --git a/source/java/org/alfresco/web/app/servlet/UploadContentServlet.java b/source/java/org/alfresco/web/app/servlet/UploadContentServlet.java new file mode 100644 index 0000000000..8ff7890c52 --- /dev/null +++ b/source/java/org/alfresco/web/app/servlet/UploadContentServlet.java @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * 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.alfresco.web.app.servlet; + +import java.io.IOException; +import java.util.StringTokenizer; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.alfresco.model.ContentModel; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.ContentWriter; +import org.alfresco.service.cmr.repository.MimetypeService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.namespace.QName; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Servlet responsible for streaming content directly into the repository from the PUT request. + * The appropriate mimetype is calculated based on filename extension. + *
+ * The URL to the servlet should be generated thus: + *
/alfresco/upload/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf+ * or + *
/alfresco/upload/myfile.pdf+ *
+ * If the store and node id are specified in the URL then the content provided will be streamed onto the node + * using an updating writer, updating the content property value accordingly. + *
+ * If only the file name is specified the content will be streamed into the content store and the content data + * will be returned in the reposonse. This can then be used to update the value of a content property manually. + * Any used content will be cleared up in the usual manner. + *
+ * By default, the download assumes that the content is on the
+ * {@link org.alfresco.model.ContentModel#PROP_CONTENT content property}.
+ * To set the content of a specific model property, use a 'property' arg, providing the qualified name of the property.
+ *
+ * Like most Alfresco servlets, the URL may be followed by a valid 'ticket' argument for authentication: + * ?ticket=1234567890 + *
+ * Guest access is currently disabled for this servlet.
+ *
+ * @author Roy Wetherall
+ */
+public class UploadContentServlet extends BaseServlet
+{
+ /** Serial version UID */
+ private static final long serialVersionUID = 1055960980867420355L;
+
+ /** Logger */
+ private static Log logger = LogFactory.getLog(UploadContentServlet.class);
+
+ /** Default mime type */
+ protected static final String MIMETYPE_OCTET_STREAM = "application/octet-stream";
+
+ /** Argument properties */
+ protected static final String ARG_PROPERTY = "property";
+ protected static final String ARG_MIMETYPE = "mimetype";
+ protected static final String ARG_ENCODING = "encoding";
+
+ /**
+ * @see javax.servlet.http.HttpServlet#doPut(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ protected void doPut(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
+ {
+ if (logger.isDebugEnabled() == true)
+ {
+ String queryString = req.getQueryString();
+ logger.debug("Authenticating request to URL: " + req.getRequestURI()
+ + ((queryString != null && queryString.length() > 0) ? ("?" + queryString) : ""));
+ }
+
+ AuthenticationStatus status = servletAuthenticate(req, res, false);
+ if (status == AuthenticationStatus.Failure || status == AuthenticationStatus.Guest)
+ {
+ res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+ return;
+ }
+
+ // Tokenise the URI
+ String uri = req.getRequestURI();
+ uri = uri.substring(req.getContextPath().length());
+ StringTokenizer t = new StringTokenizer(uri, "/");
+ int tokenCount = t.countTokens();
+
+ t.nextToken(); // skip servlet name
+
+ // get or calculate the noderef and filename to download as
+ NodeRef nodeRef = null;
+ String filename = null;
+ QName propertyQName = null;
+
+ if (tokenCount == 2)
+ {
+ // filename is the only token
+ filename = t.nextToken();
+ }
+ else if (tokenCount == 4 || tokenCount == 5)
+ {
+ // assume 'workspace' or other NodeRef based protocol for remaining URL
+ // elements
+ StoreRef storeRef = new StoreRef(t.nextToken(), t.nextToken());
+ String id = t.nextToken();
+ // build noderef from the appropriate URL elements
+ nodeRef = new NodeRef(storeRef, id);
+
+ if (tokenCount == 5)
+ {
+ // filename is last remaining token
+ filename = t.nextToken();
+ }
+
+ // get qualified of the property to get content from - default to
+ // ContentModel.PROP_CONTENT
+ propertyQName = ContentModel.PROP_CONTENT;
+ String property = req.getParameter(ARG_PROPERTY);
+ if (property != null && property.length() != 0)
+ {
+ propertyQName = QName.createQName(property);
+ }
+ }
+ else
+ {
+ logger.debug("Upload URL did not contain all required args: " + uri);
+ res.sendError(HttpServletResponse.SC_EXPECTATION_FAILED);
+ return;
+ }
+
+ // Get the encoding
+ String encoding = req.getParameter(ARG_ENCODING);
+ if (encoding == null || encoding.length() == 0)
+ {
+ encoding = "UTF-8";
+ }
+
+ // get the services we need to retrieve the content
+ ServiceRegistry serviceRegistry = getServiceRegistry(getServletContext());
+ ContentService contentService = serviceRegistry.getContentService();
+ PermissionService permissionService = serviceRegistry.getPermissionService();
+
+ // Sort out the mimetype
+ String mimetype = req.getParameter(ARG_MIMETYPE);
+ if (mimetype == null || mimetype.length() == 0)
+ {
+ mimetype = MIMETYPE_OCTET_STREAM;
+ if (filename != null)
+ {
+ MimetypeService mimetypeMap = serviceRegistry.getMimetypeService();
+ int extIndex = filename.lastIndexOf('.');
+ if (extIndex != -1)
+ {
+ String ext = filename.substring(extIndex + 1);
+ String mt = mimetypeMap.getMimetypesByExtension().get(ext);
+ if (mt != null)
+ {
+ mimetype = mt;
+ }
+ }
+ }
+ }
+
+ if (logger.isDebugEnabled())
+ {
+ if (nodeRef != null) {logger.debug("Found NodeRef: " + nodeRef.toString());}
+ logger.debug("For property: " + propertyQName);
+ logger.debug("File name: " + filename);
+ logger.debug("Mimetype: " + mimetype);
+ logger.debug("Encoding: " + encoding);
+ }
+
+ // Check that the user has the permissions to write the content
+ if (permissionService.hasPermission(nodeRef, PermissionService.WRITE_CONTENT) == AccessStatus.DENIED)
+ {
+ if (logger.isDebugEnabled() == true)
+ {
+ logger.debug("User does not have permissions to wrtie content for NodeRef: " + nodeRef.toString());
+ }
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("Returning 403 Forbidden error...");
+ }
+
+ res.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+
+ // Try and get the content writer
+ ContentWriter writer = contentService.getWriter(nodeRef, propertyQName, true);
+ if (writer == null)
+ {
+ if (logger.isDebugEnabled() == true)
+ {
+ logger.debug("Content writer cannot be obtained for NodeRef: " + nodeRef.toString());
+ }
+ res.sendError(HttpServletResponse.SC_EXPECTATION_FAILED);
+ return;
+ }
+
+ // Set the mimetype and encoding
+ writer.setMimetype(mimetype);
+ writer.setEncoding(encoding);
+
+ // Stream the content into the repository
+ writer.putContent(req.getInputStream());
+
+ if (logger.isDebugEnabled() == true)
+ {
+ logger.debug("Content details: " + writer.getContentData().toString());
+ }
+
+ // Set return status
+ res.getWriter().write(writer.getContentData().toString());
+ res.flushBuffer();
+ }
+}
diff --git a/source/java/org/alfresco/web/app/servlet/UploadFileServlet.java b/source/java/org/alfresco/web/app/servlet/UploadFileServlet.java
index 96e8beb5f4..51cc5487ac 100644
--- a/source/java/org/alfresco/web/app/servlet/UploadFileServlet.java
+++ b/source/java/org/alfresco/web/app/servlet/UploadFileServlet.java
@@ -106,8 +106,10 @@ public class UploadFileServlet extends BaseServlet
String filename = item.getName();
if (filename != null && filename.length() != 0)
{
- if (logger.isDebugEnabled())
+ if (logger.isDebugEnabled() == true)
+ {
logger.debug("Processing uploaded file: " + filename);
+ }
// workaround a bug in IE where the full path is returned
// IE is only available for Windows so only check for the Windows path separator
@@ -130,9 +132,11 @@ public class UploadFileServlet extends BaseServlet
bean.setFileName(filename);
bean.setFilePath(tempFile.getAbsolutePath());
session.setAttribute(FileUploadBean.getKey(uploadId), bean);
- if (logger.isDebugEnabled())
+ if (logger.isDebugEnabled() == true)
+ {
logger.debug("Temp file: " + tempFile.getAbsolutePath() +
" created from upload filename: " + filename);
+ }
}
}
}
@@ -143,8 +147,10 @@ public class UploadFileServlet extends BaseServlet
}
// finally redirect
- if (logger.isDebugEnabled())
+ if (logger.isDebugEnabled() == true)
+ {
logger.debug("Upload servicing complete, redirecting to: " + returnPage);
+ }
response.sendRedirect(returnPage);
}
diff --git a/source/web/WEB-INF/web.xml b/source/web/WEB-INF/web.xml
index 4c66617c19..cb908365ba 100644
--- a/source/web/WEB-INF/web.xml
+++ b/source/web/WEB-INF/web.xml
@@ -175,6 +175,11 @@