Search code examples
pythonhttptimeservercounter

Count HTTP connections when using BaseHTTPRequestHandler


I have an HTTP Server like this

from http.server import BaseHTTPRequestHandler, HTTPServer
from datetime import datetime
import datetime as dt

numberOfTests = 1
timestamp = datetime.now()




class S(BaseHTTPRequestHandler):
    
    
    def formatResponse(self, vhod):
        global numberOfTests, timestamp
        timestamp = datetime.now()  
        if (numberOfTests == 1):
            print("Test "+str(numberOfTests)+" has started")
            numberOfTests =+ 1
            return          
        
        if (numberOfTests > 1):
            print("Test "+str(numberOfTests)+" has started")
            numberOfTests =+ 1
            

    def log_message(self, format, *args): #Silence internal log output
        return 

    def _set_response(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()

    def do_POST(self):
        content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
        post_data = self.rfile.read(content_length) # <--- Gets the data itself

        self.formatResponse(post_data.decode('utf-8'))

        self._set_response()

def run(server_class=HTTPServer, handler_class=S, port=8080):
    server_address = ('', port)
    httpd = server_class(server_address, handler_class)
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass
    httpd.server_close()

I would like that every time a connection is made I would like increment a counter

the problem is that my counter always resets after a new connection is made (like that BaseHTTPRequestHandler is initiated again) so I cannot realy count

ultimatly I would like to mesure time between POST requests and if time is x do something (but I need to figure out how to persist a variable between requests first (as would like to use time.time() as my stopwatch, since time never stops)

if anyone has any idea how to persist a variable between POST requests (to counte them for instance), please let me know

Thanks for Anwsering and Best Regards


Solution

  • You could decorate do_POST and do_GET counting the requests in a class variable.

    from http.server import BaseHTTPRequestHandler, HTTPServer
    from datetime import datetime
    import datetime as dt
    from functools import wraps
    
    
    def count(fn):
        @wraps(fn)
        def wrapper(*args, **kw):
            cls = args[0]
            _http_method = fn.__name__[3:]  # Format method
    
            # Count via HTTP method
            if _http_method not in cls.counts:
                cls.counts[_http_method] = 0
            cls.counts[_http_method] += 1
            return fn(*args, **kw)
    
        return wrapper
    
    
    class S(BaseHTTPRequestHandler):
        counts = {}
    
        def formatResponse(self, vhod):
            print(f"Counter: {self.counts}")
    
        def log_message(self, format, *args):  #Silence internal log output
            return
    
        def _set_response(self):
            self.send_response(200)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
    
        @count
        def do_POST(self):
            content_length = int(
                self.headers['Content-Length']
            )  # <--- Gets the size of data
            post_data = self.rfile.read(content_length)  # <--- Gets the data itself
    
            self.formatResponse(post_data.decode('utf-8'))
    
            self._set_response()
    
        @count
        def do_GET(self):
            self.formatResponse('123')
            self._set_response()
    
    
    def run(server_class=HTTPServer, handler_class=S, port=8080):
        server_address = ('', port)
        httpd = server_class(server_address, handler_class)
        httpd.serve_forever()
        httpd.server_close()
    
    
    run()
    

    Out:

    Counter: {'GET': 1}
    Counter: {'GET': 2}
    Counter: {'GET': 3}
    Counter: {'GET': 4}
    ....