@@ -109,10 +109,117 @@ def test_sending_data(self):
109
109
c .clear_outbound_data_buffer ()
110
110
events = c .send_data (1 , b'some data' )
111
111
assert not events
112
+ data_to_send = c .data_to_send ()
112
113
assert (
113
- c . data_to_send () == b'\x00 \x00 \t \x00 \x00 \x00 \x00 \x00 \x01 some data'
114
+ data_to_send == b'\x00 \x00 \t \x00 \x00 \x00 \x00 \x00 \x01 some data'
114
115
)
115
116
117
+ buffer = h2 .frame_buffer .FrameBuffer (server = False )
118
+ buffer .max_frame_size = 65535
119
+ buffer .add_data (data_to_send )
120
+ data_frame = list (buffer )[0 ]
121
+ sanity_check_data_frame (
122
+ data_frame = data_frame ,
123
+ expected_flow_controlled_length = len (b'some data' ),
124
+ expect_padded_flag = False ,
125
+ expected_data_frame_pad_length = 0
126
+ )
127
+
128
+ def test_sending_data_with_padding (self ):
129
+ """
130
+ Single data frames with padding are encoded correctly.
131
+ """
132
+ c = h2 .connection .H2Connection ()
133
+ c .initiate_connection ()
134
+ c .send_headers (1 , self .example_request_headers )
135
+
136
+ # Clear the data, then send some data.
137
+ c .clear_outbound_data_buffer ()
138
+ events = c .send_data (1 , b'some data' , pad_length = 5 )
139
+ assert not events
140
+ data_to_send = c .data_to_send ()
141
+ assert data_to_send == (
142
+ b'\x00 \x00 \x0f \x00 \x08 \x00 \x00 \x00 \x01 '
143
+ b'\x05 some data\x00 \x00 \x00 \x00 \x00 '
144
+ )
145
+
146
+ buffer = h2 .frame_buffer .FrameBuffer (server = False )
147
+ buffer .max_frame_size = 65535
148
+ buffer .add_data (data_to_send )
149
+ data_frame = list (buffer )[0 ]
150
+ sanity_check_data_frame (
151
+ data_frame = data_frame ,
152
+ expected_flow_controlled_length = len (b'some data' ) + 1 + 5 ,
153
+ expect_padded_flag = True ,
154
+ expected_data_frame_pad_length = 5
155
+ )
156
+
157
+ def test_sending_data_with_zero_length_padding (self ):
158
+ """
159
+ Single data frames with zero-length padding are encoded
160
+ correctly.
161
+ """
162
+ c = h2 .connection .H2Connection ()
163
+ c .initiate_connection ()
164
+ c .send_headers (1 , self .example_request_headers )
165
+
166
+ # Clear the data, then send some data.
167
+ c .clear_outbound_data_buffer ()
168
+ events = c .send_data (1 , b'some data' , pad_length = 0 )
169
+ assert not events
170
+ data_to_send = c .data_to_send ()
171
+ assert data_to_send == (
172
+ b'\x00 \x00 \x0a \x00 \x08 \x00 \x00 \x00 \x01 '
173
+ b'\x00 some data'
174
+ )
175
+
176
+ buffer = h2 .frame_buffer .FrameBuffer (server = False )
177
+ buffer .max_frame_size = 65535
178
+ buffer .add_data (data_to_send )
179
+ data_frame = list (buffer )[0 ]
180
+ sanity_check_data_frame (
181
+ data_frame = data_frame ,
182
+ expected_flow_controlled_length = len (b'some data' ) + 1 ,
183
+ expect_padded_flag = True ,
184
+ expected_data_frame_pad_length = 0
185
+ )
186
+
187
+ @pytest .mark .parametrize ("expected_error,pad_length" , [
188
+ (None , 0 ),
189
+ (None , 255 ),
190
+ (None , None ),
191
+ (ValueError , - 1 ),
192
+ (ValueError , 256 ),
193
+ (TypeError , 'invalid' ),
194
+ (TypeError , '' ),
195
+ (TypeError , '10' ),
196
+ (TypeError , {}),
197
+ (TypeError , ['1' , '2' , '3' ]),
198
+ (TypeError , []),
199
+ (TypeError , 1.5 ),
200
+ (TypeError , 1.0 ),
201
+ (TypeError , - 1.0 ),
202
+ ])
203
+ def test_sending_data_with_invalid_padding_length (self ,
204
+ expected_error ,
205
+ pad_length ):
206
+ """
207
+ ``send_data`` with a ``pad_length`` parameter that is an integer
208
+ outside the range of [0, 255] throws a ``ValueError``, and a
209
+ ``pad_length`` parameter which is not an ``integer`` type
210
+ throws a ``TypeError``.
211
+ """
212
+ c = h2 .connection .H2Connection ()
213
+ c .initiate_connection ()
214
+ c .send_headers (1 , self .example_request_headers )
215
+
216
+ c .clear_outbound_data_buffer ()
217
+ if expected_error is not None :
218
+ with pytest .raises (expected_error ):
219
+ c .send_data (1 , b'some data' , pad_length = pad_length )
220
+ else :
221
+ c .send_data (1 , b'some data' , pad_length = pad_length )
222
+
116
223
def test_closing_stream_sending_data (self , frame_factory ):
117
224
"""
118
225
We can close a stream with a data frame.
@@ -1576,3 +1683,27 @@ def test_receiving_goaway_frame_with_unknown_error(self, frame_factory):
1576
1683
assert c .state_machine .state == h2 .connection .ConnectionState .CLOSED
1577
1684
1578
1685
assert not c .data_to_send ()
1686
+
1687
+
1688
+ def sanity_check_data_frame (data_frame ,
1689
+ expected_flow_controlled_length ,
1690
+ expect_padded_flag ,
1691
+ expected_data_frame_pad_length ):
1692
+ """
1693
+ ``data_frame`` is a frame of type ``hyperframe.frame.DataFrame``,
1694
+ and the ``flags`` and ``flow_controlled_length`` of ``data_frame``
1695
+ match expectations.
1696
+ """
1697
+
1698
+ assert isinstance (data_frame , hyperframe .frame .DataFrame )
1699
+
1700
+ assert (
1701
+ (data_frame .flow_controlled_length ==
1702
+ expected_flow_controlled_length )
1703
+ )
1704
+ if expect_padded_flag :
1705
+ assert 'PADDED' in data_frame .flags
1706
+ else :
1707
+ assert 'PADDED' not in data_frame .flags
1708
+
1709
+ assert data_frame .pad_length == expected_data_frame_pad_length
0 commit comments