@@ -144,8 +144,14 @@ async def _handle_http_message(self, flow: http.HTTPFlow, is_request: bool):
144144
145145 # Use the received messages.
146146 if message_set .request is not None :
147+ if message_set .request .http_version == "RI/UNSET" :
148+ message_set .request .http_version = flow .request .http_version \
149+ if flow .request is not None else "HTTP/1.1"
147150 flow .request = message_set .request
148151 if message_set .response is not None :
152+ if message_set .response .http_version == "RI/UNSET" :
153+ message_set .response .http_version = flow .response .http_version \
154+ if flow .response is not None else "HTTP/1.1"
149155 flow .response = message_set .response
150156
151157
@@ -167,10 +173,14 @@ def _headers_from_json(headers_json: dict[str, list[str]]) -> http.Headers:
167173
168174def _request_to_json (request : http .Request ) -> dict [str , object ]:
169175 return {
176+ "http_version" : request .http_version ,
170177 "method" : request .method ,
171178 "url" : request .url ,
172179 "headers" : _headers_to_json (request .headers ),
173180 "body" : base64 .b64encode (request .get_content (strict = False )).decode ("utf-8" ),
181+ "trailers" : _headers_to_json (request .trailers ) if request .trailers else None ,
182+ "timestamp_start" : request .timestamp_start ,
183+ "timestamp_end" : request .timestamp_end ,
174184 }
175185
176186
@@ -182,20 +192,41 @@ def _request_to_summary_json(request: http.Request) -> dict[str, object]:
182192
183193
184194def _request_from_json (request_json : dict [str , object ]) -> http .Request :
185- return http .Request .make (
186- method = typing .cast (str , request_json ["method" ]),
187- url = typing .cast (str , request_json ["url" ]),
188- content = base64 .b64decode (typing .cast (str , request_json ["body" ])),
195+ request = http .Request (
196+ host = "" ,
197+ port = 0 ,
198+ method = typing .cast (str , request_json ["method" ]).encode ("utf-8" , "surrogateescape" ),
199+ scheme = b"" ,
200+ authority = b"" ,
201+ path = b"" ,
202+ http_version = typing .cast (str , request_json ["http_version" ]
203+ if request_json ["http_version" ] is not None else "RI/UNSET" ).encode ("utf-8" , "surrogateescape" ),
189204 headers = _headers_from_json (typing .cast (dict [str , list [str ]], request_json ["headers" ])),
205+ content = None ,
206+ trailers = _headers_from_json (typing .cast (dict [str , list [str ]], request_json ["trailers" ]))
207+ if request_json ["trailers" ] is not None else None ,
208+ timestamp_start = typing .cast (float , request_json ["timestamp_start" ]),
209+ timestamp_end = typing .cast (float , request_json ["timestamp_end" ]),
190210 )
191211
212+ # Use the URL setter to set the host, port, scheme, authority and path.
213+ request .url = typing .cast (str , request_json ["url" ])
214+ # Use the content setter to ensure that the content is encoded in accordance with the encoding headers.
215+ request .content = base64 .b64decode (typing .cast (str , request_json ["body" ]))
216+
217+ return request
218+
192219
193220def _response_to_json (response : http .Response ) -> dict [str , object ]:
194221 return {
222+ "http_version" : response .http_version ,
195223 "status_code" : response .status_code ,
196224 "reason" : response .reason ,
197225 "headers" : _headers_to_json (response .headers ),
198226 "body" : base64 .b64encode (response .get_content (strict = False )).decode ("utf-8" ),
227+ "trailers" : _headers_to_json (response .trailers ) if response .trailers else None ,
228+ "timestamp_start" : response .timestamp_start ,
229+ "timestamp_end" : response .timestamp_end ,
199230 }
200231
201232
@@ -207,14 +238,22 @@ def _response_to_summary_json(response: http.Response) -> dict[str, object]:
207238
208239
209240def _response_from_json (response_json : dict [str , object ]) -> http .Response :
210- response = http .Response .make (
241+ response = http .Response (
242+ http_version = typing .cast (str , response_json ["http_version" ]
243+ if response_json ["http_version" ] is not None else "RI/UNSET" ).encode ("utf-8" , "surrogateescape" ),
211244 status_code = typing .cast (int , response_json ["status_code" ]),
212- content = base64 . b64decode ( typing .cast (str , response_json ["body" ]) ),
245+ reason = typing .cast (str , response_json ["reason" ] or "" ). encode ( "ISO-8859-1" ),
213246 headers = _headers_from_json (typing .cast (dict [str , list [str ]], response_json ["headers" ])),
247+ content = None ,
248+ trailers = _headers_from_json (typing .cast (dict [str , list [str ]], response_json ["trailers" ]))
249+ if response_json ["trailers" ] is not None else None ,
250+ timestamp_start = typing .cast (float , response_json ["timestamp_start" ]),
251+ timestamp_end = typing .cast (float , response_json ["timestamp_end" ]),
214252 )
215- reason : str | None = response_json .get ("reason" )
216- if reason is not None :
217- response .reason = reason
253+
254+ # Use the content setter to ensure that the content is encoded in accordance with the encoding headers.
255+ response .content = base64 .b64decode (typing .cast (str , response_json ["body" ]))
256+
218257 return response
219258
220259
0 commit comments