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