Search in sources :

Example 11 with ContentType

use of com.zimbra.common.mime.ContentType 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;
                }
            } 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;
    }
    if (!authToken.isRegistered()) {
        resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "authtoken is invalid");
        return;
    }
    if (isAdmin && !authToken.isAdmin()) {
        resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "permission denied");
        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"));
    HttpRequestBase method = null;
    try {
        HttpClientBuilder clientBuilder = ZimbraHttpConnectionManager.getExternalHttpConnMgr().newHttpClient();
        HttpProxyUtil.configureProxy(clientBuilder);
        String reqMethod = req.getMethod();
        if (reqMethod.equalsIgnoreCase("GET")) {
            method = new HttpGet(target);
        } else if (reqMethod.equalsIgnoreCase("POST")) {
            HttpPost post = new HttpPost(target);
            if (body != null)
                post.setEntity(new ByteArrayEntity(body, org.apache.http.entity.ContentType.create(req.getContentType())));
            method = post;
        } else if (reqMethod.equalsIgnoreCase("PUT")) {
            HttpPut put = new HttpPut(target);
            if (body != null)
                put.setEntity(new ByteArrayEntity(body, org.apache.http.entity.ContentType.create(req.getContentType())));
            method = put;
        } else if (reqMethod.equalsIgnoreCase("DELETE")) {
            method = new HttpDelete(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;
            }
            CredentialsProvider provider = new BasicCredentialsProvider();
            provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(user, pass));
            clientBuilder.setDefaultCredentialsProvider(provider);
        }
        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.setHeader("Host", req.getHeader(hdr));
                else
                    method.addHeader(hdr, req.getHeader(hdr));
            }
        }
        HttpResponse httpResp = null;
        try {
            if (!(reqMethod.equalsIgnoreCase("POST") || reqMethod.equalsIgnoreCase("PUT"))) {
                clientBuilder.setRedirectStrategy(new DefaultRedirectStrategy());
            }
            HttpClient client = clientBuilder.build();
            httpResp = HttpClientUtil.executeMethod(client, method);
        } catch (HttpException ex) {
            ZimbraLog.zimlet.info("exception while proxying " + target, ex);
            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        int status = httpResp.getStatusLine() == null ? HttpServletResponse.SC_INTERNAL_SERVER_ERROR : httpResp.getStatusLine().getStatusCode();
        // workaround for Alexa Thumbnails paid web service, which doesn't bother to return a content-type line
        Header ctHeader = httpResp.getFirstHeader("Content-Type");
        String contentType = ctHeader == null || ctHeader.getValue() == null ? DEFAULT_CTYPE : ctHeader.getValue();
        // getEntity may return null if no response body (e.g. HTTP 204)
        InputStream targetResponseBody = null;
        HttpEntity targetResponseEntity = httpResp.getEntity();
        if (targetResponseEntity != null) {
            targetResponseBody = targetResponseEntity.getContent();
        }
        if (asUpload) {
            String filename = req.getParameter(FILENAME_PARAM);
            if (filename == null || filename.equals(""))
                filename = new ContentType(contentType).getParameter("name");
            if ((filename == null || filename.equals("")) && httpResp.getFirstHeader("Content-Disposition") != null)
                filename = new ContentDisposition(httpResp.getFirstHeader("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 : httpResp.getAllHeaders()) 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 : HttpPost(org.apache.http.client.methods.HttpPost) HttpRequestBase(org.apache.http.client.methods.HttpRequestBase) BasicCredentialsProvider(org.apache.http.impl.client.BasicCredentialsProvider) HttpDelete(org.apache.http.client.methods.HttpDelete) HttpEntity(org.apache.http.HttpEntity) ContentType(com.zimbra.common.mime.ContentType) HttpGet(org.apache.http.client.methods.HttpGet) Upload(com.zimbra.cs.service.FileUploadServlet.Upload) HttpClientBuilder(org.apache.http.impl.client.HttpClientBuilder) URL(java.net.URL) HttpPut(org.apache.http.client.methods.HttpPut) ByteArrayEntity(org.apache.http.entity.ByteArrayEntity) DefaultRedirectStrategy(org.apache.http.impl.client.DefaultRedirectStrategy) HttpException(org.apache.http.HttpException) Enumeration(java.util.Enumeration) InputStream(java.io.InputStream) HttpResponse(org.apache.http.HttpResponse) BasicCredentialsProvider(org.apache.http.impl.client.BasicCredentialsProvider) CredentialsProvider(org.apache.http.client.CredentialsProvider) UsernamePasswordCredentials(org.apache.http.auth.UsernamePasswordCredentials) Header(org.apache.http.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.http.client.HttpClient) AuthToken(com.zimbra.cs.account.AuthToken)

Example 12 with ContentType

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

the class ParseMimeMessage method attachUpload.

private static void attachUpload(MimeMultipart mmp, Upload up, String contentID, ParseMessageContext ctxt, ContentType ctypeOverride, String contentDescription, String contentDisposition) throws ServiceException, MessagingException {
    // make sure we haven't exceeded the max size
    ctxt.incrementSize("upload " + up.getName(), (long) (up.getSize() * 1.33));
    // scan upload for viruses
    StringBuffer info = new StringBuffer();
    UploadScanner.Result result = UploadScanner.accept(up, info);
    if (result == UploadScanner.REJECT) {
        throw MailServiceException.UPLOAD_REJECTED(up.getName(), info.toString());
    } else if (result == UploadScanner.ERROR) {
        throw MailServiceException.SCAN_ERROR(up.getName());
    }
    String filename = up.getName();
    // create the part and override the DataSource's default ctype, if required
    MimeBodyPart mbp = new ForceBase64MimeBodyPart();
    UploadDataSource uds = new UploadDataSource(up);
    if (ctypeOverride != null && !ctypeOverride.equals("")) {
        uds.setContentType(ctypeOverride);
    }
    mbp.setDataHandler(new DataHandler(uds));
    // set headers -- ctypeOverride non-null has magical properties that I'm going to regret tomorrow
    ContentType ctype = ctypeOverride;
    ContentDisposition cdisp;
    if (Part.INLINE.equalsIgnoreCase(contentDisposition)) {
        cdisp = new ContentDisposition(Part.INLINE, ctxt.use2231);
    } else {
        cdisp = new ContentDisposition(Part.ATTACHMENT, ctxt.use2231);
    }
    if (ctype == null) {
        ctype = new ContentType(up.getContentType() == null ? MimeConstants.CT_APPLICATION_OCTET_STREAM : up.getContentType());
        ctype.cleanup().setParameter("name", filename);
        cdisp.setParameter("filename", filename);
    }
    mbp.setHeader("Content-Type", ctype.setCharset(ctxt.defaultCharset).toString());
    mbp.setHeader("Content-Disposition", cdisp.setCharset(ctxt.defaultCharset).toString());
    if (contentDescription != null) {
        mbp.setHeader("Content-Description", contentDescription);
    }
    if (ctype.getContentType().equals(MimeConstants.CT_APPLICATION_PDF)) {
        mbp.setHeader("Content-Transfer-Encoding", "base64");
    }
    mbp.setContentID(contentID);
    // add to the parent part
    mmp.addBodyPart(mbp);
}
Also used : ContentType(com.zimbra.common.mime.ContentType) ContentDisposition(com.zimbra.common.mime.ContentDisposition) UploadDataSource(com.zimbra.cs.service.UploadDataSource) DataHandler(javax.activation.DataHandler) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart)

Example 13 with ContentType

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

the class ParseMimeMessage method attachMessage.

@SuppressWarnings("unchecked")
private static void attachMessage(MimeMultipart mmp, ItemId iid, String contentID, ParseMessageContext ctxt, boolean attachMessageFromCache) throws MessagingException, ServiceException {
    if (!iid.isLocal()) {
        attachRemoteItem(mmp, iid, contentID, ctxt, Collections.EMPTY_MAP, new ContentType(MimeConstants.CT_MESSAGE_RFC822));
        return;
    }
    Mailbox mbox = MailboxManager.getInstance().getMailboxByAccountId(iid.getAccountId());
    Message msg = mbox.getMessageById(ctxt.octxt, iid.getId());
    ctxt.incrementSize("attached message", msg.getSize());
    MimeBodyPart mbp = new ZMimeBodyPart();
    if (attachMessageFromCache && mbox.getAccount().isFeatureSMIMEEnabled() && (Mime.isEncrypted(msg.getMimeMessage(false).getContentType()) || Mime.isPKCS7Signed(msg.getMimeMessage(false).getContentType()))) {
        MimeMessage cachedMimeMessage = msg.getMimeMessage(true);
        mbp.setContent(cachedMimeMessage, MimeConstants.CT_MESSAGE_RFC822);
    } else {
        mbp.setDataHandler(new DataHandler(new MailboxBlobDataSource(msg.getBlob())));
        mbp.setHeader("Content-Type", MimeConstants.CT_MESSAGE_RFC822);
        mbp.setHeader("Content-Disposition", Part.ATTACHMENT);
    }
    mbp.setContentID(contentID);
    mmp.addBodyPart(mbp);
}
Also used : ContentType(com.zimbra.common.mime.ContentType) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) Message(com.zimbra.cs.mailbox.Message) MimeMessage(javax.mail.internet.MimeMessage) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) MailboxBlobDataSource(com.zimbra.cs.mime.MailboxBlobDataSource) DataHandler(javax.activation.DataHandler) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart)

