implement h2::server::Stream::send_reset(Reason) and Body::is_empty() (#22)
This commit is contained in:
		
				
					committed by
					
						 Carl Lerche
						Carl Lerche
					
				
			
			
				
	
			
			
			
						parent
						
							e8f757457b
						
					
				
				
					commit
					f839443ece
				
			
							
								
								
									
										11
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/lib.rs
									
									
									
									
									
								
							| @@ -55,6 +55,17 @@ pub struct Body<B: IntoBuf> { | |||||||
|  |  | ||||||
| // ===== impl Body ===== | // ===== impl Body ===== | ||||||
|  |  | ||||||
|  | impl<B: IntoBuf> Body<B> { | ||||||
|  |     pub fn is_empty(&self) -> bool { | ||||||
|  |         // If the recv side is closed and the receive queue is empty, the body is empty. | ||||||
|  |         self.inner.body_is_empty() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     pub fn release_capacity(&mut self, sz: usize) -> Result<(), ConnectionError> { | ||||||
|  |         self.inner.release_capacity(sz as proto::WindowSize) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| impl<B: IntoBuf> futures::Stream for Body<B> { | impl<B: IntoBuf> futures::Stream for Body<B> { | ||||||
|     type Item = Bytes; |     type Item = Bytes; | ||||||
|     type Error = ConnectionError; |     type Error = ConnectionError; | ||||||
|   | |||||||
| @@ -108,4 +108,13 @@ impl<B> Deque<B> { | |||||||
|             None => None, |             None => None, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     pub fn peek_front<'a>(&self, buf: &'a Buffer<B>) -> Option<&'a Frame<B>> { | ||||||
|  |         match self.indices { | ||||||
|  |             Some(idxs) => { | ||||||
|  |                 Some(&buf.slab[idxs.head].frame) | ||||||
|  |             } | ||||||
|  |             None => None, | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -225,6 +225,16 @@ impl<B> Recv<B> where B: Buf { | |||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     pub fn body_is_empty(&self, stream: &store::Ptr<B>) -> bool { | ||||||
|  |         if !stream.state.is_recv_closed() { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         stream.pending_recv.peek_front(&self.buffer) | ||||||
|  |             .map(|frame| !frame.is_data()) | ||||||
|  |             .unwrap_or(true) | ||||||
|  |     } | ||||||
|  |  | ||||||
|     pub fn recv_data(&mut self, |     pub fn recv_data(&mut self, | ||||||
|                      frame: frame::Data, |                      frame: frame::Data, | ||||||
|                      stream: &mut store::Ptr<B>) |                      stream: &mut store::Ptr<B>) | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| use {frame, ConnectionError}; | use {frame, ConnectionError}; | ||||||
|  | use error::User::InactiveStreamId; | ||||||
| use proto::*; | use proto::*; | ||||||
| use super::*; | use super::*; | ||||||
|  |  | ||||||
| @@ -108,6 +109,23 @@ impl<B> Send<B> where B: Buf { | |||||||
|         stream.state.send_close() |         stream.state.send_close() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     pub fn send_reset(&mut self, reason: Reason, | ||||||
|  |                       stream: &mut store::Ptr<B>, | ||||||
|  |                       task: &mut Option<Task>) | ||||||
|  |         -> Result<(), ConnectionError> | ||||||
|  |     { | ||||||
|  |         if stream.state.is_closed() { | ||||||
|  |             return Err(InactiveStreamId.into()) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         stream.state.send_reset(reason)?; | ||||||
|  |  | ||||||
|  |         let frame = frame::Reset::new(stream.id, reason); | ||||||
|  |         self.prioritize.queue_frame(frame.into(), stream, task); | ||||||
|  |  | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  |  | ||||||
|     pub fn send_data(&mut self, |     pub fn send_data(&mut self, | ||||||
|                      frame: frame::Data<B>, |                      frame: frame::Data<B>, | ||||||
|                      stream: &mut store::Ptr<B>, |                      stream: &mut store::Ptr<B>, | ||||||
|   | |||||||
| @@ -242,6 +242,19 @@ impl State { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Indicates that the local side will not send more data to the local. | ||||||
|  |     pub fn send_reset(&mut self, reason: Reason) -> Result<(), ConnectionError> { | ||||||
|  |         match self.inner { | ||||||
|  |             Idle => Err(ProtocolError.into()), | ||||||
|  |             Closed(..) => Ok(()), | ||||||
|  |             _ => { | ||||||
|  |                 trace!("send_reset: => Closed"); | ||||||
|  |                 self.inner = Closed(Some(Cause::Proto(reason))); | ||||||
|  |                 Ok(()) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /// Returns true if a stream with the current state counts against the |     /// Returns true if a stream with the current state counts against the | ||||||
|     /// concurrency limit. |     /// concurrency limit. | ||||||
|     pub fn is_counted(&self) -> bool { |     pub fn is_counted(&self) -> bool { | ||||||
|   | |||||||
| @@ -334,6 +334,16 @@ impl<B> StreamRef<B> | |||||||
|         me.actions.recv.take_request(&mut stream) |         me.actions.recv.take_request(&mut stream) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     pub fn send_reset<P: Peer>(&mut self, reason: Reason) -> Result<(), ConnectionError> { | ||||||
|  |         let mut me = self.inner.lock().unwrap(); | ||||||
|  |         let me = &mut *me; | ||||||
|  |  | ||||||
|  |         let stream = me.store.resolve(self.key); | ||||||
|  |         me.actions.transition::<P, _, _>(stream, move |actions, stream| { | ||||||
|  |             actions.send.send_reset(reason, stream, &mut actions.task) | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  |  | ||||||
|     pub fn send_response(&mut self, response: Response<()>, end_of_stream: bool) |     pub fn send_response(&mut self, response: Response<()>, end_of_stream: bool) | ||||||
|         -> Result<(), ConnectionError> |         -> Result<(), ConnectionError> | ||||||
|     { |     { | ||||||
| @@ -350,6 +360,15 @@ impl<B> StreamRef<B> | |||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     pub fn body_is_empty(&self) -> bool { | ||||||
|  |         let mut me = self.inner.lock().unwrap(); | ||||||
|  |         let me = &mut *me; | ||||||
|  |  | ||||||
|  |         let stream = me.store.resolve(self.key); | ||||||
|  |  | ||||||
|  |         me.actions.recv.body_is_empty(&stream) | ||||||
|  |     } | ||||||
|  |  | ||||||
|     pub fn poll_response(&mut self) -> Poll<Response<()>, ConnectionError> { |     pub fn poll_response(&mut self) -> Poll<Response<()>, ConnectionError> { | ||||||
|         let mut me = self.inner.lock().unwrap(); |         let mut me = self.inner.lock().unwrap(); | ||||||
|         let me = &mut *me; |         let me = &mut *me; | ||||||
|   | |||||||
| @@ -1,12 +1,12 @@ | |||||||
| use {frame, ConnectionError, StreamId}; | use {frame, Body, ConnectionError, StreamId}; | ||||||
| use Body; |  | ||||||
| use proto::{self, Connection, WindowSize}; | use proto::{self, Connection, WindowSize}; | ||||||
|  | use error::Reason; | ||||||
| use error::Reason::*; | use error::Reason::*; | ||||||
|  |  | ||||||
| use http::{self, Request, Response}; | use http::{self, Request, Response}; | ||||||
| use futures::{self, Future, Sink, Poll, Async, AsyncSink, IntoFuture}; | use futures::{self, Future, Sink, Poll, Async, AsyncSink, IntoFuture}; | ||||||
| use tokio_io::{AsyncRead, AsyncWrite}; | use tokio_io::{AsyncRead, AsyncWrite}; | ||||||
| use bytes::{Bytes, IntoBuf}; | use bytes::{Bytes, IntoBuf, Buf}; | ||||||
|  |  | ||||||
| use std::fmt; | use std::fmt; | ||||||
|  |  | ||||||
| @@ -191,6 +191,10 @@ impl<B: IntoBuf> Stream<B> { | |||||||
|     { |     { | ||||||
|         unimplemented!(); |         unimplemented!(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     pub fn send_reset(mut self, reason: Reason) -> Result<(), ConnectionError> { | ||||||
|  |         self.inner.send_reset::<Peer>(reason) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl Stream<Bytes> { | impl Stream<Bytes> { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user