@@ -25,6 +25,17 @@ def sendfile(*args, **kwargs):
25
25
return loop
26
26
27
27
28
+ @pytest .fixture
29
+ def loop_with_mocked_native_sendfile (loop : Any ):
30
+ def sendfile (transport , fobj , offset , count ):
31
+ if count == 0 :
32
+ raise ValueError ("count must be a positive integer (got 0)" )
33
+ raise NotImplementedError
34
+
35
+ loop .sendfile = sendfile
36
+ return loop
37
+
38
+
28
39
@pytest .fixture (params = ["sendfile" , "no_sendfile" ], ids = ["sendfile" , "no_sendfile" ])
29
40
def sender (request , loop_without_sendfile ):
30
41
def maker (* args , ** kwargs ):
@@ -74,13 +85,44 @@ async def handler(request):
74
85
app .router .add_get ("/" , handler )
75
86
client = await aiohttp_client (app )
76
87
77
- resp = await client .get ("/" )
78
- assert resp .status == 200
79
- txt = await resp .text ()
80
- assert "" == txt .rstrip ()
81
- assert "application/octet-stream" == resp .headers ["Content-Type" ]
82
- assert resp .headers .get ("Content-Encoding" ) is None
83
- await resp .release ()
88
+ # Run the request multiple times to ensure
89
+ # that an untrapped exception is not hidden
90
+ # because there is no read of the zero bytes
91
+ for i in range (2 ):
92
+ resp = await client .get ("/" )
93
+ assert resp .status == 200
94
+ txt = await resp .text ()
95
+ assert "" == txt .rstrip ()
96
+ assert "application/octet-stream" == resp .headers ["Content-Type" ]
97
+ assert resp .headers .get ("Content-Encoding" ) is None
98
+ await resp .release ()
99
+
100
+
101
+ async def test_zero_bytes_file_mocked_native_sendfile (
102
+ aiohttp_client : Any , loop_with_mocked_native_sendfile : Any
103
+ ) -> None :
104
+ filepath = pathlib .Path (__file__ ).parent / "data.zero_bytes"
105
+
106
+ async def handler (request ):
107
+ asyncio .set_event_loop (loop_with_mocked_native_sendfile )
108
+ return web .FileResponse (filepath )
109
+
110
+ app = web .Application ()
111
+ app .router .add_get ("/" , handler )
112
+ client = await aiohttp_client (app )
113
+
114
+ # Run the request multiple times to ensure
115
+ # that an untrapped exception is not hidden
116
+ # because there is no read of the zero bytes
117
+ for i in range (2 ):
118
+ resp = await client .get ("/" )
119
+ assert resp .status == 200
120
+ txt = await resp .text ()
121
+ assert "" == txt .rstrip ()
122
+ assert "application/octet-stream" == resp .headers ["Content-Type" ]
123
+ assert resp .headers .get ("Content-Encoding" ) is None
124
+ assert resp .headers .get ("Content-Length" ) == "0"
125
+ await resp .release ()
84
126
85
127
86
128
async def test_static_file_ok_string_path (
0 commit comments