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::{event::Provider, Datagram};
10 use neqo_crypto::AuthenticationStatus;
11 use neqo_http3::{
12 Header, Http3Client, Http3ClientEvent, Http3Server, Http3ServerEvent, Http3State,
13 };
14 use std::mem;
15 use test_fixture::*;
16
17 const RESPONSE_DATA: &[u8] = &[0x61, 0x62, 0x63];
18
process_server_events(server: &mut Http3Server)19 fn process_server_events(server: &mut Http3Server) {
20 let mut request_found = false;
21 while let Some(event) = server.next_event() {
22 if let Http3ServerEvent::Headers {
23 mut request,
24 headers,
25 fin,
26 } = event
27 {
28 assert_eq!(
29 headers,
30 vec![
31 Header::new(":method", "GET"),
32 Header::new(":scheme", "https"),
33 Header::new(":authority", "something.com"),
34 Header::new(":path", "/")
35 ]
36 );
37 assert!(fin);
38 request
39 .set_response(
40 &[
41 Header::new(":status", "200"),
42 Header::new("content-length", "3"),
43 ],
44 RESPONSE_DATA,
45 )
46 .unwrap();
47 request_found = true;
48 }
49 }
50 assert!(request_found);
51 }
52
process_client_events(conn: &mut Http3Client)53 fn process_client_events(conn: &mut Http3Client) {
54 let mut response_header_found = false;
55 let mut response_data_found = false;
56 while let Some(event) = conn.next_event() {
57 match event {
58 Http3ClientEvent::HeaderReady { headers, fin, .. } => {
59 assert_eq!(
60 headers,
61 vec![
62 Header::new(":status", "200"),
63 Header::new("content-length", "3"),
64 ]
65 );
66 assert!(!fin);
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!(fin);
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!(response_header_found);
81 assert!(response_data_found);
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 mem::drop(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!(hconn_s.settings_received);
102 let out = hconn_c.process(out.dgram(), now());
103 // assert!(hconn_c.settings_received);
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(now(), "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 mem::drop(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 mem::drop(hconn_c.process(out.dgram(), now()));
132 let out = hconn_s.process(None, now());
133 mem::drop(hconn_c.process(out.dgram(), now()));
134 process_client_events(&mut hconn_c);
135 }
136