From 661419760563cccf6166c9c642dec3c3e9952c5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?= <99925035+tomas-sexenian@users.noreply.github.com> Date: Mon, 5 Aug 2024 10:40:17 -0300 Subject: [PATCH 1/2] Remove encoding from file download and beautify code --- .../genexus/internet/POP3SessionJavaMail.java | 466 ++++++++---------- 1 file changed, 201 insertions(+), 265 deletions(-) diff --git a/gxmail/src/main/java/com/genexus/internet/POP3SessionJavaMail.java b/gxmail/src/main/java/com/genexus/internet/POP3SessionJavaMail.java index 791f9788d..87aa454e7 100644 --- a/gxmail/src/main/java/com/genexus/internet/POP3SessionJavaMail.java +++ b/gxmail/src/main/java/com/genexus/internet/POP3SessionJavaMail.java @@ -1,8 +1,6 @@ package com.genexus.internet; import java.io.*; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; import java.util.Enumeration; import java.util.Hashtable; import java.util.Properties; @@ -27,8 +25,7 @@ import com.sun.mail.pop3.POP3Folder; import com.sun.mail.pop3.POP3Store; -public class POP3SessionJavaMail implements GXInternetConstants,IPOP3Session -{ +public class POP3SessionJavaMail implements GXInternetConstants, IPOP3Session { public static final ILogger logger = LogManager.getLogger(POP3SessionJavaMail.class); private String user; @@ -45,33 +42,30 @@ public class POP3SessionJavaMail implements GXInternetConstants,IPOP3Session private int numOfMessages; private int lastReadMessage; private StringCollection attachs; - + private Session session; private POP3Store emailStore; private Boolean downloadAttachments = false; - + Message[] messages; POP3Folder emailFolder; - public POP3SessionJavaMail() - { - } + public POP3SessionJavaMail() {} - public void login(GXPOP3Session sessionInfo) - { + public void login(GXPOP3Session sessionInfo) { this.pop3Host = sessionInfo.getHost(); this.pop3Port = sessionInfo.getPort(); - this.timeout = sessionInfo.getTimeout(); + this.timeout = sessionInfo.getTimeout(); this.user = sessionInfo.getUserName(); this.password = sessionInfo.getPassword(); - this.deleteOnRead = false; + this.deleteOnRead = false; this.readSinceLast = sessionInfo.getNewMessages() != 0; this.secureConnection = sessionInfo.getSecure() != 0; - + timeout = timeout * 1000; Properties props = new Properties(); props.setProperty("mail.pop3.host", pop3Host); - props.setProperty("mail.pop3.port", String.valueOf(pop3Port)); + props.setProperty("mail.pop3.port", String.valueOf(pop3Port)); props.setProperty("mail.pop3.connectiontimeout", String.valueOf(timeout)); props.setProperty("mail.pop3.timeout", String.valueOf(timeout)); @@ -84,339 +78,281 @@ public void login(GXPOP3Session sessionInfo) } props.setProperty("mail.pop3.ssl.enable", String.valueOf(secureConnection)); - + session = Session.getInstance(props); - if (logger.isDebugEnabled()) - { + if (logger.isDebugEnabled()) { session.setDebug(true); - } - try - { + } + try { emailStore = (POP3Store) session.getStore("pop3"); emailStore.connect(user, password); - + emailFolder = (POP3Folder) emailStore.getFolder("INBOX"); emailFolder.open(Folder.READ_WRITE); lastReadMessage = 0; - - if (readSinceLast) - { + + if (readSinceLast) { numOfMessages = emailFolder.getNewMessageCount(); - } - else - { + } else { numOfMessages = emailFolder.getMessageCount(); } messages = emailFolder.getMessages(); - } - catch(NoSuchProviderException e) - { - log (e.getMessage()); + } catch (NoSuchProviderException e) { + log(e.getMessage()); + sessionInfo.exceptionHandler(new GXMailException("Can't connect to mail server", MAIL_CantLogin)); + } catch (MessagingException me) { + log(me.getMessage()); sessionInfo.exceptionHandler(new GXMailException("Can't connect to mail server", MAIL_CantLogin)); } - catch(MessagingException me) - { - log (me.getMessage()); - sessionInfo.exceptionHandler(new GXMailException("Can't connect to mail server", MAIL_CantLogin)); - } } - public void logout(GXPOP3Session sessionInfo) - { - try - { + public void logout(GXPOP3Session sessionInfo) { + try { emailFolder.close(true); emailStore.close(); - } - catch (MessagingException e) - { - log (e.getMessage()); + } catch (MessagingException e) { + log(e.getMessage()); sessionInfo.exceptionHandler(new GXMailException(e.getMessage(), MAIL_ConnectionLost)); } } - public void delete(GXPOP3Session sessionInfo) - { - try - { - messages[lastReadMessage-1].setFlag(Flags.Flag.DELETED, true); - } - catch (MessagingException e) - { - log (e.getMessage()); + public void delete(GXPOP3Session sessionInfo) { + try { + messages[lastReadMessage - 1].setFlag(Flags.Flag.DELETED, true); + } catch (MessagingException e) { + log(e.getMessage()); sessionInfo.exceptionHandler(new GXMailException(e.getMessage(), MAIL_ServerRepliedErr)); } } - public void skip(GXPOP3Session sessionInfo) - { - try - { - if (lastReadMessage == numOfMessages) + public void skip(GXPOP3Session sessionInfo) { + try { + if (lastReadMessage == numOfMessages) throw new GXMailException("No messages to receive", MAIL_NoMessages); - + ++lastReadMessage; - } - catch (GXMailException e) - { + } catch (GXMailException e) { sessionInfo.exceptionHandler(e); - } + } } - - public void receive(GXPOP3Session sessionInfo, GXMailMessage gxmessage) - { - try - { + + public void receive(GXPOP3Session sessionInfo, GXMailMessage gxmessage) { + try { gxmessage.clear(); - setAttachmentsPath(sessionInfo.getAttachDir()); - - if (lastReadMessage +1 > numOfMessages) + setAttachmentsPath(sessionInfo.getAttachDir()); + + if (lastReadMessage + 1 > numOfMessages) throw new GXMailException("No messages to receive", MAIL_NoMessages); - + Message message = messages[lastReadMessage++]; - gxmessage.setFrom(getMailRecipient((InternetAddress)message.getFrom()[0])); - - - gxmessage.setTo(processRecipients(message, Message.RecipientType.TO)); + gxmessage.setFrom(getMailRecipient((InternetAddress) message.getFrom()[0])); + + gxmessage.setTo(processRecipients(message, Message.RecipientType.TO)); gxmessage.setCc(processRecipients(message, Message.RecipientType.CC)); gxmessage.setBcc(processRecipients(message, Message.RecipientType.BCC)); - + MailRecipientCollection mailRecipient = new MailRecipientCollection(); - for (int i = 0 ; i < message.getReplyTo().length; i++) - { - InternetAddress addr = ((InternetAddress)message.getReplyTo()[i]); - mailRecipient.addNew(addr.getPersonal(), addr.getAddress()); + for (int i = 0; i < message.getReplyTo().length; i++) { + InternetAddress addr = ((InternetAddress) message.getReplyTo()[i]); + mailRecipient.addNew(addr.getPersonal(), addr.getAddress()); } - + gxmessage.setReplyto(mailRecipient); - + gxmessage.setDateSent(message.getSentDate()); - gxmessage.setDateReceived(message.getReceivedDate() == null ? com.genexus.CommonUtil.now(): message.getReceivedDate()); - + gxmessage.setDateReceived(message.getReceivedDate() == null ? com.genexus.CommonUtil.now() : message.getReceivedDate()); + gxmessage.setSubject(message.getSubject()); Hashtable headers = new Hashtable(); - for (Enumeration en = message.getAllHeaders(); en.hasMoreElements(); ) - { + for (Enumeration en = message.getAllHeaders(); en.hasMoreElements();) { Header h = (Header) en.nextElement(); headers.put(h.getName(), h.getValue()); } gxmessage.setHeaders(headers); - + attachs = new StringCollection(); - Object content = message.getContent(); - if (content instanceof Multipart) - { - handleMultipart((Multipart)content, gxmessage); - } - else - { - handlePart(message, gxmessage); - } - } - catch (GXMailException e) - { + Object content = message.getContent(); + if (content instanceof Multipart) { + handleMultipart((Multipart) content, gxmessage); + } else { + handlePart(message, gxmessage); + } + } catch (GXMailException e) { sessionInfo.exceptionHandler(e); - } - catch (MessagingException e) - { - log (e.getMessage()); + } catch (MessagingException e) { + log(e.getMessage()); + sessionInfo.exceptionHandler(new GXMailException(e.getMessage(), MAIL_ServerRepliedErr)); + } catch (IOException e) { + log(e.getMessage()); sessionInfo.exceptionHandler(new GXMailException(e.getMessage(), MAIL_ServerRepliedErr)); - } - catch (IOException e) - { - log (e.getMessage()); - sessionInfo.exceptionHandler(new GXMailException(e.getMessage(), MAIL_ServerRepliedErr)); } } - - private MailRecipient getMailRecipient(InternetAddress inetAdd) - { - return new MailRecipient(inetAdd.getPersonal(), inetAdd.getAddress()); + + private MailRecipient getMailRecipient(InternetAddress inetAdd) { + return new MailRecipient(inetAdd.getPersonal(), inetAdd.getAddress()); } - - private MailRecipientCollection processRecipients(Message message, Message.RecipientType rType) throws MessagingException - { + + private MailRecipientCollection processRecipients(Message message, Message.RecipientType rType) throws MessagingException { MailRecipientCollection mailRecipient = new MailRecipientCollection(); try { - if (message.getRecipients(rType) != null) - { - for (int i = 0 ; i < message.getRecipients(rType).length; i++) - { - InternetAddress address = (InternetAddress)message.getRecipients(rType)[i]; + if (message.getRecipients(rType) != null) { + for (int i = 0; i < message.getRecipients(rType).length; i++) { + InternetAddress address = (InternetAddress) message.getRecipients(rType)[i]; mailRecipient.addNew(address.getPersonal(), address.getAddress()); } } return mailRecipient; } catch (AddressException e) { - /* - Some email clients like Gmail separate the list of addresses using commas while others like Outlook separate them using - semicolons. This is a hack to consider the case where the list of addresses is separated with semicolons which produces - an exception because the InternetAddress class used by jakarta mail to parse the addresses expects the list to be separated by commas - */ - String[] addresses = message.getHeader(rType.toString()); + /* + Some email clients like Gmail separate the list of addresses using commas while others like Outlook separate them using + semicolons. This is a hack to consider the case where the list of addresses is separated with semicolons which produces + an exception because the InternetAddress class used by jakarta mail to parse the addresses expects the list to be separated by commas + */ + String[] addresses = message.getHeader(rType.toString()); if (addresses != null && addresses.length > 0) { - for (String address : addresses) { + for (String address: addresses) { String[] splitAddresses = address.split(";"); - for (String splitAddress : splitAddresses){ + for (String splitAddress: splitAddresses) { InternetAddress ia = new InternetAddress(splitAddress); - mailRecipient.addNew(ia.getPersonal(),ia.getAddress()); + mailRecipient.addNew(ia.getPersonal(), ia.getAddress()); } } } return mailRecipient; } } - - private void handleMultipart(Multipart multipart, GXMailMessage gxmessage) throws MessagingException, IOException - { - for (int i=0, n=multipart.getCount(); i")) { + cid = cids[0].substring(1, cids[0].length() - 1); + } + return cid; + } + + private void saveFile(String filename, InputStream input) throws IOException { + filename = filename.replace("/", "_") + .replace("\\", "_") + .replace(":", "_") + .replace("*", "_") + .replace("?", "_") + .replace("\"", "_") + .replace("<", "_") + .replace(">", "_") + .replace("|", "_"); - try (InputStream is = part.getContent() instanceof MimeMessage ? ((MimeMessage) part.getContent()).getInputStream() : part.getInputStream()){ - saveFile(fileName, is); + File file = new File(attachmentsPath + filename); + + try (FileOutputStream fos = new FileOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream(fos); BufferedInputStream bis = new BufferedInputStream(input)) { + int aByte; + while ((aByte = bis.read()) != -1) { + bos.write(aByte); + } + bos.flush(); + } catch (IOException e) { + throw new IOException("Error while writing the file", e); } - attachs.add(attachmentsPath + fileName); - gxmessage.setAttachments(attachs); - } - } - - private String getAttachmentContentId(Part part) throws MessagingException - { - String cid = ""; - String[] cids = part.getHeader("Content-ID"); - if (cids != null && !cids[0].isEmpty() && cids[0].startsWith("<") && cids[0].endsWith(">")) - { - cid = cids[0].substring(1, cids[0].length() - 1); - } - return cid; - } - - private void saveFile(String filename, InputStream input) throws IOException - { - try { - String encodedFilename = URLEncoder.encode(filename, StandardCharsets.UTF_8.toString()); - encodedFilename = encodedFilename.replace("+", "_"); - File file = new File(attachmentsPath + encodedFilename); - try (FileOutputStream fos = new FileOutputStream(file); - BufferedOutputStream bos = new BufferedOutputStream(fos); - BufferedInputStream bis = new BufferedInputStream(input)) { - int aByte; - while ((aByte = bis.read()) != -1) { - bos.write(aByte); - } - bos.flush(); - } - } catch (UnsupportedEncodingException e) { - throw new IOException("Error encoding the filename", e); - } - } - - public String getNextUID() throws GXMailException - { - try - { - if (lastReadMessage == numOfMessages) + } + + public String getNextUID() throws GXMailException { + try { + if (lastReadMessage == numOfMessages) throw new GXMailException("No messages to receive", MAIL_NoMessages); - - int messageNum = lastReadMessage +1; + + int messageNum = lastReadMessage + 1; return emailFolder.getUID(emailFolder.getMessage(messageNum)); - } - catch (MessagingException e) - { - log (e.getMessage()); + } catch (MessagingException e) { + log(e.getMessage()); throw new GXMailException(e.getMessage(), MAIL_ServerRepliedErr); - } + } } - - public int getMessageCount() throws GXMailException - { - try - { - if (readSinceLast) + + public int getMessageCount() throws GXMailException { + try { + if (readSinceLast) return emailFolder.getNewMessageCount(); return emailFolder.getMessageCount(); - } - catch (MessagingException e) - { - log (e.getMessage()); + } catch (MessagingException e) { + log(e.getMessage()); throw new GXMailException(e.getMessage(), MAIL_ServerRepliedErr); } } - public void setAttachmentsPath(String _attachmentsPath) - { + public void setAttachmentsPath(String _attachmentsPath) { attachmentsPath = _attachmentsPath.trim(); - if (!attachmentsPath.equals("")) - { + if (!attachmentsPath.equals("")) { this.downloadAttachments = true; - } - if(!attachmentsPath.equals("") && !attachmentsPath.endsWith(File.separator))attachmentsPath += File.separator; + } + if (!attachmentsPath.equals("") && !attachmentsPath.endsWith(File.separator)) attachmentsPath += File.separator; } - - private void log(String text) - { + + private void log(String text) { logger.debug(text); } } \ No newline at end of file From e396e18506d82d95365ad9c7d85a80b95bc83154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?= <99925035+tomas-sexenian@users.noreply.github.com> Date: Wed, 9 Oct 2024 02:53:20 -0300 Subject: [PATCH 2/2] Encode using UTF-8 if return has funny characters Issue:201744 --- java/src/main/java/com/genexus/internet/HttpClientJavaLib.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/java/src/main/java/com/genexus/internet/HttpClientJavaLib.java b/java/src/main/java/com/genexus/internet/HttpClientJavaLib.java index a3fd0de21..662d47cb0 100644 --- a/java/src/main/java/com/genexus/internet/HttpClientJavaLib.java +++ b/java/src/main/java/com/genexus/internet/HttpClientJavaLib.java @@ -730,6 +730,9 @@ public String getString() { charset = StandardCharsets.UTF_8; } String res = EntityUtils.toString(entity, charset); + if (res.matches(".*[Ã-ÿ].*")) { + res = EntityUtils.toString(entity, StandardCharsets.UTF_8); + } eof = true; return res; } catch (IOException e) {