11from __future__ import annotations
22
33import base64
4- import re
5- from http import HTTPStatus
64from typing import TYPE_CHECKING , TypeVar
75
86from pyqwest import Headers as HTTPHeaders
97from pyqwest import StreamError , StreamErrorCode
108
11- from ._codec import CODEC_NAME_JSON , CODEC_NAME_JSON_CHARSET_UTF8 , Codec
12- from ._protocol import ConnectWireError
13- from ._protocol_connect import (
14- CONNECT_PROTOCOL_VERSION ,
15- CONNECT_STREAMING_CONTENT_TYPE_PREFIX ,
16- CONNECT_UNARY_CONTENT_TYPE_PREFIX ,
17- codec_name_from_content_type ,
18- )
9+ from ._codec import Codec
10+ from ._protocol_connect import CONNECT_PROTOCOL_VERSION
1911from .code import Code
2012from .errors import ConnectError
2113
@@ -41,70 +33,6 @@ def prepare_get_params(
4133 return params
4234
4335
44- def validate_unary_response (
45- request_codec_name : str , status_code : int , response_content_type : str
46- ) -> None :
47- if status_code != HTTPStatus .OK :
48- # Error responses must be JSON-encoded
49- if response_content_type in (
50- f"{ CONNECT_UNARY_CONTENT_TYPE_PREFIX } { CODEC_NAME_JSON } " ,
51- f"{ CONNECT_UNARY_CONTENT_TYPE_PREFIX } { CODEC_NAME_JSON_CHARSET_UTF8 } " ,
52- ):
53- return
54- raise ConnectWireError .from_http_status (status_code ).to_exception ()
55-
56- if not response_content_type .startswith (CONNECT_UNARY_CONTENT_TYPE_PREFIX ):
57- raise ConnectError (
58- Code .UNKNOWN ,
59- f"invalid content-type: '{ response_content_type } '; expecting '{ CONNECT_UNARY_CONTENT_TYPE_PREFIX } { request_codec_name } '" ,
60- )
61-
62- response_codec_name = codec_name_from_content_type (
63- response_content_type , stream = False
64- )
65- if response_codec_name == request_codec_name :
66- return
67-
68- if (
69- response_codec_name == CODEC_NAME_JSON
70- and request_codec_name == CODEC_NAME_JSON_CHARSET_UTF8
71- ) or (
72- response_codec_name == CODEC_NAME_JSON_CHARSET_UTF8
73- and request_codec_name == CODEC_NAME_JSON
74- ):
75- # Both are JSON
76- return
77-
78- raise ConnectError (
79- Code .INTERNAL ,
80- f"invalid content-type: '{ response_content_type } '; expecting '{ CONNECT_UNARY_CONTENT_TYPE_PREFIX } { request_codec_name } '" ,
81- )
82-
83-
84- def validate_stream_response_content_type (
85- request_codec_name : str , response_content_type : str
86- ) -> None :
87- if not response_content_type .startswith (CONNECT_STREAMING_CONTENT_TYPE_PREFIX ):
88- raise ConnectError (
89- Code .UNKNOWN ,
90- f"invalid content-type: '{ response_content_type } '; expecting '{ CONNECT_STREAMING_CONTENT_TYPE_PREFIX } { request_codec_name } '" ,
91- )
92-
93- response_codec_name = response_content_type [
94- len (CONNECT_STREAMING_CONTENT_TYPE_PREFIX ) :
95- ]
96- if response_codec_name != request_codec_name :
97- raise ConnectError (
98- Code .INTERNAL ,
99- f"invalid content-type: '{ response_content_type } '; expecting '{ CONNECT_STREAMING_CONTENT_TYPE_PREFIX } { request_codec_name } '" ,
100- )
101-
102-
103- _stream_error_code_regex = re .compile (
104- r".*<StreamReset .*, error_code:(\d+), .*remote_reset:True>.*"
105- )
106-
107-
10836# https://github.com/connectrpc/connect-go/blob/59cc6973156cd9164d6bea493b1d106ed894f2df/error.go#L393
10937def maybe_map_stream_reset (
11038 e : Exception , ctx : RequestContext [REQ , RES ]
0 commit comments