Search in sources :

Example 11 with ContentDisposition

use of com.zimbra.common.mime.ContentDisposition in project zm-mailbox by Zimbra.

the class ParsedContact method generateMimeMessage.

private static MimeMessage generateMimeMessage(List<Attachment> attachments) throws MessagingException {
    MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSession());
    MimeMultipart multi = new ZMimeMultipart("mixed");
    int part = 1;
    for (Attachment attach : attachments) {
        ContentDisposition cdisp = new ContentDisposition(Part.ATTACHMENT);
        cdisp.setParameter("filename", attach.getFilename()).setParameter("field", attach.getName());
        MimeBodyPart bp = new ZMimeBodyPart();
        // it gets called before setting Content-Type and CTE headers.
        try {
            bp.setDataHandler(new DataHandler(new ByteArrayDataSource(attach.getContent(), attach.getContentType())));
        } catch (IOException e) {
            throw new MessagingException("could not generate mime part content", e);
        }
        bp.addHeader("Content-Disposition", cdisp.toString());
        bp.addHeader("Content-Type", attach.getContentType());
        bp.addHeader("Content-Transfer-Encoding", MimeConstants.ET_8BIT);
        multi.addBodyPart(bp);
        attach.setPartName(Integer.toString(part++));
    }
    mm.setContent(multi);
    mm.saveChanges();
    return mm;
}
Also used : ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MessagingException(javax.mail.MessagingException) Attachment(com.zimbra.cs.mailbox.Contact.Attachment) DataHandler(javax.activation.DataHandler) IOException(java.io.IOException) ContentDisposition(com.zimbra.common.mime.ContentDisposition) MimeMessage(javax.mail.internet.MimeMessage) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart) ByteArrayDataSource(javax.mail.util.ByteArrayDataSource)

Example 12 with ContentDisposition

use of com.zimbra.common.mime.ContentDisposition in project zm-mailbox by Zimbra.

the class ProxyServlet method doProxy.

