Skip to content

perf: switch to url::Url for server addresses #103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions examples/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ use async_std::net::{TcpListener, TcpStream};
use async_std::prelude::*;
use async_std::task;
use http_types::{Response, StatusCode};
use url::Url;

#[async_std::main]
async fn main() -> http_types::Result<()> {
// Open up a TCP connection and create a URL.
let listener = TcpListener::bind(("127.0.0.1", 8080)).await?;
let addr = format!("http://{}", listener.local_addr()?);
let addr = Url::parse(&format!("http://{}", listener.local_addr()?))?;
println!("listening on {}", addr);

// For each incoming TCP connection, spawn a task and call `accept`.
Expand All @@ -25,7 +26,7 @@ async fn main() -> http_types::Result<()> {
}

// Take a TCP stream, and convert it into sequential HTTP request / response pairs.
async fn accept(addr: String, stream: TcpStream) -> http_types::Result<()> {
async fn accept(addr: Url, stream: TcpStream) -> http_types::Result<()> {
println!("starting new connection from {}", stream.peer_addr()?);
async_h1::accept(&addr, stream.clone(), |_req| async move {
let mut res = Response::new(StatusCode::Ok);
Expand Down
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,16 @@
//! async fn main() -> http_types::Result<()> {
//! // Open up a TCP connection and create a URL.
//! let listener = TcpListener::bind(("127.0.0.1", 8080)).await?;
//! let addr = format!("http://{}", listener.local_addr()?);
//! let addr: url::Url = format!("http://{}", listener.local_addr()?).parse()?;
//! println!("listening on {}", addr);
//!
//! // For each incoming TCP connection, spawn a task and call `accept`.
//! let mut incoming = listener.incoming();
//! while let Some(stream) = incoming.next().await {
//! let stream = stream?;
//! let addr = addr.clone();
//! task::spawn(async {
//! if let Err(err) = accept(addr, stream).await {
//! task::spawn(async move {
//! if let Err(err) = accept(&addr, stream).await {
//! eprintln!("{}", err);
//! }
//! });
Expand All @@ -78,7 +78,7 @@
//! }
//!
//! // Take a TCP stream, and convert it into sequential HTTP request / response pairs.
//! async fn accept(addr: String, stream: TcpStream) -> http_types::Result<()> {
//! async fn accept(addr: &url::Url, stream: TcpStream) -> http_types::Result<()> {
//! println!("starting new connection from {}", stream.peer_addr()?);
//! async_h1::accept(&addr, stream.clone(), |_req| async move {
//! let mut res = Response::new(StatusCode::Ok);
Expand Down
5 changes: 3 additions & 2 deletions src/server/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use async_std::prelude::*;
use http_types::headers::{HeaderName, HeaderValue, CONTENT_LENGTH, TRANSFER_ENCODING};
use http_types::{ensure, ensure_eq, format_err};
use http_types::{Body, Method, Request};
use url::Url;

use crate::chunked::ChunkedDecoder;
use crate::{MAX_HEADERS, MAX_HEAD_LENGTH};
Expand All @@ -18,7 +19,7 @@ const LF: u8 = b'\n';
const HTTP_1_1_VERSION: u8 = 1;

/// Decode an HTTP request on the server.
pub(crate) async fn decode<R>(addr: &str, reader: R) -> http_types::Result<Option<Request>>
pub(crate) async fn decode<R>(addr: &Url, reader: R) -> http_types::Result<Option<Request>>
where
R: Read + Unpin + Send + Sync + 'static,
{
Expand Down Expand Up @@ -59,7 +60,7 @@ where

let uri = httparse_req.path;
let uri = uri.ok_or_else(|| format_err!("No uri found"))?;
let uri = url::Url::parse(&format!("{}{}", addr, uri))?;
let uri = addr.join(uri)?;

let version = httparse_req.version;
let version = version.ok_or_else(|| format_err!("No version found"))?;
Expand Down
8 changes: 4 additions & 4 deletions src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
use std::time::Duration;

use async_std::future::{timeout, Future, TimeoutError};
use async_std::io::{self};
use async_std::io::{Read, Write};
use async_std::io::{self, Read, Write};
use http_types::{Request, Response};
use url::Url;

mod decode;
mod encode;
Expand All @@ -31,7 +31,7 @@ impl Default for ServerOptions {
/// Accept a new incoming HTTP/1.1 connection.
///
/// Supports `KeepAlive` requests by default.
pub async fn accept<RW, F, Fut>(addr: &str, io: RW, endpoint: F) -> http_types::Result<()>
pub async fn accept<RW, F, Fut>(addr: &Url, io: RW, endpoint: F) -> http_types::Result<()>
where
RW: Read + Write + Clone + Send + Sync + Unpin + 'static,
F: Fn(Request) -> Fut,
Expand All @@ -44,7 +44,7 @@ where
///
/// Supports `KeepAlive` requests by default.
pub async fn accept_with_opts<RW, F, Fut>(
addr: &str,
addr: &Url,
mut io: RW,
endpoint: F,
opts: ServerOptions,
Expand Down
16 changes: 10 additions & 6 deletions tests/server-chunked-encode-large.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,16 @@ const RESPONSE: &'static str = concat![
#[async_std::test]
async fn server_chunked_large() {
let case = TestCase::new(REQUEST, "").await;
async_h1::accept("http://example.com", case.clone(), |_| async {
let mut res = Response::new(StatusCode::Ok);
let body = Cursor::new(TEXT.to_owned());
res.set_body(Body::from_reader(body, None));
Ok(res)
})
async_h1::accept(
&"http://example.com".parse().unwrap(),
case.clone(),
|_| async {
let mut res = Response::new(StatusCode::Ok);
let body = Cursor::new(TEXT.to_owned());
res.set_body(Body::from_reader(body, None));
Ok(res)
},
)
.await
.unwrap();
case.assert_writer_with(RESPONSE, common::munge_date).await;
Expand Down
16 changes: 10 additions & 6 deletions tests/server-chunked-encode-small.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,16 @@ const RESPONSE: &'static str = concat![
#[async_std::test]
async fn server_chunked_large() {
let case = TestCase::new(REQUEST, "").await;
async_h1::accept("http://example.com", case.clone(), |_| async {
let mut res = Response::new(StatusCode::Ok);
let body = Cursor::new(TEXT.to_owned());
res.set_body(Body::from_reader(body, None));
Ok(res)
})
async_h1::accept(
&"http://example.com".parse().unwrap(),
case.clone(),
|_| async {
let mut res = Response::new(StatusCode::Ok);
let body = Cursor::new(TEXT.to_owned());
res.set_body(Body::from_reader(body, None));
Ok(res)
},
)
.await
.unwrap();
case.assert_writer_with(RESPONSE, common::munge_date).await;
Expand Down
20 changes: 10 additions & 10 deletions tests/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ async fn test_basic_request() {
"fixtures/response-add-date.txt",
)
.await;
let addr = "http://example.com";
let addr = "http://example.com".parse().unwrap();

async_h1::accept(addr, case.clone(), |_req| async {
async_h1::accept(&addr, case.clone(), |_req| async {
let mut res = Response::new(StatusCode::Ok);
res.set_body("");
Ok(res)
Expand All @@ -32,9 +32,9 @@ async fn test_chunked_basic() {
"fixtures/response-chunked-basic.txt",
)
.await;
let addr = "http://example.com";
let addr = "http://example.com".parse().unwrap();

async_h1::accept(addr, case.clone(), |_req| async {
async_h1::accept(&addr, case.clone(), |_req| async {
let mut res = Response::new(StatusCode::Ok);
res.set_body(Body::from_reader(
Cursor::new(b"Mozilla")
Expand All @@ -59,8 +59,8 @@ async fn test_chunked_echo() {
)
.await;

let addr = "http://example.com";
async_h1::accept(addr, case.clone(), |req| async {
let addr = "http://example.com".parse().unwrap();
async_h1::accept(&addr, case.clone(), |req| async {
let ct = req.content_type();
let body: Body = req.into();

Expand All @@ -86,9 +86,9 @@ async fn test_unexpected_eof() {
"fixtures/response-unexpected-eof.txt",
)
.await;
let addr = "http://example.com";
let addr = "http://example.com".parse().unwrap();

async_h1::accept(addr, case.clone(), |req| async {
async_h1::accept(&addr, case.clone(), |req| async {
let mut res = Response::new(StatusCode::Ok);
let ct = req.content_type();
let body: Body = req.into();
Expand All @@ -112,9 +112,9 @@ async fn test_invalid_trailer() {
"fixtures/response-invalid-trailer.txt",
)
.await;
let addr = "http://example.com";
let addr = "http://example.com".parse().unwrap();

async_h1::accept(addr, case.clone(), |req| async {
async_h1::accept(&addr, case.clone(), |req| async {
let mut res = Response::new(StatusCode::Ok);
let ct = req.content_type();
let body: Body = req.into();
Expand Down