flaskwsgigeventwsgiserver

How to suppress "Invalid HTTP method" error message on gevent flask/wsgi server running HTTP when it gets an HTTPS request


If a confused user of my application accidentally makes an HTTPS call against my "plain" flask server (expecting an HTTP request) running gevent, I get a log message that I dont know how to get rid of.

I dont think the exception ever reaches python code so I cant catch the exception.

Code example (just a regular flask server):

from flask import Flask
from gevent.pywsgi import WSGIServer

app = Flask(__name__)


@app.route("/")
def hello_world():
    return "Hello, World!"


if __name__ == "__main__":
    http_server = WSGIServer(("0.0.0.0", 8000), app)
    http_server.serve_forever()

Trigger the problem:

curl https://localhost:8000

Log output (the thing I want to get rid of):

<gevent._socket3.socket at 0x10272dbe0 object, fd=9, family=2, type=1, proto=0>: (from ('127.0.0.1', 63996)) Invalid HTTP method: "\x16\x03\x01\x01:\x01\x00\x016\x03\x035o;OÀ|¶\x9aã[3F\x81>?ÞB1f'ø×ÈùG\x0eAV\x9c\x1cÿ\x9f I+Hýò¶\x9aݽL\r{p\n"
{p" 400 - 0.0005314-05-17 08:09:57] ":65o;OÀ|¶ã[3F>?ÞB1f'ø×ÈùGAVÿò¶Ý½L

If it is not possible to get rid of this message, maybe there is some way to at least add another log message with some context/explanation for the user when it happens?


Solution

  • If it required just suppress error messages from Web Server I was found a solution via passing configured err_logger parameter with configured filter via addFilter.

    In filter method it just suppressed messages by what they contains, in your python version message text could be a little differ, however I am still getting logs of response with appropriate status code, i suppose they also could be suppressed by setting log parameter of WSGIServer

    import os
    import logging
    from flask import Flask
    from gevent.pywsgi import WSGIServer
    
    app = Flask(__name__)
    
    @app.route("/")
    def hello_world():
        return "Hello, World!"
    
    class HttpsErrSuppressFilter(logging.Filter):
        def filter(self, record):
            msg = record.msg
            if msg.find("Invalid http version") != -1 or \
               msg.find("Expected GET method") != -1 or \
               msg.find("Invalid HTTP method") != -1 or \
               msg.find("400 -"):
                return False
            return True
    
    if __name__ == "__main__":
        
        print("starting WSGI server itself")
        
        logger = logging.getLogger(__name__)
        logger.addFilter(HttpsErrSuppressFilter())
        logger.propagate = False
        http_server = WSGIServer(("0.0.0.0", 8000), app, error_log=logger)
        
        print("WSGI server started, awaiting 4 requests")
        http_server.serve_forever()
    

    Result look as follows:

    Result of err suppress