private void doProxy(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    ZimbraLog.clearContext();
    boolean isAdmin = isAdminRequest(req);
    AuthToken authToken = isAdmin ? getAdminAuthTokenFromCookie(req, resp, true) : getAuthTokenFromCookie(req, resp, true);
    if (authToken == null) {
        String zAuthToken = req.getParameter(QP_ZAUTHTOKEN);
        if (zAuthToken != null) {
            try {
                authToken = AuthProvider.getAuthToken(zAuthToken);
                if (authToken.isExpired()) {
                    resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "authtoken expired");
                    return;
                }
                if (!authToken.isRegistered()) {
                    resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "authtoken is invalid");
                    return;
                }
                if (isAdmin && !authToken.isAdmin()) {
                    resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "permission denied");
                    return;
                }
            } catch (AuthTokenException e) {
                resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "unable to parse authtoken");
                return;
            }
        }
    }
    if (authToken == null) {
        resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "no authtoken cookie");
        return;
    }
    // get the posted body before the server read and parse them.
    byte[] body = copyPostedData(req);
    // sanity check
    String target = req.getParameter(TARGET_PARAM);
    if (target == null) {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
        return;
    }
    // check for permission
    URL url = new URL(target);
    if (!isAdmin && !checkPermissionOnTarget(url, authToken)) {
        resp.sendError(HttpServletResponse.SC_FORBIDDEN);
        return;
    }
    // determine whether to return the target inline or store it as an upload
    String uploadParam = req.getParameter(UPLOAD_PARAM);
    boolean asUpload = uploadParam != null && (uploadParam.equals("1") || uploadParam.equalsIgnoreCase("true"));
    HttpMethod method = null;
    try {
        HttpClient client = ZimbraHttpConnectionManager.getExternalHttpConnMgr().newHttpClient();
        HttpProxyUtil.configureProxy(client);
        String reqMethod = req.getMethod();
        if (reqMethod.equalsIgnoreCase("GET")) {
            method = new GetMethod(target);
        } else if (reqMethod.equalsIgnoreCase("POST")) {
            PostMethod post = new PostMethod(target);
            if (body != null)
                post.setRequestEntity(new ByteArrayRequestEntity(body, req.getContentType()));
            method = post;
        } else if (reqMethod.equalsIgnoreCase("PUT")) {
            PutMethod put = new PutMethod(target);
            if (body != null)
                put.setRequestEntity(new ByteArrayRequestEntity(body, req.getContentType()));
            method = put;
        } else if (reqMethod.equalsIgnoreCase("DELETE")) {
            method = new DeleteMethod(target);
        } else {
            ZimbraLog.zimlet.info("unsupported request method: " + reqMethod);
            resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
            return;
        }
        // handle basic auth
        String auth, user, pass;
        auth = req.getParameter(AUTH_PARAM);
        user = req.getParameter(USER_PARAM);
        pass = req.getParameter(PASS_PARAM);
        if (auth != null && user != null && pass != null) {
            if (!auth.equals(AUTH_BASIC)) {
                ZimbraLog.zimlet.info("unsupported auth type: " + auth);
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
                return;
            }
            HttpState state = new HttpState();
            state.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(user, pass));
            client.setState(state);
            method.setDoAuthentication(true);
        }
        Enumeration headers = req.getHeaderNames();
        while (headers.hasMoreElements()) {
            String hdr = (String) headers.nextElement();
            ZimbraLog.zimlet.debug("incoming: " + hdr + ": " + req.getHeader(hdr));
            if (canProxyHeader(hdr)) {
                ZimbraLog.zimlet.debug("outgoing: " + hdr + ": " + req.getHeader(hdr));
                if (hdr.equalsIgnoreCase("x-host"))
                    method.getParams().setVirtualHost(req.getHeader(hdr));
                else
                    method.addRequestHeader(hdr, req.getHeader(hdr));
            }
        }
        try {
            if (!(reqMethod.equalsIgnoreCase("POST") || reqMethod.equalsIgnoreCase("PUT"))) {
                method.setFollowRedirects(true);
            }
            HttpClientUtil.executeMethod(client, method);
        } catch (HttpException ex) {
            ZimbraLog.zimlet.info("exception while proxying " + target, ex);
            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        int status = method.getStatusLine() == null ? HttpServletResponse.SC_INTERNAL_SERVER_ERROR : method.getStatusCode();
        // workaround for Alexa Thumbnails paid web service, which doesn't bother to return a content-type line
        Header ctHeader = method.getResponseHeader("Content-Type");
        String contentType = ctHeader == null || ctHeader.getValue() == null ? DEFAULT_CTYPE : ctHeader.getValue();
        InputStream targetResponseBody = method.getResponseBodyAsStream();
        if (asUpload) {
            String filename = req.getParameter(FILENAME_PARAM);
            if (filename == null || filename.equals(""))
                filename = new ContentType(contentType).getParameter("name");
            if ((filename == null || filename.equals("")) && method.getResponseHeader("Content-Disposition") != null)
                filename = new ContentDisposition(method.getResponseHeader("Content-Disposition").getValue()).getParameter("filename");
            if (filename == null || filename.equals(""))
                filename = "unknown";
            List<Upload> uploads = null;
            if (targetResponseBody != null) {
                try {
                    Upload up = FileUploadServlet.saveUpload(targetResponseBody, filename, contentType, authToken.getAccountId());
                    uploads = Arrays.asList(up);
                } catch (ServiceException e) {
                    if (e.getCode().equals(MailServiceException.UPLOAD_REJECTED))
                        status = HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE;
                    else
                        status = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
                }
            }
            resp.setStatus(status);
            FileUploadServlet.sendResponse(resp, status, req.getParameter(FORMAT_PARAM), null, uploads, null);
        } else {
            resp.setStatus(status);
            resp.setContentType(contentType);
            for (Header h : method.getResponseHeaders()) if (canProxyHeader(h.getName()))
                resp.addHeader(h.getName(), h.getValue());
            if (targetResponseBody != null)
                ByteUtil.copy(targetResponseBody, true, resp.getOutputStream(), true);
        }
    } finally {
        if (method != null)
            method.releaseConnection();
    }
}
Also used : ContentType(com.zimbra.common.mime.ContentType) PostMethod(org.apache.commons.httpclient.methods.PostMethod) HttpState(org.apache.commons.httpclient.HttpState) Upload(com.zimbra.cs.service.FileUploadServlet.Upload) URL(java.net.URL) HttpException(org.apache.commons.httpclient.HttpException) DeleteMethod(org.apache.commons.httpclient.methods.DeleteMethod) Enumeration(java.util.Enumeration) InputStream(java.io.InputStream) UsernamePasswordCredentials(org.apache.commons.httpclient.UsernamePasswordCredentials) Header(org.apache.commons.httpclient.Header) ContentDisposition(com.zimbra.common.mime.ContentDisposition) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) AuthTokenException(com.zimbra.cs.account.AuthTokenException) HttpClient(org.apache.commons.httpclient.HttpClient) GetMethod(org.apache.commons.httpclient.methods.GetMethod) AuthToken(com.zimbra.cs.account.AuthToken) PutMethod(org.apache.commons.httpclient.methods.PutMethod) HttpMethod(org.apache.commons.httpclient.HttpMethod) ByteArrayRequestEntity(org.apache.commons.httpclient.methods.ByteArrayRequestEntity)

Example 13 with ContentDisposition

use of com.zimbra.common.mime.ContentDisposition in project zm-mailbox by Zimbra.

the class ContentServlet method retrieveUpload.

private void retrieveUpload(HttpServletRequest req, HttpServletResponse resp, AuthToken authToken) throws IOException {
    // if it's another server fetching an already-uploaded file, just do that
    String uploadId = req.getParameter(PARAM_UPLOAD_ID);
    if (uploadId == null) {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, L10nUtil.getMessage(MsgKey.errMissingUploadId, req));
        return;
    }
    try {
        if (!FileUploadServlet.isLocalUpload(uploadId)) {
            // wrong server; proxy to the right one...
            String serverId = FileUploadServlet.getUploadServerId(uploadId);
            Server server = Provisioning.getInstance().get(Key.ServerBy.id, serverId);
            proxyServletRequest(req, resp, server, null);
            return;
        }
        Upload up = FileUploadServlet.fetchUpload(authToken.getAccountId(), uploadId, authToken);
        if (up == null) {
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, L10nUtil.getMessage(MsgKey.errNoSuchUpload, req));
            return;
        }
        String filename = up.getName();
        ContentDisposition cd = new ContentDisposition(Part.ATTACHMENT).setParameter("filename", filename == null ? "unknown" : filename);
        resp.addHeader("Content-Disposition", cd.toString());
        sendbackOriginalDoc(up.getInputStream(), up.getContentType(), resp);
        boolean expunge = "true".equalsIgnoreCase(req.getParameter(PARAM_EXPUNGE)) || "1".equals(req.getParameter(PARAM_EXPUNGE));
        if (expunge)
            FileUploadServlet.deleteUpload(up);
    } catch (ServiceException e) {
        returnError(resp, e);
    }
}
Also used : Server(com.zimbra.cs.account.Server) ContentDisposition(com.zimbra.common.mime.ContentDisposition) ServiceException(com.zimbra.common.service.ServiceException) Upload(com.zimbra.cs.service.FileUploadServlet.Upload)

Example 14 with ContentDisposition

use of com.zimbra.common.mime.ContentDisposition in project zm-mailbox by Zimbra.

the class FileUploadServlet method handlePlainUpload.

/**
     * This is used when handling a POST request generated by {@link ZMailbox#uploadContentAsStream}
     *
     * @param req
     * @param resp
     * @param fmt
     * @param acct
     * @param limitByFileUploadMaxSize
     * @return
     * @throws IOException
     * @throws ServiceException
     */
List<Upload> handlePlainUpload(HttpServletRequest req, HttpServletResponse resp, String fmt, Account acct, boolean limitByFileUploadMaxSize) throws IOException, ServiceException {
    // metadata is encoded in the response's HTTP headers
    ContentType ctype = new ContentType(req.getContentType());
    String contentType = ctype.getContentType(), filename = ctype.getParameter("name");
    if (filename == null) {
        filename = new ContentDisposition(req.getHeader("Content-Disposition")).getParameter("filename");
    }
    if (filename == null || filename.trim().equals("")) {
        mLog.info("Rejecting upload with no name.");
        drainRequestStream(req);
        sendResponse(resp, HttpServletResponse.SC_NO_CONTENT, fmt, null, null, null);
        return Collections.emptyList();
    }
    // Unescape the filename so it actually displays correctly
    filename = StringEscapeUtils.unescapeHtml(filename);
    // store the fetched file as a normal upload
    ServletFileUpload upload = getUploader2(limitByFileUploadMaxSize);
    FileItem fi = upload.getFileItemFactory().createItem("upload", contentType, false, filename);
    try {
        // write the upload to disk, but make sure not to exceed the permitted max upload size
        long size = ByteUtil.copy(req.getInputStream(), false, fi.getOutputStream(), true, upload.getSizeMax() * 3);
        if ((upload.getSizeMax() >= 0) && (size > upload.getSizeMax())) {
            mLog.debug("handlePlainUpload(): deleting %s", fi);
            fi.delete();
            mLog.info("Exceeded maximum upload size of " + upload.getSizeMax() + " bytes: " + acct.getId());
            drainRequestStream(req);
            sendResponse(resp, HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE, fmt, null, null, null);
            return Collections.emptyList();
        }
    } catch (IOException ioe) {
        mLog.warn("Unable to store upload.  Deleting %s", fi, ioe);
        fi.delete();
        drainRequestStream(req);
        sendResponse(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, fmt, null, null, null);
        return Collections.emptyList();
    }
    List<FileItem> items = new ArrayList<FileItem>(1);
    items.add(fi);
    Upload up = new Upload(acct.getId(), fi, filename);
    mLog.info("Received plain: %s", up);
    synchronized (mPending) {
        mPending.put(up.uuid, up);
    }
    List<Upload> uploads = Arrays.asList(up);
    sendResponse(resp, HttpServletResponse.SC_OK, fmt, null, uploads, items);
    return uploads;
}
Also used : DefaultFileItem(org.apache.commons.fileupload.DefaultFileItem) FileItem(org.apache.commons.fileupload.FileItem) DiskFileItem(org.apache.commons.fileupload.disk.DiskFileItem) ServletFileUpload(org.apache.commons.fileupload.servlet.ServletFileUpload) ContentType(com.zimbra.common.mime.ContentType) ContentDisposition(com.zimbra.common.mime.ContentDisposition) ArrayList(java.util.ArrayList) ServletFileUpload(org.apache.commons.fileupload.servlet.ServletFileUpload) IOException(java.io.IOException)

