Search in sources :

Example 11 with RetryException

use of org.structr.api.RetryException in project structr by structr.

the class UploadServlet method doPost.

@Override
protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException {
    try {
        if (!ServletFileUpload.isMultipartContent(request)) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.getOutputStream().write("ERROR (400): Request does not contain multipart content.\n".getBytes("UTF-8"));
            return;
        }
    } catch (IOException ioex) {
        logger.warn("Unable to send response", ioex);
    }
    SecurityContext securityContext = null;
    String redirectUrl = null;
    boolean appendUuidOnRedirect = false;
    String path = null;
    // isolate request authentication in a transaction
    try (final Tx tx = StructrApp.getInstance().tx()) {
        try {
            securityContext = getConfig().getAuthenticator().initializeAndExamineRequest(request, response);
        } catch (AuthenticationException ae) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getOutputStream().write("ERROR (401): Invalid user or password.\n".getBytes("UTF-8"));
            return;
        }
        tx.success();
    } catch (FrameworkException fex) {
        logger.warn("Unable to examine request", fex);
    } catch (IOException ioex) {
        logger.warn("Unable to send response", ioex);
    }
    // something went wrong, but we don't know what...
    if (securityContext == null) {
        logger.warn("No SecurityContext, aborting.");
        return;
    }
    try {
        if (securityContext.getUser(false) == null && !Settings.UploadAllowAnonymous.getValue()) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getOutputStream().write("ERROR (401): Anonymous uploads forbidden.\n".getBytes("UTF-8"));
            return;
        }
        // Ensure access mode is frontend
        securityContext.setAccessMode(AccessMode.Frontend);
        request.setCharacterEncoding("UTF-8");
        // Important: Set character encoding before calling response.getWriter() !!, see Servlet Spec 5.4
        response.setCharacterEncoding("UTF-8");
        // don't continue on redirects
        if (response.getStatus() == 302) {
            return;
        }
        final String pathInfo = request.getPathInfo();
        String type = null;
        if (StringUtils.isNotBlank(pathInfo)) {
            type = SchemaHelper.normalizeEntityName(StringUtils.stripStart(pathInfo.trim(), "/"));
        }
        uploader.setFileSizeMax((long) MEGABYTE * Settings.UploadMaxFileSize.getValue());
        uploader.setSizeMax((long) MEGABYTE * Settings.UploadMaxRequestSize.getValue());
        response.setContentType("text/html");
        FileItemIterator fileItemsIterator = uploader.getItemIterator(request);
        final Map<String, Object> params = new HashMap<>();
        while (fileItemsIterator.hasNext()) {
            final FileItemStream item = fileItemsIterator.next();
            if (item.isFormField()) {
                final String fieldName = item.getFieldName();
                final String fieldValue = IOUtils.toString(item.openStream(), "UTF-8");
                if (REDIRECT_AFTER_UPLOAD_PARAMETER.equals(fieldName)) {
                    redirectUrl = fieldValue;
                } else if (APPEND_UUID_ON_REDIRECT_PARAMETER.equals(fieldName)) {
                    appendUuidOnRedirect = "true".equalsIgnoreCase(fieldValue);
                } else if (UPLOAD_FOLDER_PATH_PARAMETER.equals(fieldName)) {
                    path = fieldValue;
                } else {
                    params.put(fieldName, fieldValue);
                }
            } else {
                try {
                    final String contentType = item.getContentType();
                    boolean isImage = (contentType != null && contentType.startsWith("image"));
                    boolean isVideo = (contentType != null && contentType.startsWith("video"));
                    // Override type from path info
                    if (params.containsKey(NodeInterface.type.jsonName())) {
                        type = (String) params.get(NodeInterface.type.jsonName());
                    }
                    Class cls = null;
                    if (type != null) {
                        cls = SchemaHelper.getEntityClassForRawType(type);
                    }
                    if (cls == null) {
                        if (isImage) {
                            cls = Image.class;
                        } else if (isVideo) {
                            cls = SchemaHelper.getEntityClassForRawType("VideoFile");
                            if (cls == null) {
                                logger.warn("Unable to create entity of type VideoFile, class is not defined.");
                            }
                        } else {
                            cls = File.class;
                        }
                    }
                    if (cls != null) {
                        type = cls.getSimpleName();
                    }
                    final String name = item.getName().replaceAll("\\\\", "/");
                    File newFile = null;
                    String uuid = null;
                    boolean retry = true;
                    while (retry) {
                        retry = false;
                        Folder uploadFolder = null;
                        final String defaultUploadFolderConfigValue = Settings.DefaultUploadFolder.getValue();
                        // If a path attribute was sent, create all folders on the fly.
                        if (path != null) {
                            uploadFolder = getOrCreateFolderPath(securityContext, path);
                        } else if (StringUtils.isNotBlank(defaultUploadFolderConfigValue)) {
                            uploadFolder = getOrCreateFolderPath(SecurityContext.getSuperUserInstance(), defaultUploadFolderConfigValue);
                        }
                        try (final Tx tx = StructrApp.getInstance(securityContext).tx()) {
                            try (final InputStream is = item.openStream()) {
                                newFile = FileHelper.createFile(securityContext, is, contentType, cls, name, uploadFolder);
                                AbstractFile.validateAndRenameFileOnce(newFile, securityContext, null);
                                final PropertyMap changedProperties = new PropertyMap();
                                changedProperties.putAll(PropertyMap.inputTypeToJavaType(securityContext, cls, params));
                                // Update type as it could have changed
                                changedProperties.put(AbstractNode.type, type);
                                newFile.unlockSystemPropertiesOnce();
                                newFile.setProperties(securityContext, changedProperties);
                                uuid = newFile.getUuid();
                            }
                            tx.success();
                        } catch (RetryException rex) {
                            retry = true;
                        }
                    }
                    // only the actual existing file creates a UUID output
                    if (newFile != null) {
                        // upload trigger
                        newFile.notifyUploadCompletion();
                        // send redirect to allow form-based file upload without JavaScript..
                        if (StringUtils.isNotBlank(redirectUrl)) {
                            if (appendUuidOnRedirect) {
                                response.sendRedirect(redirectUrl + uuid);
                            } else {
                                response.sendRedirect(redirectUrl);
                            }
                        } else {
                            // Just write out the uuids of the new files
                            response.getWriter().write(uuid);
                        }
                    }
                } catch (IOException ex) {
                    logger.warn("Could not upload file", ex);
                }
            }
        }
    } catch (Throwable t) {
        final String content;
        if (t instanceof FrameworkException) {
            final FrameworkException fex = (FrameworkException) t;
            logger.error(fex.toString());
            content = errorPage(fex);
        } else {
            logger.error("Exception while processing upload request", t);
            content = errorPage(t);
        }
        try {
            final ServletOutputStream out = response.getOutputStream();
            IOUtils.write(content, out);
        } catch (IOException ex) {
            logger.error("Could not write to response", ex);
        }
    }
}
Also used : Tx(org.structr.core.graph.Tx) FrameworkException(org.structr.common.error.FrameworkException) AuthenticationException(org.structr.core.auth.exception.AuthenticationException) HashMap(java.util.HashMap) ServletOutputStream(javax.servlet.ServletOutputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) Folder(org.structr.web.entity.Folder) RetryException(org.structr.api.RetryException) PropertyMap(org.structr.core.property.PropertyMap) FileItemStream(org.apache.commons.fileupload.FileItemStream) SecurityContext(org.structr.common.SecurityContext) GraphObject(org.structr.core.GraphObject) FileItemIterator(org.apache.commons.fileupload.FileItemIterator) AbstractFile(org.structr.web.entity.AbstractFile) File(org.structr.web.entity.File)

Aggregations

RetryException (org.structr.api.RetryException)11 FrameworkException (org.structr.common.error.FrameworkException)8 Tx (org.structr.core.graph.Tx)7 JsonParseException (com.google.gson.JsonParseException)6 JsonSyntaxException (com.google.gson.JsonSyntaxException)6 SecurityContext (org.structr.common.SecurityContext)6 App (org.structr.core.app.App)6 StructrApp (org.structr.core.app.StructrApp)6 Authenticator (org.structr.core.auth.Authenticator)6 RestMethodResult (org.structr.rest.RestMethodResult)6 Resource (org.structr.rest.resource.Resource)6 StaticRelationshipResource (org.structr.rest.resource.StaticRelationshipResource)5 GraphObject (org.structr.core.GraphObject)4 IOException (java.io.IOException)2 DecimalFormat (java.text.DecimalFormat)2 LinkedList (java.util.LinkedList)2 TransientException (org.neo4j.driver.v1.exceptions.TransientException)2 IJsonInput (org.structr.core.IJsonInput)2 JsonInput (org.structr.core.JsonInput)2 InputStream (java.io.InputStream)1