@@ -42,7 +42,7 @@ class Handler(BaseHTTPRequestHandler):
4242 """
4343
4444 server_version = "cloudstack-image-server/1.0"
45- server_protocol = "HTTP/1.1"
45+ protocol_version = "HTTP/1.1"
4646
4747 _registry : TransferRegistry
4848
@@ -78,12 +78,33 @@ def _send_json(
7878 try :
7979 self .wfile .write (body )
8080 except BrokenPipeError :
81- pass
81+ logging .error (
82+ "HTTP response write failure status=%s method=%s path=%s err=%s" ,
83+ int (status ),
84+ self .command ,
85+ self .path ,
86+ "client disconnected" ,
87+ )
8288
8389 def _send_error_json (self , status : int , message : str ) -> None :
90+ logging .error (
91+ "HTTP failure status=%s method=%s path=%s message=%s" ,
92+ int (status ),
93+ self .command ,
94+ self .path ,
95+ message ,
96+ )
8497 self ._send_json (status , {"error" : message })
8598
8699 def _send_range_not_satisfiable (self , size : int ) -> None :
100+ logging .error (
101+ "HTTP failure status=%s method=%s path=%s message=%s size=%s" ,
102+ int (HTTPStatus .REQUESTED_RANGE_NOT_SATISFIABLE ),
103+ self .command ,
104+ self .path ,
105+ "range not satisfiable" ,
106+ size ,
107+ )
87108 self .send_response (HTTPStatus .REQUESTED_RANGE_NOT_SATISFIABLE )
88109 self ._send_imageio_headers ()
89110 self .send_header ("Content-Type" , "application/json" )
@@ -94,7 +115,13 @@ def _send_range_not_satisfiable(self, size: int) -> None:
94115 try :
95116 self .wfile .write (body )
96117 except BrokenPipeError :
97- pass
118+ logging .error (
119+ "HTTP response write failure status=%s method=%s path=%s err=%s" ,
120+ int (HTTPStatus .REQUESTED_RANGE_NOT_SATISFIABLE ),
121+ self .command ,
122+ self .path ,
123+ "client disconnected" ,
124+ )
98125
99126 # ------------------------------------------------------------------
100127 # Parsing helpers
@@ -493,6 +520,7 @@ def _handle_get_image(
493520 ) -> None :
494521 start = now_s ()
495522 bytes_sent = 0
523+ expected_bytes = 0
496524 try :
497525 logging .info ("GET start image_id=%s range=%s" , image_id , range_header or "-" )
498526 backend = create_backend (cfg )
@@ -524,6 +552,7 @@ def _handle_get_image(
524552 return
525553 status = HTTPStatus .PARTIAL_CONTENT
526554 content_length = (end_off_incl - start_off ) + 1
555+ expected_bytes = content_length
527556
528557 self .send_response (status )
529558 self ._send_imageio_headers ()
@@ -539,11 +568,26 @@ def _handle_get_image(
539568 to_read = min (CHUNK_SIZE , end_excl - offset )
540569 data = session .read (offset , to_read )
541570 if not data :
571+ logging .error (
572+ "GET short read image_id=%s expected_bytes=%d sent_bytes=%d offset=%d" ,
573+ image_id ,
574+ expected_bytes ,
575+ bytes_sent ,
576+ offset ,
577+ )
578+ self .close_connection = True
542579 break
543580 try :
544581 self .wfile .write (data )
545582 except BrokenPipeError :
546- logging .info ("GET client disconnected image_id=%s at=%d" , image_id , offset )
583+ logging .error (
584+ "GET client disconnected image_id=%s at=%d expected_bytes=%d sent_bytes=%d" ,
585+ image_id ,
586+ offset ,
587+ expected_bytes ,
588+ bytes_sent ,
589+ )
590+ self .close_connection = True
547591 break
548592 offset += len (data )
549593 bytes_sent += len (data )
@@ -558,6 +602,13 @@ def _handle_get_image(
558602 except Exception :
559603 pass
560604 finally :
605+ if expected_bytes > 0 and bytes_sent < expected_bytes :
606+ logging .error (
607+ "GET incomplete image_id=%s expected_bytes=%d sent_bytes=%d" ,
608+ image_id ,
609+ expected_bytes ,
610+ bytes_sent ,
611+ )
561612 dur = now_s () - start
562613 logging .info (
563614 "GET end image_id=%s bytes=%d duration_s=%.3f" , image_id , bytes_sent , dur
@@ -603,7 +654,7 @@ def _handle_put_range(
603654 try :
604655 logging .info (
605656 "PUT range start image_id=%s Content-Range=%s content_length=%d flush=%s" ,
606- image_id , content_range , content_length , flush ,
657+ image_id ,content_range , content_length , flush ,
607658 )
608659 try :
609660 start_off , _end_inclusive = self ._parse_content_range (content_range )
0 commit comments