Example 15 with ContentDisposition

use of com.zimbra.common.mime.ContentDisposition in project zm-mailbox by Zimbra.

the class UserServlet method getRemoteResourceAsUpload.

public static FileUploadServlet.Upload getRemoteResourceAsUpload(AuthToken at, ItemId iid, Map<String, String> params) throws ServiceException, IOException {
    Map<String, String> pcopy = new HashMap<String, String>(params);
    pcopy.put(QP_ID, iid.toString());
    // fetch from remote store
    Provisioning prov = Provisioning.getInstance();
    Account target = prov.get(AccountBy.id, iid.getAccountId(), at);
    String url = getRemoteUrl(target, null, pcopy);
    Pair<Header[], HttpInputStream> response = getRemoteResourceAsStream(at.toZAuthToken(), url);
    // and save the result as an upload
    String ctype = "text/plain", filename = null;
    for (Header hdr : response.getFirst()) {
        String hname = hdr.getName().toLowerCase();
        if (hname.equals("content-type"))
            ctype = hdr.getValue();
        else if (hname.equals("content-disposition"))
            filename = new ContentDisposition(hdr.getValue()).getParameter("filename");
    }
    if (filename == null || filename.equals(""))
        filename = new ContentType(ctype).getParameter("name");
    if (filename == null || filename.equals(""))
        filename = "unknown";
    return FileUploadServlet.saveUpload(response.getSecond(), filename, ctype, at.getAccountId());
}
Also used : Account(com.zimbra.cs.account.Account) Header(org.apache.commons.httpclient.Header) ContentDisposition(com.zimbra.common.mime.ContentDisposition) ContentType(com.zimbra.common.mime.ContentType) HashMap(java.util.HashMap) Provisioning(com.zimbra.cs.account.Provisioning)

Aggregations

ContentDisposition (com.zimbra.common.mime.ContentDisposition)18 ContentType (com.zimbra.common.mime.ContentType)8 ZMimeBodyPart (com.zimbra.common.zmime.ZMimeBodyPart)8 IOException (java.io.IOException)7 MimeBodyPart (javax.mail.internet.MimeBodyPart)7 ServiceException (com.zimbra.common.service.ServiceException)6 DataHandler (javax.activation.DataHandler)6 ZMimeMultipart (com.zimbra.common.zmime.ZMimeMultipart)5 MessagingException (javax.mail.MessagingException)5 MimeMessage (javax.mail.internet.MimeMessage)5 MimeMultipart (javax.mail.internet.MimeMultipart)5 Server (com.zimbra.cs.account.Server)4 ByteArrayDataSource (javax.mail.util.ByteArrayDataSource)4 AuthToken (com.zimbra.cs.account.AuthToken)3 Provisioning (com.zimbra.cs.account.Provisioning)3 InputStream (java.io.InputStream)3 ServletFileUpload (org.apache.commons.fileupload.servlet.ServletFileUpload)3 Header (org.apache.commons.httpclient.Header)3 Attachment (com.zimbra.cs.mailbox.Contact.Attachment)2 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)2