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 #![allow(unused_assignments)]
8 
9 use neqo_common::{matches, Datagram};
10 use neqo_crypto::AuthenticationStatus;
11 use neqo_http3::{Http3Client, Http3ClientEvent, Http3Server, Http3ServerEvent, Http3State};
12 use test_fixture::*;
13 
14 const RESPONSE_DATA: &[u8] = &[0x61, 0x62, 0x63];
15 
process_server_events(server: &mut Http3Server)16 fn process_server_events(server: &mut Http3Server) {
17     let mut request_found = false;
18     while let Some(event) = server.next_event() {
19         if let Http3ServerEvent::Headers {
20             mut request,
21             headers,
22             fin,
23         } = event
24         {
25             assert_eq!(
26                 headers,
27                 vec![
28                     (String::from(":method"), String::from("GET")),
29                     (String::from(":scheme"), String::from("https")),
30                     (String::from(":authority"), String::from("something.com")),
31                     (String::from(":path"), String::from("/"))
32                 ]
33             );
34             assert_eq!(fin, true);
35             request
36                 .set_response(
37                     &[
38                         (String::from(":status"), String::from("200")),
39                         (String::from("content-length"), String::from("3")),
40                     ],
41                     RESPONSE_DATA.to_vec(),
42                 )
43                 .unwrap();
44             request_found = true;
45         }
46     }
47     assert_eq!(request_found, true);
48 }
49 
process_client_events(conn: &mut Http3Client)50 fn process_client_events(conn: &mut Http3Client) {
51     let mut response_header_found = false;
52     let mut response_data_found = false;
53     while let Some(event) = conn.next_event() {
54         match event {
55             Http3ClientEvent::HeaderReady { stream_id } => {
56                 let h = conn.read_response_headers(stream_id);
57                 assert_eq!(
58                     h,
59                     Ok((
60                         vec![
61                             (String::from(":status"), String::from("200")),
62                             (String::from("content-length"), String::from("3")),
63                         ],
64                         false
65                     ))
66                 );
67                 response_header_found = true;
68             }
69             Http3ClientEvent::DataReadable { stream_id } => {
70                 let mut buf = [0u8; 100];
71                 let (amount, fin) = conn.read_response_data(now(), stream_id, &mut buf).unwrap();
72                 assert_eq!(fin, true);
73                 assert_eq!(amount, RESPONSE_DATA.len());
74                 assert_eq!(&buf[..RESPONSE_DATA.len()], RESPONSE_DATA);
75                 response_data_found = true;
76             }
77             _ => {}
78         }
79     }
80     assert_eq!(response_header_found, true);
81     assert_eq!(response_data_found, true)
82 }
83 
connect() -> (Http3Client, Http3Server, Option<Datagram>)84 fn connect() -> (Http3Client, Http3Server, Option<Datagram>) {
85     let mut hconn_c = default_http3_client();
86     let mut hconn_s = default_http3_server();
87 
88     assert_eq!(hconn_c.state(), Http3State::Initializing);
89     let out = hconn_c.process(None, now()); // Initial
90     let out = hconn_s.process(out.dgram(), now()); // Initial + Handshake
91     let out = hconn_c.process(out.dgram(), now()); // ACK
92     let _ = hconn_s.process(out.dgram(), now()); //consume ACK
93     let authentication_needed = |e| matches!(e, Http3ClientEvent::AuthenticationNeeded);
94     assert!(hconn_c.events().any(authentication_needed));
95     hconn_c.authenticated(AuthenticationStatus::Ok, now());
96     let out = hconn_c.process(None, now()); // Handshake
97     assert_eq!(hconn_c.state(), Http3State::Connected);
98     let out = hconn_s.process(out.dgram(), now()); // Handshake
99     let out = hconn_c.process(out.dgram(), now());
100     let out = hconn_s.process(out.dgram(), now());
101     // assert_eq!(hconn_s.settings_received, true);
102     let out = hconn_c.process(out.dgram(), now());
103     // assert_eq!(hconn_c.settings_received, true);
104 
105     (hconn_c, hconn_s, out.dgram())
106 }
107 
108 #[test]
test_connect()109 fn test_connect() {
110     let (_hconn_c, _hconn_s, _d) = connect();
111 }
112 
113 #[test]
test_fetch()114 fn test_fetch() {
115     let (mut hconn_c, mut hconn_s, dgram) = connect();
116 
117     eprintln!("-----client");
118     let req = hconn_c
119         .fetch("GET", "https", "something.com", "/", &[])
120         .unwrap();
121     assert_eq!(req, 0);
122     hconn_c.stream_close_send(req).unwrap();
123     let out = hconn_c.process(dgram, now());
124     eprintln!("-----server");
125     let out = hconn_s.process(out.dgram(), now());
126     let _ = hconn_c.process(out.dgram(), now());
127     process_server_events(&mut hconn_s);
128     let out = hconn_s.process(None, now());
129 
130     eprintln!("-----client");
131     let _ = hconn_c.process(out.dgram(), now());
132     let out = hconn_s.process(None, now());
133     let _ = hconn_c.process(out.dgram(), now());
134     process_client_events(&mut hconn_c);
135 }
136