Example 14 with ContentType

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

the class TnefConverter method expandTNEF.

/**
 * Performs the TNEF->MIME conversion on any TNEF body parts that
 * make up the given message.
 * @throws ServiceException
 */
private MimeMultipart expandTNEF(MimeBodyPart bp) throws MessagingException, IOException {
    if (!TNEFUtils.isTNEFMimeType(bp.getContentType()))
        return null;
    MimeMessage converted = null;
    // convert TNEF to a MimeMessage and remove it from the parent
    InputStream is = null;
    try {
        TNEFInputStream tnefis = new TNEFInputStream(is = bp.getInputStream());
        converted = TNEFMime.convert(JMSession.getSession(), tnefis);
    // XXX bburtin: nasty hack.  Don't handle OOME since JTNEF can allocate a huge byte
    // array when the TNEF file is malformed.  See bug 42649.
    // } catch (OutOfMemoryError e) {
    // Zimbra.halt("Ran out of memory while expanding TNEF attachment", e);
    } catch (Throwable t) {
        ZimbraLog.extensions.warn("Conversion failed.  TNEF attachment will not be expanded.", t);
        return null;
    } finally {
        ByteUtil.closeStream(is);
    }
    Object convertedContent = converted.getContent();
    if (!(convertedContent instanceof MimeMultipart)) {
        ZimbraLog.extensions.debug("TNEF attachment doesn't contain valid MimeMultiPart");
        return null;
    }
    MimeMultipart convertedMulti = (MimeMultipart) convertedContent;
    // make sure that all the attachments are marked as attachments
    for (int i = 0; i < convertedMulti.getCount(); i++) {
        BodyPart subpart = convertedMulti.getBodyPart(i);
        if (subpart.getHeader("Content-Disposition") == null)
            subpart.setHeader("Content-Disposition", Part.ATTACHMENT);
    }
    // Create a MimeBodyPart for the converted data.  Currently we're throwing
    // away the top-level message because its content shows up as blank after
    // the conversion.
    MimeBodyPart convertedPart = new ZMimeBodyPart();
    convertedPart.setContent(convertedMulti);
    // If the TNEF object contains calendar data, create an iCalendar version.
    MimeBodyPart icalPart = null;
    if (DebugConfig.enableTnefToICalendarConversion) {
        try {
            TnefToICalendar calConverter = new DefaultTnefToICalendar();
            ZCalendar.DefaultContentHandler icalHandler = new ZCalendar.DefaultContentHandler();
            if (calConverter.convert(mMimeMessage, bp.getInputStream(), icalHandler)) {
                if (icalHandler.getNumCals() > 0) {
                    List<ZVCalendar> cals = icalHandler.getCals();
                    Writer writer = new StringWriter(1024);
                    ICalTok method = null;
                    for (ZVCalendar cal : cals) {
                        cal.toICalendar(writer);
                        if (method == null)
                            method = cal.getMethod();
                    }
                    writer.close();
                    icalPart = new ZMimeBodyPart();
                    icalPart.setText(writer.toString());
                    ContentType ct = new ContentType(MimeConstants.CT_TEXT_CALENDAR);
                    ct.setCharset(MimeConstants.P_CHARSET_UTF8);
                    if (method != null)
                        ct.setParameter("method", method.toString());
                    icalPart.setHeader("Content-Type", ct.toString());
                }
            }
        } catch (ServiceException e) {
            throw new MessagingException("TNEF to iCalendar conversion failure: " + e.getMessage(), e);
        } catch (Throwable t) {
            // don't allow TNEF errors to crash server
            ZimbraLog.extensions.warn("Failed to convert TNEF to iCal", t);
            throw new MessagingException("TNEF to iCalendar conversion failure");
        }
    }
    // create a multipart/alternative for the TNEF and its MIME version
    MimeMultipart altMulti = new ZMimeMultipart("alternative");
    // altMulti.addBodyPart(bp);
    altMulti.addBodyPart(convertedPart);
    if (icalPart != null)
        altMulti.addBodyPart(icalPart);
    return altMulti;
}
Also used : ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart) BodyPart(javax.mail.BodyPart) ContentType(com.zimbra.common.mime.ContentType) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MessagingException(javax.mail.MessagingException) TNEFInputStream(net.freeutils.tnef.TNEFInputStream) InputStream(java.io.InputStream) TNEFInputStream(net.freeutils.tnef.TNEFInputStream) DefaultTnefToICalendar(com.zimbra.cs.util.tnef.DefaultTnefToICalendar) ICalTok(com.zimbra.common.calendar.ZCalendar.ICalTok) ZCalendar(com.zimbra.common.calendar.ZCalendar) ZVCalendar(com.zimbra.common.calendar.ZCalendar.ZVCalendar) StringWriter(java.io.StringWriter) ServiceException(com.zimbra.common.service.ServiceException) MimeMessage(javax.mail.internet.MimeMessage) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) TnefToICalendar(com.zimbra.cs.util.tnef.TnefToICalendar) DefaultTnefToICalendar(com.zimbra.cs.util.tnef.DefaultTnefToICalendar) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart) StringWriter(java.io.StringWriter) Writer(java.io.Writer)

