@@ -271,6 +271,8 @@ class ClientRequest:
271
271
__writer = None # async task for streaming data
272
272
_continue = None # waiter future for '100 Continue' response
273
273
274
+ _skip_auto_headers : Optional ["CIMultiDict[None]" ] = None
275
+
274
276
# N.B.
275
277
# Adding __del__ method with self._writer closing doesn't make sense
276
278
# because _writer is instance method, thus it keeps a reference to self.
@@ -358,6 +360,10 @@ def __init__(
358
360
def __reset_writer (self , _ : object = None ) -> None :
359
361
self .__writer = None
360
362
363
+ @property
364
+ def skip_auto_headers (self ) -> CIMultiDict [None ]:
365
+ return self ._skip_auto_headers or CIMultiDict ()
366
+
361
367
@property
362
368
def _writer (self ) -> Optional ["asyncio.Task[None]" ]:
363
369
return self .__writer
@@ -469,20 +475,19 @@ def update_headers(self, headers: Optional[LooseHeaders]) -> None:
469
475
470
476
def update_auto_headers (self , skip_auto_headers : Optional [Iterable [str ]]) -> None :
471
477
if skip_auto_headers is not None :
472
- self .skip_auto_headers = CIMultiDict (
478
+ self ._skip_auto_headers = CIMultiDict (
473
479
(hdr , None ) for hdr in sorted (skip_auto_headers )
474
480
)
475
481
used_headers = self .headers .copy ()
476
- used_headers .extend (self .skip_auto_headers ) # type: ignore[arg-type]
482
+ used_headers .extend (self ._skip_auto_headers ) # type: ignore[arg-type]
477
483
else :
478
484
# Fast path when there are no headers to skip
479
485
# which is the most common case.
480
- self .skip_auto_headers = CIMultiDict ()
481
486
used_headers = self .headers
482
487
483
488
for hdr , val in self .DEFAULT_HEADERS .items ():
484
489
if hdr not in used_headers :
485
- self .headers . add ( hdr , val )
490
+ self .headers [ hdr ] = val
486
491
487
492
if hdrs .USER_AGENT not in used_headers :
488
493
self .headers [hdrs .USER_AGENT ] = SERVER_SOFTWARE
@@ -584,21 +589,20 @@ def update_body_from_data(self, body: Any) -> None:
584
589
self .body = body
585
590
586
591
# enable chunked encoding if needed
587
- if not self .chunked :
588
- if hdrs .CONTENT_LENGTH not in self .headers :
589
- size = body .size
590
- if size is None :
591
- self .chunked = True
592
- else :
593
- if hdrs .CONTENT_LENGTH not in self .headers :
594
- self .headers [hdrs .CONTENT_LENGTH ] = str (size )
592
+ if not self .chunked and hdrs .CONTENT_LENGTH not in self .headers :
593
+ if (size := body .size ) is not None :
594
+ self .headers [hdrs .CONTENT_LENGTH ] = str (size )
595
+ else :
596
+ self .chunked = True
595
597
596
598
# copy payload headers
597
599
assert body .headers
600
+ headers = self .headers
601
+ skip_headers = self ._skip_auto_headers
598
602
for key , value in body .headers .items ():
599
- if key in self . headers or key in self . skip_auto_headers :
603
+ if key in headers or ( skip_headers is not None and key in skip_headers ) :
600
604
continue
601
- self . headers [key ] = value
605
+ headers [key ] = value
602
606
603
607
def update_expect_continue (self , expect : bool = False ) -> None :
604
608
if expect :
@@ -723,7 +727,10 @@ async def send(self, conn: "Connection") -> "ClientResponse":
723
727
# set default content-type
724
728
if (
725
729
self .method in self .POST_METHODS
726
- and hdrs .CONTENT_TYPE not in self .skip_auto_headers
730
+ and (
731
+ self ._skip_auto_headers is None
732
+ or hdrs .CONTENT_TYPE not in self ._skip_auto_headers
733
+ )
727
734
and hdrs .CONTENT_TYPE not in self .headers
728
735
):
729
736
self .headers [hdrs .CONTENT_TYPE ] = "application/octet-stream"
0 commit comments