Get a server working
This commit is contained in:
@@ -8,7 +8,7 @@ futures = "0.1"
|
||||
tokio-io = "0.1"
|
||||
tokio-timer = "0.1"
|
||||
bytes = "0.4"
|
||||
http = { git = "https://github.com/carllerche/http" }
|
||||
http = { git = "https://github.com/carllerche/http", branch = "uri-parts" }
|
||||
byteorder = "1.0"
|
||||
log = "0.3.8"
|
||||
fnv = "1.0.5"
|
||||
|
||||
@@ -8,6 +8,8 @@ extern crate env_logger;
|
||||
|
||||
use h2::server;
|
||||
|
||||
use http::{response, status};
|
||||
|
||||
use futures::*;
|
||||
|
||||
use tokio_core::reactor;
|
||||
@@ -34,10 +36,17 @@ pub fn main() {
|
||||
|
||||
println!("H2 connection bound");
|
||||
|
||||
conn.for_each(|frame| {
|
||||
println!("RX: {:?}", frame);
|
||||
Ok(())
|
||||
})
|
||||
// Receive a request
|
||||
conn.into_future()
|
||||
.then(|res| {
|
||||
let (frame, conn) = res.unwrap();
|
||||
println!("Zomg frame; {:?}", frame);
|
||||
|
||||
let mut response = response::Head::default();
|
||||
response.status = status::NO_CONTENT;
|
||||
|
||||
conn.send_response(1, response, true)
|
||||
})
|
||||
})
|
||||
.then(|res| {
|
||||
let _ = res.unwrap();
|
||||
|
||||
@@ -3,7 +3,7 @@ use hpack;
|
||||
use frame::{self, Frame, Head, Kind, Error};
|
||||
use util::byte_str::ByteStr;
|
||||
|
||||
use http::{request, response, Method, StatusCode};
|
||||
use http::{request, response, version, uri, Method, StatusCode};
|
||||
use http::header::{self, HeaderMap, HeaderName, HeaderValue};
|
||||
|
||||
use bytes::{BytesMut, Bytes};
|
||||
@@ -201,7 +201,43 @@ impl Headers {
|
||||
}
|
||||
|
||||
pub fn into_request(self) -> request::Head {
|
||||
unimplemented!();
|
||||
let mut request = request::Head::default();
|
||||
|
||||
// TODO: should we distinguish between HTTP_2 and HTTP_2C?
|
||||
// carllerche/http#42
|
||||
request.version = version::HTTP_2;
|
||||
|
||||
if let Some(method) = self.pseudo.method {
|
||||
request.method = method;
|
||||
} else {
|
||||
// TODO: invalid request
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
// Convert the URI
|
||||
let mut parts = uri::Parts::default();
|
||||
|
||||
if let Some(scheme) = self.pseudo.scheme {
|
||||
// TODO: Don't unwrap
|
||||
parts.scheme = Some(uri::Scheme::try_from_shared(scheme.into()).unwrap());
|
||||
}
|
||||
|
||||
if let Some(authority) = self.pseudo.authority {
|
||||
// TODO: Don't unwrap
|
||||
parts.authority = Some(uri::Authority::try_from_shared(authority.into()).unwrap());
|
||||
}
|
||||
|
||||
if let Some(path) = self.pseudo.path {
|
||||
// TODO: Don't unwrap
|
||||
parts.origin_form = Some(uri::OriginForm::try_from_shared(path.into()).unwrap());
|
||||
}
|
||||
|
||||
request.uri = parts.into();
|
||||
|
||||
// Set the header fields
|
||||
request.headers = self.fields;
|
||||
|
||||
request
|
||||
}
|
||||
|
||||
pub fn encode(self, encoder: &mut hpack::Encoder, dst: &mut BytesMut)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use {frame, Frame, ConnectionError, Peer, StreamId};
|
||||
use client::Client;
|
||||
use server::Server;
|
||||
use proto::{self, ReadySink, State};
|
||||
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
|
||||
use http::{request};
|
||||
use http::{request, response};
|
||||
|
||||
use futures::*;
|
||||
|
||||
@@ -52,6 +53,23 @@ impl<T> Connection<T, Client>
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Connection<T, Server>
|
||||
where T: AsyncRead + AsyncWrite,
|
||||
{
|
||||
pub fn send_response(self,
|
||||
id: StreamId, // TODO: Generate one internally?
|
||||
response: response::Head,
|
||||
end_of_stream: bool)
|
||||
-> sink::Send<Self>
|
||||
{
|
||||
self.send(Frame::Headers {
|
||||
id: id,
|
||||
headers: response,
|
||||
end_of_stream: end_of_stream,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, P> Stream for Connection<T, P>
|
||||
where T: AsyncRead + AsyncWrite,
|
||||
P: Peer,
|
||||
@@ -126,7 +144,9 @@ impl<T, P> Sink for Connection<T, P>
|
||||
match item {
|
||||
Frame::Headers { id, headers, end_of_stream } => {
|
||||
// Ensure ID is valid
|
||||
try!(P::check_initiating_id(id));
|
||||
// TODO: This check should only be done **if** this is a new
|
||||
// stream ID
|
||||
// try!(P::check_initiating_id(id));
|
||||
|
||||
// TODO: Ensure available capacity for a new stream
|
||||
// This won't be as simple as self.streams.len() as closed
|
||||
|
||||
@@ -58,3 +58,9 @@ impl<'a> From<&'a str> for ByteStr {
|
||||
ByteStr { bytes: Bytes::from(src) }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ByteStr> for Bytes {
|
||||
fn from(src: ByteStr) -> Self {
|
||||
src.bytes
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user