From ac8fe8261eae35452f0fd02ecced0fd9a421c6f9 Mon Sep 17 00:00:00 2001 From: "kuldeep.k@cisinlabs.com" Date: Wed, 23 Feb 2022 20:15:56 +0530 Subject: [PATCH 1/3] Updated the smtp client object handling logic by thread local client variable --- main.py | 74 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/main.py b/main.py index e0554d3..b163b93 100644 --- a/main.py +++ b/main.py @@ -13,11 +13,18 @@ from email.mime.text import MIMEText import cherrypy import logging +import threading + logging.basicConfig(stream=sys.stdout, format='%(name)s - %(levelname)s - %(message)s') +def soft_return(msg): + time.sleep(0.2) + return(msg) + + class SMTPWebhookApp: """ SMTP webhook server @@ -49,33 +56,49 @@ class SMTPWebhookApp: body = req_body['body'] to_mail = req_body['to_mail'] - try: - client = smtplib.SMTP(host=SMTP_SERVER_HOST, port=SMTP_SERVER_PORT) - except (smtplib.SMTPConnectionError, TimeoutError) as e: - time.sleep(0.2) - logging.error("To: {}, error: {}".format(to_mail, e)) - return {"status": 400, "message": "SMTP client error: {}.".format( - e)} - msg = MIMEText(body, 'plain', 'utf-8') msg['Subject'] = Header(subject, 'utf-8') msg['From'] = FROM_MAIL msg['To'] = to_mail - try: - client.ehlo() - client.starttls() - client.ehlo() - client.login(msg["From"], FROM_MAIL_PASSWORD) - client.sendmail(msg['From'], msg['To'], msg.as_string()) - response = {"status": 200, "message": "mail sent successfully"} - logging.info("To: {}, mail sent successfully".format(to_mail)) - except smtplib.SMTPException as e: - time.sleep(0.2) - logging.error("To: {}, error: {}".format(to_mail, e)) - response = {"status": 500, "message": "some error: {}".format(e)} - finally: - client.quit() - return response + + c = 0 + while (c < 2): + try: + mythread.client.sendmail(msg['From'], + msg['To'], msg.as_string()) + response = {"status": 200, "message": "mail sent successfully"} + except (AttributeError, ValueError, + smtplib.SMTPServerDisconnected): + if (c == 1): + soft_return("can't connect") + try: + print("- - - - - CREATING CLIENT - - - - -") + mythread.client = smtplib.SMTP(host=SMTP_SERVER_HOST, + port=SMTP_SERVER_PORT) + mythread.client.starttls() + except (smtplib.SMTPException, TimeoutError) as e: + soft_return("can't connect") + response = {"status": 500, + "message": "some error: {}".format(e)} + print("response1: ", response) + + try: + mythread.client.login(msg["From"], FROM_MAIL_PASSWORD) + except smtplib.SMTPException as e: + soft_return(e) + response = {"status": 500, + "message": "some error: {}".format(e)} + print("response2: ", response) + + except smtplib.SMTPException as e: + soft_return("can't send for some reason") + response = {"status": 500, + "message": "some error: {}".format(e)} + print("response3: ", response) + finally: + c += 1 + + return response @cherrypy.expose def send_mail(self): @@ -89,7 +112,6 @@ class SMTPWebhookApp: ROOT = SMTPWebhookApp() - SMTP_SERVER_PORT = 587 CHERRYPY_SERVER_HOST = "0.0.0.0" CHERRYPY_SERVER_PORT = 8081 @@ -109,6 +131,10 @@ if __name__ == "__main__": ENGINE = cherrypy.engine cherrypy.tree.mount(ROOT, config={}) + mythread = threading.local() + mythread.client = smtplib.SMTP(host=SMTP_SERVER_HOST, + port=SMTP_SERVER_PORT) + mythread.client.starttls() if hasattr(ENGINE, "signal_handler"): ENGINE.signal_handler.subscribe() -- 2.40.1 From f7d6fa0488bc6be6851335d47f1b003d4a3d1c31 Mon Sep 17 00:00:00 2001 From: "kuldeep.k@cisinlabs.com" Date: Thu, 24 Feb 2022 20:59:12 +0530 Subject: [PATCH 2/3] Updated code and seperated in functions --- main.py | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/main.py b/main.py index b163b93..a852c9f 100644 --- a/main.py +++ b/main.py @@ -30,6 +30,27 @@ class SMTPWebhookApp: SMTP webhook server """ + def create_new_client(self, response): + try: + print("- - - - - CREATING CLIENT - - - - -") + mythread.client = smtplib.SMTP(host=SMTP_SERVER_HOST, + port=SMTP_SERVER_PORT) + mythread.client.starttls() + except (smtplib.SMTPException, TimeoutError) as e: + soft_return("can't connect") + response = {"status": 500, + "message": "some error: {}".format(e)} + print("response1: ", response) + + def smtp_login(self, response, msg): + try: + mythread.client.login(msg["From"], FROM_MAIL_PASSWORD) + except smtplib.SMTPException as e: + soft_return(e) + response = {"status": 500, + "message": "some error: {}".format(e)} + print("response2: ", response) + def _send_mail(self): if not cherrypy.request.headers.get('Content-Length'): @@ -62,6 +83,7 @@ class SMTPWebhookApp: msg['To'] = to_mail c = 0 + response = {} while (c < 2): try: mythread.client.sendmail(msg['From'], @@ -71,24 +93,9 @@ class SMTPWebhookApp: smtplib.SMTPServerDisconnected): if (c == 1): soft_return("can't connect") - try: - print("- - - - - CREATING CLIENT - - - - -") - mythread.client = smtplib.SMTP(host=SMTP_SERVER_HOST, - port=SMTP_SERVER_PORT) - mythread.client.starttls() - except (smtplib.SMTPException, TimeoutError) as e: - soft_return("can't connect") - response = {"status": 500, - "message": "some error: {}".format(e)} - print("response1: ", response) - try: - mythread.client.login(msg["From"], FROM_MAIL_PASSWORD) - except smtplib.SMTPException as e: - soft_return(e) - response = {"status": 500, - "message": "some error: {}".format(e)} - print("response2: ", response) + self.create_new_client(response) + self.smtp_login(response, msg) except smtplib.SMTPException as e: soft_return("can't send for some reason") @@ -132,10 +139,7 @@ if __name__ == "__main__": cherrypy.tree.mount(ROOT, config={}) mythread = threading.local() - mythread.client = smtplib.SMTP(host=SMTP_SERVER_HOST, - port=SMTP_SERVER_PORT) - mythread.client.starttls() - + mythread.client = None if hasattr(ENGINE, "signal_handler"): ENGINE.signal_handler.subscribe() if hasattr(ENGINE, "console_control_handler"): -- 2.40.1 From bd83b013621b4fd1110368d753ee889600a8f708 Mon Sep 17 00:00:00 2001 From: "kuldeep.k@cisinlabs.com" Date: Fri, 25 Feb 2022 19:18:37 +0530 Subject: [PATCH 3/3] Added boolean return to functions & added break based on functions response --- main.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/main.py b/main.py index a852c9f..f4cce94 100644 --- a/main.py +++ b/main.py @@ -32,24 +32,25 @@ class SMTPWebhookApp: def create_new_client(self, response): try: - print("- - - - - CREATING CLIENT - - - - -") mythread.client = smtplib.SMTP(host=SMTP_SERVER_HOST, port=SMTP_SERVER_PORT) mythread.client.starttls() + return True except (smtplib.SMTPException, TimeoutError) as e: soft_return("can't connect") - response = {"status": 500, + response = {"status": 500, # noqa:F841 "message": "some error: {}".format(e)} - print("response1: ", response) + return False def smtp_login(self, response, msg): try: mythread.client.login(msg["From"], FROM_MAIL_PASSWORD) + return True except smtplib.SMTPException as e: soft_return(e) - response = {"status": 500, + response = {"status": 500, # noqa:F841 "message": "some error: {}".format(e)} - print("response2: ", response) + return False def _send_mail(self): @@ -94,14 +95,15 @@ class SMTPWebhookApp: if (c == 1): soft_return("can't connect") - self.create_new_client(response) - self.smtp_login(response, msg) + if not self.create_new_client(response): + break + if not self.smtp_login(response, msg): + break except smtplib.SMTPException as e: soft_return("can't send for some reason") response = {"status": 500, "message": "some error: {}".format(e)} - print("response3: ", response) finally: c += 1 -- 2.40.1