Skip to content

Cherrypy ssl error #354

Description

@DogAteMyCode

It is a simple cherrypy server, however after the server running fine for 1-2 hours I get this error and it becomes unresponsive. How can I fix this

StackOverflow
I added this to stack overflow if you prefer to see it there

[27/Dec/2020:09:46:29] ENGINE Error in HTTPServer.serve
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/cheroot/server.py", line 1810, in serve
    self._connections.run(self.expiration_interval)
  File "/usr/local/lib/python3.9/site-packages/cheroot/connections.py", line 201, in run
    self._run(expiration_interval)
  File "/usr/local/lib/python3.9/site-packages/cheroot/connections.py", line 218, in _run
    new_conn = self._from_server_socket(self.server.socket)
  File "/usr/local/lib/python3.9/site-packages/cheroot/connections.py", line 271, in _from_server_socket
    s, ssl_env = self.server.ssl_adapter.wrap(s)
  File "/usr/local/lib/python3.9/site-packages/cheroot/ssl/builtin.py", line 277, in wrap
    s = self.context.wrap_socket(
  File "/usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "/usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 1040, in _create
    self.do_handshake()
  File "/usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: UNEXPECTED_RECORD] unexpected record (_ssl.c:1122)

This is the server code

import cherrypy
import json
import sys
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import threading

WEBSITEURL = "http"
STORAGEDIR = sys.argv[0].replace("__main__.py", "") + '/'


def sendMessage(msgToSend, toWhom, decay):
    """
    Keeps trying to send message until success, decay defines an expiry after a certain amount of attempts



    :param msgToSend: What to send
    :param toWhom: Who will recieve the message
    :param decay: What amount of retries on failure
    :return: Nothing
    """
    for i in range(decay):
        result = order(msgToSend, toWhom)
        if result:
            break


def order(msgToSend, toWhom):
    """
    Send Email from email@gmail.com



    :param msgToSend: Message to send
    :param toWhom: Email to send message to
    :return: True if success, nothing on failure
    """
    from_address = "email@gmail.com"
    to_address = f"{toWhom}"
    # Create message container - the correct MIME type is multipart/alternative.
    msg = MIMEMultipart('alternative')
    msg['Subject'] = "Pedido"
    msg['From'] = from_address
    msg['To'] = to_address
    msg['Bcc'] = "email@gmail.com"
    # Create the message (HTML).
    html = f"""\
    {msgToSend}
    """
    # Record the MIME type - text/html.
    part1 = MIMEText(html, 'html')
    # Credentials
    username = 'email@gmail.com'
    password = 'app sign in'
    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.ehlo()
    server.starttls()
    server.login(username, password)
    server.sendmail(from_address, to_address, msg.as_string())
    server.quit()
    return True


def smartMessage(msgToSend, toWhom, decay=100):
    x = threading.Thread(target=sendMessage, args=(msgToSend, toWhom, decay))
    x.start()
    x.join()


class Webpage:
    """
    Website class
    """

    @cherrypy.expose
    def products(self):
        """
        Products page
        :return:Products Page
        """
        response = ""
        with open(STORAGEDIR + "productos.csv", "r") as f:
            text = f.read()
            response = text.replace('\n', ';')
        return response

    @cherrypy.expose
    @cherrypy.tools.json_in()
    def api(self):
        """
        User
        Login
        API
        :return:Api Page
        """
        data = cherrypy.request.json
        try:
            if data["method"] == "verify":
                with open(STORAGEDIR + "Users.json", "r+") as json_file:
                    users = json.load(json_file)
                    if data["email"] in users:
                        user = users[data["email"]]
                        if data["password"] == user["password"]:
                            return "True"
                raise cherrypy.HTTPError(403)
        except KeyError:
            return "missing parameters"
        try:
            if data["method"] == "signup":
                users = {}
                with open(STORAGEDIR + "USERS.json", "r+") as json_file:
                    users = json.load(json_file)
                    if data["email"] in users:
                        raise cherrypy.HTTPError(403)
                    else:
                        users[data["email"]] = data
                        with open(STORAGEDIR + "USERS.json", "w+") as f:
                            json.dump(users, f)
                            return "True"

        except KeyError:
            return "missing parameters"
        return "test"

    @cherrypy.expose
    @cherrypy.tools.json_in()
    def order(self):
        data = cherrypy.request.json
        email = data["email"]
        password = data["password"]
        items = data["order"]
        with open(STORAGEDIR + "Users.json", "r+") as json_file:
            users = json.load(json_file)
            if email in users:
                user = users[email]
                if password == user["password"]:
                    smartMessage(items,email,decay=50)
                    return "True"
            return "False"

def runserver():
    """
    Cherry Py starting
    """

    cherrypy.tree.mount(Webpage(), '/', config={
        '/': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': "/Users/User/Documents/Webpage",
            'tools.staticdir.index': 'index.html',
            'error_page.404': "/Users/User/Documents/Webpage/404.html",
            'error_page.403': "/Users/User/Documents/Webpage/404.html"
        }
    })

    cherrypy.config.update({
        'server.socket_port': 443,
        'server.socket_host': '0.0.0.0',
        'server.ssl_module': 'builtin',
        'server.ssl_certificate': '/Users/user/letsencrypt/config/live/website.com/cert.pem',
        'server.ssl_certificate_chain': '/Users/user/letsencrypt/config/live/website.com/fullchain.pem',
        'server.ssl_private_key': '/Users/user/letsencrypt/config/live/website.com/privkey.pem'
    })

    try:
        cherrypy.engine.start()
        cherrypy.engine.block()
    except KeyboardInterrupt:
        cherrypy.engine.stop()

runserver()

This issue happens after 1-2 hours of running the server, you get this error and it becomes unresponsive. What can I do to fix this. Is it a Cherrypy error? or am I doing something wrong?

  • Cheroot version: 8.5.1
  • CherryPy version: 18.6.0
  • Python version: 3.9
  • OS: macOS Catalina
  • Browser: all

Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, e.g. stackoverflow, gitter, etc.)
StackOverflow question

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is brokenhelp wantedSomebody help us, please!reproducer: missingThis PR or issue lacks code, which reproduce the problem described or clearly understandable STR

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions