@@ -209,6 +209,8 @@ class ClientRequest:
209209 __writer : Optional ["asyncio.Task[None]" ] = None # async task for streaming data
210210 _continue = None # waiter future for '100 Continue' response
211211
212+ _skip_auto_headers : Optional ["CIMultiDict[None]" ] = None
213+
212214 # N.B.
213215 # Adding __del__ method with self._writer closing doesn't make sense
214216 # because _writer is instance method, thus it keeps a reference to self.
@@ -293,6 +295,10 @@ def __init__(
293295 def __reset_writer (self , _ : object = None ) -> None :
294296 self .__writer = None
295297
298+ @property
299+ def skip_auto_headers (self ) -> CIMultiDict [None ]:
300+ return self ._skip_auto_headers or CIMultiDict ()
301+
296302 @property
297303 def _writer (self ) -> Optional ["asyncio.Task[None]" ]:
298304 return self .__writer
@@ -404,20 +410,19 @@ def update_headers(self, headers: Optional[LooseHeaders]) -> None:
404410
405411 def update_auto_headers (self , skip_auto_headers : Optional [Iterable [str ]]) -> None :
406412 if skip_auto_headers is not None :
407- self .skip_auto_headers = CIMultiDict (
413+ self ._skip_auto_headers = CIMultiDict (
408414 (hdr , None ) for hdr in sorted (skip_auto_headers )
409415 )
410416 used_headers = self .headers .copy ()
411- used_headers .extend (self .skip_auto_headers ) # type: ignore[arg-type]
417+ used_headers .extend (self ._skip_auto_headers ) # type: ignore[arg-type]
412418 else :
413419 # Fast path when there are no headers to skip
414420 # which is the most common case.
415- self .skip_auto_headers = CIMultiDict ()
416421 used_headers = self .headers
417422
418423 for hdr , val in self .DEFAULT_HEADERS .items ():
419424 if hdr not in used_headers :
420- self .headers . add ( hdr , val )
425+ self .headers [ hdr ] = val
421426
422427 if hdrs .USER_AGENT not in used_headers :
423428 self .headers [hdrs .USER_AGENT ] = SERVER_SOFTWARE
@@ -522,21 +527,20 @@ def update_body_from_data(self, body: Any) -> None:
522527 self .body = body
523528
524529 # enable chunked encoding if needed
525- if not self .chunked :
526- if hdrs .CONTENT_LENGTH not in self .headers :
527- size = body .size
528- if size is None :
529- self .chunked = True
530- else :
531- if hdrs .CONTENT_LENGTH not in self .headers :
532- self .headers [hdrs .CONTENT_LENGTH ] = str (size )
530+ if not self .chunked and hdrs .CONTENT_LENGTH not in self .headers :
531+ if (size := body .size ) is not None :
532+ self .headers [hdrs .CONTENT_LENGTH ] = str (size )
533+ else :
534+ self .chunked = True
533535
534536 # copy payload headers
535537 assert body .headers
538+ headers = self .headers
539+ skip_headers = self ._skip_auto_headers
536540 for key , value in body .headers .items ():
537- if key in self . headers or key in self . skip_auto_headers :
541+ if key in headers or ( skip_headers is not None and key in skip_headers ) :
538542 continue
539- self . headers [key ] = value
543+ headers [key ] = value
540544
541545 def update_expect_continue (self , expect : bool = False ) -> None :
542546 if expect :
@@ -664,7 +668,10 @@ async def send(self, conn: "Connection") -> "ClientResponse":
664668 # set default content-type
665669 if (
666670 self .method in self .POST_METHODS
667- and hdrs .CONTENT_TYPE not in self .skip_auto_headers
671+ and (
672+ self ._skip_auto_headers is None
673+ or hdrs .CONTENT_TYPE not in self ._skip_auto_headers
674+ )
668675 and hdrs .CONTENT_TYPE not in self .headers
669676 ):
670677 self .headers [hdrs .CONTENT_TYPE ] = "application/octet-stream"
0 commit comments