More code
This commit is contained in:
@@ -24,6 +24,7 @@ pub struct Client<T, B: IntoBuf> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Client half of an active HTTP/2.0 stream.
|
/// Client half of an active HTTP/2.0 stream.
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Stream<B: IntoBuf> {
|
pub struct Stream<B: IntoBuf> {
|
||||||
inner: proto::StreamRef<Peer, B::Buf>,
|
inner: proto::StreamRef<Peer, B::Buf>,
|
||||||
}
|
}
|
||||||
@@ -89,6 +90,19 @@ impl<T, B> Client<T, B>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T, B> Future for Client<T, B>
|
||||||
|
// TODO: Get rid of 'static
|
||||||
|
where T: AsyncRead + AsyncWrite + 'static,
|
||||||
|
B: IntoBuf + 'static,
|
||||||
|
{
|
||||||
|
type Item = ();
|
||||||
|
type Error = ConnectionError;
|
||||||
|
|
||||||
|
fn poll(&mut self) -> Poll<(), ConnectionError> {
|
||||||
|
self.connection.poll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, B> fmt::Debug for Client<T, B>
|
impl<T, B> fmt::Debug for Client<T, B>
|
||||||
where T: fmt::Debug,
|
where T: fmt::Debug,
|
||||||
B: fmt::Debug + IntoBuf,
|
B: fmt::Debug + IntoBuf,
|
||||||
@@ -145,6 +159,15 @@ impl<B: IntoBuf> Stream<B> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<B: IntoBuf> Future for Stream<B> {
|
||||||
|
type Item = Response<()>;
|
||||||
|
type Error = ConnectionError;
|
||||||
|
|
||||||
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
|
self.poll_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ===== impl Peer =====
|
// ===== impl Peer =====
|
||||||
|
|
||||||
impl proto::Peer for Peer {
|
impl proto::Peer for Peer {
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ impl<T, P, B> Connection<T, P, B>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Advances the internal state of the connection.
|
/// Advances the internal state of the connection.
|
||||||
pub fn poll(&mut self) -> Poll<Option<()>, ConnectionError> {
|
pub fn poll(&mut self) -> Poll<(), ConnectionError> {
|
||||||
use frame::Frame::*;
|
use frame::Frame::*;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@@ -183,11 +183,9 @@ impl<T, P, B> Connection<T, P, B>
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
unimplemented!();
|
// TODO: Is this correct?
|
||||||
/*
|
|
||||||
trace!("codec closed");
|
trace!("codec closed");
|
||||||
return Ok(Async::Ready(None));
|
return Ok(Async::Ready(()));
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ pub struct Deque<B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Tracks the head & tail for a sequence of frames in a `Buffer`.
|
/// Tracks the head & tail for a sequence of frames in a `Buffer`.
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default, Copy, Clone)]
|
||||||
struct Indices {
|
struct Indices {
|
||||||
head: usize,
|
head: usize,
|
||||||
tail: usize,
|
tail: usize,
|
||||||
@@ -27,7 +27,7 @@ struct Indices {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Slot<B> {
|
struct Slot<B> {
|
||||||
frame: Frame<B>,
|
frame: Frame<B>,
|
||||||
next: usize,
|
next: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> Buffer<B> {
|
impl<B> Buffer<B> {
|
||||||
@@ -50,11 +50,42 @@ impl<B> Deque<B> {
|
|||||||
self.indices.is_none()
|
self.indices.is_none()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_back(&mut self, buf: &mut Buffer<B>, val: Frame<B>) {
|
pub fn push_back(&mut self, buf: &mut Buffer<B>, frame: Frame<B>) {
|
||||||
unimplemented!();
|
let key = buf.slab.insert(Slot {
|
||||||
|
frame,
|
||||||
|
next: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
match self.indices {
|
||||||
|
Some(ref mut idxs) => {
|
||||||
|
buf.slab[idxs.tail].next = Some(key);
|
||||||
|
idxs.tail = key;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.indices = Some(Indices {
|
||||||
|
head: key,
|
||||||
|
tail: key,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop_front(&mut self, buf: &mut Buffer<B>) -> Option<Frame<B>> {
|
pub fn pop_front(&mut self, buf: &mut Buffer<B>) -> Option<Frame<B>> {
|
||||||
unimplemented!();
|
match self.indices {
|
||||||
|
Some(mut idxs) => {
|
||||||
|
let mut slot = buf.slab.remove(idxs.head);
|
||||||
|
|
||||||
|
if idxs.head == idxs.tail {
|
||||||
|
assert!(slot.next.is_none());
|
||||||
|
self.indices = None;
|
||||||
|
} else {
|
||||||
|
idxs.head = slot.next.take().unwrap();
|
||||||
|
self.indices = Some(idxs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Some(slot.frame);
|
||||||
|
}
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,27 +38,8 @@ impl<B> Prioritize<B>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The next pointer shouldn't be set
|
|
||||||
debug_assert!(stream.next_pending_send.is_none());
|
|
||||||
|
|
||||||
// Queue the stream
|
// Queue the stream
|
||||||
match self.pending_send {
|
self.push_sender(stream);
|
||||||
Some(ref mut idxs) => {
|
|
||||||
// Update the current tail node to point to `stream`
|
|
||||||
stream.resolve(idxs.tail).next_pending_send = Some(stream.key());
|
|
||||||
|
|
||||||
// Update the tail pointer
|
|
||||||
idxs.tail = stream.key();
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self.pending_send = Some(Indices {
|
|
||||||
head: stream.key(),
|
|
||||||
tail: stream.key(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.is_pending_send = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_complete<T>(&mut self,
|
pub fn poll_complete<T>(&mut self,
|
||||||
@@ -88,6 +69,59 @@ impl<B> Prioritize<B>
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn pop_frame(&mut self, store: &mut Store<B>) -> Option<Frame<B>> {
|
fn pop_frame(&mut self, store: &mut Store<B>) -> Option<Frame<B>> {
|
||||||
unimplemented!();
|
match self.pop_sender(store) {
|
||||||
|
Some(mut stream) => {
|
||||||
|
let frame = stream.pending_send.pop_front(&mut self.buffer).unwrap();
|
||||||
|
|
||||||
|
if !stream.pending_send.is_empty() {
|
||||||
|
self.push_sender(&mut stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(frame)
|
||||||
|
}
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push_sender(&mut self, stream: &mut store::Ptr<B>) {
|
||||||
|
// The next pointer shouldn't be set
|
||||||
|
debug_assert!(stream.next_pending_send.is_none());
|
||||||
|
|
||||||
|
// Queue the stream
|
||||||
|
match self.pending_send {
|
||||||
|
Some(ref mut idxs) => {
|
||||||
|
// Update the current tail node to point to `stream`
|
||||||
|
stream.resolve(idxs.tail).next_pending_send = Some(stream.key());
|
||||||
|
|
||||||
|
// Update the tail pointer
|
||||||
|
idxs.tail = stream.key();
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.pending_send = Some(Indices {
|
||||||
|
head: stream.key(),
|
||||||
|
tail: stream.key(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.is_pending_send = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pop_sender<'a>(&mut self, store: &'a mut Store<B>) -> Option<store::Ptr<'a, B>> {
|
||||||
|
if let Some(mut idxs) = self.pending_send {
|
||||||
|
let mut stream = store.resolve(idxs.head);
|
||||||
|
|
||||||
|
if idxs.head == idxs.tail {
|
||||||
|
assert!(stream.next_pending_send.is_none());
|
||||||
|
self.pending_send = None;
|
||||||
|
} else {
|
||||||
|
idxs.head = stream.next_pending_send.take().unwrap();
|
||||||
|
self.pending_send = Some(idxs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Some(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pub(super) struct Ptr<'a, B: 'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// References an entry in the store.
|
/// References an entry in the store.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub(super) struct Key(usize);
|
pub(super) struct Key(usize);
|
||||||
|
|
||||||
pub(super) enum Entry<'a, B: 'a> {
|
pub(super) enum Entry<'a, B: 'a> {
|
||||||
|
|||||||
@@ -271,6 +271,11 @@ impl<B> Streams<client::Peer, B>
|
|||||||
pub fn send_request(&mut self, request: Request<()>, end_of_stream: bool)
|
pub fn send_request(&mut self, request: Request<()>, end_of_stream: bool)
|
||||||
-> Result<StreamRef<client::Peer, B>, ConnectionError>
|
-> Result<StreamRef<client::Peer, B>, ConnectionError>
|
||||||
{
|
{
|
||||||
|
// TODO: There is a hazard with assigning a stream ID before the
|
||||||
|
// prioritize layer. If prioritization reorders new streams, this
|
||||||
|
// implicitly closes the earlier stream IDs.
|
||||||
|
//
|
||||||
|
// See: carllerche/h2#11
|
||||||
let key = {
|
let key = {
|
||||||
let mut me = self.inner.lock().unwrap();
|
let mut me = self.inner.lock().unwrap();
|
||||||
let me = &mut *me;
|
let me = &mut *me;
|
||||||
|
|||||||
@@ -23,16 +23,21 @@ fn send_recv_headers_only() {
|
|||||||
.read(&[0, 0, 1, 1, 5, 0, 0, 0, 1, 0x89])
|
.read(&[0, 0, 1, 1, 5, 0, 0, 0, 1, 0x89])
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let h2 = client::handshake(mock)
|
let mut h2 = Client::handshake(mock)
|
||||||
.wait().unwrap();
|
.wait().unwrap();
|
||||||
|
|
||||||
// Send the request
|
// Send the request
|
||||||
let mut request = request::Head::default();
|
let request = Request::builder()
|
||||||
request.uri = "https://http2.akamai.com/".parse().unwrap();
|
.uri("https://http2.akamai.com/")
|
||||||
|
.body(()).unwrap();
|
||||||
|
|
||||||
info!("sending request");
|
info!("sending request");
|
||||||
let h2 = h2.send_request(1.into(), request, true).wait().unwrap();
|
let stream = h2.request(request, true).unwrap();
|
||||||
|
|
||||||
|
let resp = stream.select2(h2).wait().ok().unwrap();
|
||||||
|
println!("GOT: {:?}", resp);
|
||||||
|
|
||||||
|
/*
|
||||||
// Get the response
|
// Get the response
|
||||||
|
|
||||||
info!("getting response");
|
info!("getting response");
|
||||||
@@ -48,8 +53,10 @@ fn send_recv_headers_only() {
|
|||||||
// No more frames
|
// No more frames
|
||||||
info!("ensure no more responses");
|
info!("ensure no more responses");
|
||||||
assert!(Stream::wait(h2).next().is_none());;
|
assert!(Stream::wait(h2).next().is_none());;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#[test]
|
#[test]
|
||||||
fn send_recv_data() {
|
fn send_recv_data() {
|
||||||
let _ = env_logger::init();
|
let _ = env_logger::init();
|
||||||
@@ -257,3 +264,4 @@ fn send_data_without_headers() {
|
|||||||
#[ignore]
|
#[ignore]
|
||||||
fn exceed_max_streams() {
|
fn exceed_max_streams() {
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ pub use self::http::{
|
|||||||
response,
|
response,
|
||||||
method,
|
method,
|
||||||
status,
|
status,
|
||||||
|
Request,
|
||||||
|
Response,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use self::h2::{
|
pub use self::h2::client::{self, Client};
|
||||||
client,
|
// pub use self::h2::server;
|
||||||
server,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub use self::bytes::{
|
pub use self::bytes::{
|
||||||
Buf,
|
Buf,
|
||||||
|
|||||||
Reference in New Issue
Block a user