@@ -228,6 +228,62 @@ 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+
262+ def check_sendfile_offset (self , offset , fallback ):
263+ srv_proto , cli_proto = self .prepare_sendfile ()
264+ self .file .seek (123 )
265+ coro = self .loop .sendfile (cli_proto .transport , self .file , offset , fallback = fallback )
266+ try :
267+ ret = self .run_loop (coro )
268+ except asyncio .SendfileNotAvailableError :
269+ if fallback :
270+ raise
271+ cli_proto .transport .close ()
272+ self .run_loop (srv_proto .done )
273+ return
274+ cli_proto .transport .close ()
275+ self .run_loop (srv_proto .done )
276+ self .assertEqual (ret , len (self .DATA ) - offset )
277+ self .assertEqual (srv_proto .nbytes , len (self .DATA ) - offset )
278+ self .assertEqual (srv_proto .data , self .DATA [offset :])
279+ self .assertEqual (self .file .tell (), len (self .DATA ))
280+
281+ def test_sendfile_offset (self ):
282+ for offset in (0 , len (self .DATA ) // 2 , len (self .DATA )):
283+ for fallback in (False , True ):
284+ with self .subTest (offset = offset , fallback = fallback ):
285+ self .check_sendfile_offset (offset , fallback )
286+
231287 def test_sock_sendfile_mix_with_regular_send (self ):
232288 buf = b"mix_regular_send" * (4 * 1024 ) # 64 KiB
233289 sock , proto = self .prepare_socksendfile ()
0 commit comments