8585
8686from http import HTTPStatus
8787
88+ lazy import _colorize
89+
8890
8991# Default error message template
9092DEFAULT_ERROR_MESSAGE = """\
@@ -574,6 +576,31 @@ def flush_headers(self):
574576 self .wfile .write (b"" .join (self ._headers_buffer ))
575577 self ._headers_buffer = []
576578
579+ def _colorize_request (self , code , size , t ):
580+ try :
581+ code_int = int (code )
582+ except (TypeError , ValueError ):
583+ code_color = ""
584+ else :
585+ if code_int >= 500 :
586+ code_color = t .status_server_error
587+ elif code_int >= 400 :
588+ code_color = t .status_client_error
589+ elif code_int >= 300 :
590+ code_color = t .status_redirect
591+ elif code_int >= 200 :
592+ code_color = t .status_ok
593+ else :
594+ code_color = t .status_informational
595+
596+ request_line = self .requestline .translate (self ._control_char_table )
597+ parts = request_line .split (None , 2 )
598+ if len (parts ) == 3 :
599+ method , path , version = parts
600+ request_line = f"{ method } { t .path } { path } { t .reset } { version } "
601+
602+ return f'"{ request_line } " { code_color } { code } { t .size } { size } { t .reset } '
603+
577604 def log_request (self , code = '-' , size = '-' ):
578605 """Log an accepted request.
579606
@@ -582,6 +609,7 @@ def log_request(self, code='-', size='-'):
582609 """
583610 if isinstance (code , HTTPStatus ):
584611 code = code .value
612+ self ._log_request_info = (code , size )
585613 self .log_message ('"%s" %s %s' ,
586614 self .requestline , str (code ), str (size ))
587615
@@ -596,7 +624,7 @@ def log_error(self, format, *args):
596624 XXX This should go to the separate error log.
597625
598626 """
599-
627+ self . _log_is_error = True
600628 self .log_message (format , * args )
601629
602630 # https://en.wikipedia.org/wiki/List_of_Unicode_characters#Control_codes
@@ -623,12 +651,22 @@ def log_message(self, format, *args):
623651 before writing the output to stderr.
624652
625653 """
626-
627- message = format % args
628- sys .stderr .write ("%s - - [%s] %s\n " %
629- (self .address_string (),
630- self .log_date_time_string (),
631- message .translate (self ._control_char_table )))
654+ message = (format % args ).translate (self ._control_char_table )
655+ t = _colorize .get_theme (tty_file = sys .stderr ).http_server
656+
657+ info = getattr (self , "_log_request_info" , None )
658+ if info is not None :
659+ self ._log_request_info = None
660+ message = self ._colorize_request (* info , t )
661+ elif getattr (self , "_log_is_error" , False ):
662+ self ._log_is_error = False
663+ message = f"{ t .error } { message } { t .reset } "
664+
665+ sys .stderr .write (
666+ f"{ t .timestamp } { self .address_string ()} - - "
667+ f"[{ self .log_date_time_string ()} ]{ t .reset } "
668+ f"{ message } \n "
669+ )
632670
633671 def version_string (self ):
634672 """Return the server software version string."""
@@ -994,9 +1032,11 @@ def test(HandlerClass=BaseHTTPRequestHandler,
9941032 host , port = httpd .socket .getsockname ()[:2 ]
9951033 url_host = f'[{ host } ]' if ':' in host else host
9961034 protocol = 'HTTPS' if tls_cert else 'HTTP'
1035+ t = _colorize .get_theme ().http_server
1036+ url = f"{ protocol .lower ()} ://{ url_host } :{ port } /"
9971037 print (
998- f"Serving { protocol } on { host } port { port } "
999- f"({ protocol . lower () } :// { url_host } : { port } / ) ..."
1038+ f"{ t . serving } Serving { protocol } on { host } port { port } { t . reset } "
1039+ f"({ t . url } { url } { t . reset } ) ..."
10001040 )
10011041 try :
10021042 httpd .serve_forever ()
0 commit comments