1 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4 // option. This file may not be copied, modified, or distributed
5 // except according to those terms.
6 
7 use lazy_static::lazy_static;
8 use neqo_common::event::Provider;
9 use neqo_crypto::AuthenticationStatus;
10 use neqo_http3::{
11     Error, Header, Http3Client, Http3ClientEvent, Http3OrWebTransportStream, Http3Server,
12     Http3ServerEvent, Priority,
13 };
14 use test_fixture::*;
15 
16 const RESPONSE_DATA: &[u8] = &[0x61, 0x62, 0x63];
17 
18 lazy_static! {
19     static ref RESPONSE_HEADER_NO_DATA: Vec<Header> =
20         vec![Header::new(":status", "200"), Header::new("something", "3")];
21 }
22 
23 lazy_static! {
24     static ref RESPONSE_HEADER_103: Vec<Header> =
25         vec![Header::new(":status", "103"), Header::new("link", "...")];
26 }
27 
exchange_packets(client: &mut Http3Client, server: &mut Http3Server)28 fn exchange_packets(client: &mut Http3Client, server: &mut Http3Server) {
29     let mut out = None;
30     loop {
31         out = client.process(out, now()).dgram();
32         out = server.process(out, now()).dgram();
33         if out.is_none() {
34             break;
35         }
36     }
37 }
38 
receive_request(server: &mut Http3Server) -> Option<Http3OrWebTransportStream>39 fn receive_request(server: &mut Http3Server) -> Option<Http3OrWebTransportStream> {
40     while let Some(event) = server.next_event() {
41         if let Http3ServerEvent::Headers {
42             stream,
43             headers,
44             fin,
45         } = event
46         {
47             assert_eq!(
48                 &headers,
49                 &[
50                     Header::new(":method", "GET"),
51                     Header::new(":scheme", "https"),
52                     Header::new(":authority", "something.com"),
53                     Header::new(":path", "/")
54                 ]
55             );
56             assert!(fin);
57             return Some(stream);
58         }
59     }
60     None
61 }
62 
send_trailers(request: &mut Http3OrWebTransportStream) -> Result<(), Error>63 fn send_trailers(request: &mut Http3OrWebTransportStream) -> Result<(), Error> {
64     request.send_headers(&[
65         Header::new("something1", "something"),
66         Header::new("something2", "3"),
67     ])
68 }
69 
send_informational_headers(request: &mut Http3OrWebTransportStream) -> Result<(), Error>70 fn send_informational_headers(request: &mut Http3OrWebTransportStream) -> Result<(), Error> {
71     request.send_headers(&RESPONSE_HEADER_103)
72 }
73 
send_headers(request: &mut Http3OrWebTransportStream) -> Result<(), Error>74 fn send_headers(request: &mut Http3OrWebTransportStream) -> Result<(), Error> {
75     request.send_headers(&[
76         Header::new(":status", "200"),
77         Header::new("content-length", "3"),
78     ])
79 }
80 
process_client_events(conn: &mut Http3Client)81 fn process_client_events(conn: &mut Http3Client) {
82     let mut response_header_found = false;
83     let mut response_data_found = false;
84     while let Some(event) = conn.next_event() {
85         match event {
86             Http3ClientEvent::HeaderReady { headers, fin, .. } => {
87                 assert!(
88                     (headers.as_ref()
89                         == [
90                             Header::new(":status", "200"),
91                             Header::new("content-length", "3"),
92                         ])
93                         || (headers.as_ref() == *RESPONSE_HEADER_103)
94                 );
95                 assert!(!fin);
96                 response_header_found = true;
97             }
98             Http3ClientEvent::DataReadable { stream_id } => {
99                 let mut buf = [0u8; 100];
100                 let (amount, fin) = conn.read_data(now(), stream_id, &mut buf).unwrap();
101                 assert!(fin);
102                 assert_eq!(amount, RESPONSE_DATA.len());
103                 assert_eq!(&buf[..RESPONSE_DATA.len()], RESPONSE_DATA);
104                 response_data_found = true;
105             }
106             _ => {}
107         }
108     }
109     assert!(response_header_found);
110     assert!(response_data_found);
111 }
112 
process_client_events_no_data(conn: &mut Http3Client)113 fn process_client_events_no_data(conn: &mut Http3Client) {
114     let mut response_header_found = false;
115     let mut fin_received = false;
116     while let Some(event) = conn.next_event() {
117         match event {
118             Http3ClientEvent::HeaderReady { headers, fin, .. } => {
119                 assert_eq!(headers.as_ref(), *RESPONSE_HEADER_NO_DATA);
120                 fin_received = fin;
121                 response_header_found = true;
122             }
123             Http3ClientEvent::DataReadable { stream_id } => {
124                 let mut buf = [0u8; 100];
125                 let (amount, fin) = conn.read_data(now(), stream_id, &mut buf).unwrap();
126                 assert!(fin);
127                 fin_received = true;
128                 assert_eq!(amount, 0);
129             }
130             _ => {}
131         }
132     }
133     assert!(response_header_found);
134     assert!(fin_received);
135 }
136 
connect_send_and_receive_request() -> (Http3Client, Http3Server, Http3OrWebTransportStream)137 fn connect_send_and_receive_request() -> (Http3Client, Http3Server, Http3OrWebTransportStream) {
138     let mut hconn_c = default_http3_client();
139     let mut hconn_s = default_http3_server();
140 
141     exchange_packets(&mut hconn_c, &mut hconn_s);
142     let authentication_needed = |e| matches!(e, Http3ClientEvent::AuthenticationNeeded);
143     assert!(hconn_c.events().any(authentication_needed));
144     hconn_c.authenticated(AuthenticationStatus::Ok, now());
145     exchange_packets(&mut hconn_c, &mut hconn_s);
146 
147     let req = hconn_c
148         .fetch(
149             now(),
150             "GET",
151             &("https", "something.com", "/"),
152             &[],
153             Priority::default(),
154         )
155         .unwrap();
156     assert_eq!(req, 0);
157     hconn_c.stream_close_send(req).unwrap();
158     exchange_packets(&mut hconn_c, &mut hconn_s);
159 
160     let request = receive_request(&mut hconn_s).unwrap();
161 
162     (hconn_c, hconn_s, request)
163 }
164 
165 #[test]
response_trailers1()166 fn response_trailers1() {
167     let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
168     send_headers(&mut request).unwrap();
169     request.send_data(RESPONSE_DATA).unwrap();
170     send_trailers(&mut request).unwrap();
171     request.stream_close_send().unwrap();
172     exchange_packets(&mut hconn_c, &mut hconn_s);
173     process_client_events(&mut hconn_c);
174 }
175 
176 #[test]
response_trailers2()177 fn response_trailers2() {
178     let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
179     send_headers(&mut request).unwrap();
180     request.send_data(RESPONSE_DATA).unwrap();
181     exchange_packets(&mut hconn_c, &mut hconn_s);
182     send_trailers(&mut request).unwrap();
183     request.stream_close_send().unwrap();
184     exchange_packets(&mut hconn_c, &mut hconn_s);
185     process_client_events(&mut hconn_c);
186 }
187 
188 #[test]
response_trailers3()189 fn response_trailers3() {
190     let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
191     send_headers(&mut request).unwrap();
192     request.send_data(RESPONSE_DATA).unwrap();
193     exchange_packets(&mut hconn_c, &mut hconn_s);
194     send_trailers(&mut request).unwrap();
195     exchange_packets(&mut hconn_c, &mut hconn_s);
196     request.stream_close_send().unwrap();
197     exchange_packets(&mut hconn_c, &mut hconn_s);
198     process_client_events(&mut hconn_c);
199 }
200 
201 #[test]
response_trailers_no_data()202 fn response_trailers_no_data() {
203     let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
204     request.send_headers(&RESPONSE_HEADER_NO_DATA).unwrap();
205     exchange_packets(&mut hconn_c, &mut hconn_s);
206     send_trailers(&mut request).unwrap();
207     exchange_packets(&mut hconn_c, &mut hconn_s);
208     request.stream_close_send().unwrap();
209     exchange_packets(&mut hconn_c, &mut hconn_s);
210     process_client_events_no_data(&mut hconn_c);
211 }
212 
213 #[test]
multiple_response_trailers()214 fn multiple_response_trailers() {
215     let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
216     send_headers(&mut request).unwrap();
217     request.send_data(RESPONSE_DATA).unwrap();
218     exchange_packets(&mut hconn_c, &mut hconn_s);
219     send_trailers(&mut request).unwrap();
220     exchange_packets(&mut hconn_c, &mut hconn_s);
221 
222     assert_eq!(send_trailers(&mut request), Err(Error::InvalidInput));
223 
224     request.stream_close_send().unwrap();
225     exchange_packets(&mut hconn_c, &mut hconn_s);
226     process_client_events(&mut hconn_c);
227 }
228 
229 #[test]
data_after_trailer()230 fn data_after_trailer() {
231     let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
232     send_headers(&mut request).unwrap();
233     request.send_data(RESPONSE_DATA).unwrap();
234     exchange_packets(&mut hconn_c, &mut hconn_s);
235     send_trailers(&mut request).unwrap();
236     exchange_packets(&mut hconn_c, &mut hconn_s);
237 
238     assert_eq!(request.send_data(RESPONSE_DATA), Err(Error::InvalidInput));
239 
240     request.stream_close_send().unwrap();
241     exchange_packets(&mut hconn_c, &mut hconn_s);
242     process_client_events(&mut hconn_c);
243 }
244 
245 #[test]
trailers_after_close()246 fn trailers_after_close() {
247     let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
248     send_headers(&mut request).unwrap();
249     request.send_data(RESPONSE_DATA).unwrap();
250     request.stream_close_send().unwrap();
251 
252     assert_eq!(send_trailers(&mut request), Err(Error::InvalidStreamId));
253 
254     exchange_packets(&mut hconn_c, &mut hconn_s);
255     process_client_events(&mut hconn_c);
256 }
257 
258 #[test]
multiple_response_headers()259 fn multiple_response_headers() {
260     let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
261     request.send_headers(&RESPONSE_HEADER_NO_DATA).unwrap();
262 
263     assert_eq!(
264         request.send_headers(&RESPONSE_HEADER_NO_DATA),
265         Err(Error::InvalidHeader)
266     );
267 
268     request.stream_close_send().unwrap();
269     exchange_packets(&mut hconn_c, &mut hconn_s);
270     process_client_events_no_data(&mut hconn_c);
271 }
272 
273 #[test]
informational_after_response_headers()274 fn informational_after_response_headers() {
275     let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
276     request.send_headers(&RESPONSE_HEADER_NO_DATA).unwrap();
277 
278     assert_eq!(
279         send_informational_headers(&mut request),
280         Err(Error::InvalidHeader)
281     );
282 
283     request.stream_close_send().unwrap();
284     exchange_packets(&mut hconn_c, &mut hconn_s);
285     process_client_events_no_data(&mut hconn_c);
286 }
287 
288 #[test]
data_after_informational()289 fn data_after_informational() {
290     let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
291     send_informational_headers(&mut request).unwrap();
292 
293     assert_eq!(request.send_data(RESPONSE_DATA), Err(Error::InvalidInput));
294 
295     send_headers(&mut request).unwrap();
296     request.send_data(RESPONSE_DATA).unwrap();
297     request.stream_close_send().unwrap();
298     exchange_packets(&mut hconn_c, &mut hconn_s);
299     process_client_events(&mut hconn_c);
300 }
301 
302 #[test]
non_trailers_headers_after_data()303 fn non_trailers_headers_after_data() {
304     let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
305     send_headers(&mut request).unwrap();
306     request.send_data(RESPONSE_DATA).unwrap();
307     exchange_packets(&mut hconn_c, &mut hconn_s);
308 
309     assert_eq!(
310         request.send_headers(&RESPONSE_HEADER_NO_DATA),
311         Err(Error::InvalidHeader)
312     );
313 
314     request.stream_close_send().unwrap();
315     exchange_packets(&mut hconn_c, &mut hconn_s);
316     process_client_events(&mut hconn_c);
317 }
318 
319 #[test]
data_before_headers()320 fn data_before_headers() {
321     let (mut hconn_c, mut hconn_s, mut request) = connect_send_and_receive_request();
322     assert_eq!(request.send_data(RESPONSE_DATA), Err(Error::InvalidInput));
323 
324     send_headers(&mut request).unwrap();
325     request.send_data(RESPONSE_DATA).unwrap();
326     request.stream_close_send().unwrap();
327     exchange_packets(&mut hconn_c, &mut hconn_s);
328     process_client_events(&mut hconn_c);
329 }
330