1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use crate::error::Reason;
use crate::frame::{Pseudo, StreamId};
use crate::proto::{Error, Open};
use http::{HeaderMap, Request, Response};
use std::fmt;
pub(crate) trait Peer {
type Poll: fmt::Debug;
const NAME: &'static str;
fn r#dyn() -> Dyn;
fn is_server() -> bool;
fn convert_poll_message(
pseudo: Pseudo,
fields: HeaderMap,
stream_id: StreamId,
) -> Result<Self::Poll, Error>;
fn is_local_init(id: StreamId) -> bool {
assert!(!id.is_zero());
Self::is_server() == id.is_server_initiated()
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub(crate) enum Dyn {
Client,
Server,
}
#[derive(Debug)]
pub enum PollMessage {
Client(Response<()>),
Server(Request<()>),
}
impl Dyn {
pub fn is_server(&self) -> bool {
*self == Dyn::Server
}
pub fn is_local_init(&self, id: StreamId) -> bool {
assert!(!id.is_zero());
self.is_server() == id.is_server_initiated()
}
pub fn convert_poll_message(
&self,
pseudo: Pseudo,
fields: HeaderMap,
stream_id: StreamId,
) -> Result<PollMessage, Error> {
if self.is_server() {
crate::server::Peer::convert_poll_message(pseudo, fields, stream_id)
.map(PollMessage::Server)
} else {
crate::client::Peer::convert_poll_message(pseudo, fields, stream_id)
.map(PollMessage::Client)
}
}
pub fn ensure_can_open(&self, id: StreamId, mode: Open) -> Result<(), Error> {
if self.is_server() {
if mode.is_push_promise() || !id.is_client_initiated() {
proto_err!(conn: "cannot open stream {:?} - not client initiated", id);
return Err(Error::library_go_away(Reason::PROTOCOL_ERROR));
}
Ok(())
} else {
if !mode.is_push_promise() || !id.is_server_initiated() {
proto_err!(conn: "cannot open stream {:?} - not server initiated", id);
return Err(Error::library_go_away(Reason::PROTOCOL_ERROR));
}
Ok(())
}
}
}