@@ -228,6 +228,61 @@ def test_sock_sendfile_zero_size(self):
228228 self .assertEqual (ret , 0 )
229229 self .assertEqual (self .file .tell (), 0 )
230230
231+ def check_sock_sendfile_offset (self , data , offset , force_fallback = False ):
232+ sock , proto = self .prepare_socksendfile ()
233+ with tempfile .TemporaryFile () as f :
234+ f .write (data )
235+ f .flush ()
236+ self .assertEqual (f .tell (), len (data ))
237+
238+ if force_fallback :
239+ async def _sock_sendfile_fail (sock , file , offset , count ):
240+ raise asyncio .exceptions .SendfileNotAvailableError ()
241+ with support .swap_attr (self .loop , '_sock_sendfile_native' , _sock_sendfile_fail ):
242+ ret = self .run_loop (self .loop .sock_sendfile (sock , f , offset , None ))
243+ else :
244+ ret = self .run_loop (self .loop .sock_sendfile (sock , f , offset , None ))
245+
246+ self .assertEqual (f .tell (), len (data ))
247+
248+ sock .close ()
249+ self .run_loop (proto .wait_closed ())
250+
251+ self .assertEqual (ret , len (data ) - offset )
252+
253+
254+ def test_sock_sendfile_offset (self ):
255+ data = b'abcdef'
256+ for offset in (0 , len (data ) // 2 , len (data )):
257+ for force_fallback in (False , True ):
258+ with self .subTest (offset = offset , force_fallback = force_fallback ):
259+ self .check_sock_sendfile_offset (data , offset , force_fallback )
260+
261+ def check_sendfile_offset (self , offset , fallback ):
262+ srv_proto , cli_proto = self .prepare_sendfile ()
263+ self .file .seek (123 )
264+ coro = self .loop .sendfile (cli_proto .transport , self .file , offset , fallback = fallback )
265+ try :
266+ ret = self .run_loop (coro )
267+ except asyncio .SendfileNotAvailableError :
268+ if fallback :
269+ raise
270+ cli_proto .transport .close ()
271+ self .run_loop (srv_proto .done )
272+ return
273+ cli_proto .transport .close ()
274+ self .run_loop (srv_proto .done )
275+ self .assertEqual (ret , len (self .DATA ) - offset )
276+ self .assertEqual (srv_proto .nbytes , len (self .DATA ) - offset )
277+ self .assertEqual (srv_proto .data , self .DATA [offset :])
278+ self .assertEqual (self .file .tell (), len (self .DATA ))
279+
280+ def test_sendfile_offset (self ):
281+ for offset in (0 , len (self .DATA ) // 2 , len (self .DATA )):
282+ for fallback in (False , True ):
283+ with self .subTest (offset = offset , fallback = fallback ):
284+ self .check_sendfile_offset (offset , fallback )
285+
231286 def test_sock_sendfile_mix_with_regular_send (self ):
232287 buf = b"mix_regular_send" * (4 * 1024 ) # 64 KiB
233288 sock , proto = self .prepare_socksendfile ()
0 commit comments