Example 15 with ContentType

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

the class Mime method main.

public static void main(String[] args) throws MessagingException, IOException {
    String s = URLDecoder.decode("Zimbra%20&#26085;&#26412;&#35486;&#21270;&#12398;&#32771;&#24942;&#28857;.txt", "utf-8");
    System.out.println(s);
    System.out.println(expandNumericCharacterReferences("Zimbra%20&#26085;&#26412;&#35486;&#21270;&#12398;&#32771;&#24942;&#28857;.txt&#x40;&;&#;&#x;&#&#3876;&#55"));
    MimeMessage mm = new FixedMimeMessage(JMSession.getSession(), new SharedFileInputStream("C:\\Temp\\mail\\24245"));
    InputStream is = new RawContentMultipartDataSource(mm, new ContentType(mm.getContentType())).getInputStream();
    int num;
    byte[] buf = new byte[1024];
    while ((num = is.read(buf)) != -1) {
        System.out.write(buf, 0, num);
    }
}
Also used : ContentType(com.zimbra.common.mime.ContentType) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) SharedFileInputStream(javax.mail.util.SharedFileInputStream) BufferedInputStream(java.io.BufferedInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) PipedInputStream(java.io.PipedInputStream) SharedFileInputStream(javax.mail.util.SharedFileInputStream) FilterInputStream(java.io.FilterInputStream) InputStream(java.io.InputStream)

Aggregations

ContentType (com.zimbra.common.mime.ContentType)20 MimeBodyPart (javax.mail.internet.MimeBodyPart)8 MimeMessage (javax.mail.internet.MimeMessage)8 ContentDisposition (com.zimbra.common.mime.ContentDisposition)7 ZMimeBodyPart (com.zimbra.common.zmime.ZMimeBodyPart)6 Mailbox (com.zimbra.cs.mailbox.Mailbox)6 IOException (java.io.IOException)6 ServiceException (com.zimbra.common.service.ServiceException)5 InputStream (java.io.InputStream)5 Element (com.zimbra.common.soap.Element)4 ZMimeMessage (com.zimbra.common.zmime.ZMimeMessage)4 MimeMultipart (javax.mail.internet.MimeMultipart)4 MimePart (javax.mail.internet.MimePart)4 Account (com.zimbra.cs.account.Account)3 Document (com.zimbra.cs.mailbox.Document)3 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)3 Message (com.zimbra.cs.mailbox.Message)3 ByteArrayInputStream (java.io.ByteArrayInputStream)3 MessagingException (javax.mail.MessagingException)3 ZVCalendar (com.zimbra.common.calendar.ZCalendar.ZVCalendar)2