Skip to content

Commit

Permalink
Enable default middlewares in server.listen
Browse files Browse the repository at this point in the history
Fixes http-rs#396 by ensuring the cookies and log middleware is only created
when we actually call .listen and not when nested.

This change adds a public `into_mock` method to Server so that an
instance with the cookie and log middleware can be crated from the
tests.
  • Loading branch information
vladan committed Apr 24, 2020
1 parent b2ed4d7 commit 41bfe18
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@ http = { version = "0.2.0", optional = true }
tokio = { version = "0.2.13", optional = true }
url = "2.1.1"
kv-log-macro = "1.0.4"
http-service-mock = "0.5.0"

[dev-dependencies]
async-std = { version = "1.4.0", features = ["unstable", "attributes"] }
basic-cookies = "0.1.3"
bytes = "0.4.12"
futures-fs = "0.0.5"
futures-util = { version = "0.3.0", features = ["compat"] }
http-service-mock = "0.5.0"
juniper = "0.14.1"
mime = "0.3.14"
mime_guess = "2.0.1"
Expand Down
27 changes: 19 additions & 8 deletions src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use async_std::net::ToSocketAddrs;
use async_std::sync::Arc;
use async_std::task::{Context, Poll};
use http_service::HttpService;
use http_service_mock;

use std::fmt::Debug;
use std::pin::Pin;
Expand Down Expand Up @@ -201,14 +202,11 @@ impl<State: Send + Sync + 'static> Server<State> {
/// # Ok(()) }) }
/// ```
pub fn with_state(state: State) -> Server<State> {
let mut server = Server {
Server {
router: Arc::new(Router::new()),
middleware: Arc::new(vec![]),
state: Arc::new(state),
};
server.middleware(cookies::CookiesMiddleware::new());
server.middleware(log::LogMiddleware::new());
server
}
}

/// Add a new route at the given `path`, relative to root.
Expand Down Expand Up @@ -284,12 +282,25 @@ impl<State: Send + Sync + 'static> Server<State> {
self
}

// Enable loggin and cookie middleware
fn enable_default_middleware(&mut self) {
self.middleware(cookies::CookiesMiddleware::new());
self.middleware(log::LogMiddleware::new());
}

pub fn into_mock(mut self) -> io::Result<http_service_mock::TestBackend<Self>> {
self.enable_default_middleware();
http_service_mock::make_server(self)
}

/// Asynchronously serve the app at the given address.
#[cfg(feature = "h1-server")]
pub async fn listen(self, addr: impl ToSocketAddrs) -> std::io::Result<()> {
pub async fn listen(mut self, addr: impl ToSocketAddrs) -> std::io::Result<()> {
let listener = async_std::net::TcpListener::bind(addr).await?;

let addr = format!("http://{}", listener.local_addr()?);

self.enable_default_middleware();

log::info!("Server is listening on: {}", addr);
let mut server = http_service_h1::Server::new(addr, listener.incoming(), self);

Expand Down Expand Up @@ -389,7 +400,7 @@ impl<State: Sync + Send + 'static, InnerState: Sync + Send + 'static> Endpoint<S
}

#[cfg(test)]
mod test {
pub mod server_test {
use crate as tide;

#[test]
Expand Down
29 changes: 27 additions & 2 deletions tests/cookies.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use cookie::Cookie;
use futures::executor::block_on;
use futures::AsyncReadExt;
use http_service_mock::make_server;

use tide::{Request, Response, Server, StatusCode};

Expand Down Expand Up @@ -42,7 +41,7 @@ fn app() -> crate::Server<()> {

fn make_request(endpoint: &str) -> http_types::Response {
let app = app();
let mut server = make_server(app).unwrap();
let mut server = app.into_mock().unwrap();
let mut req = http_types::Request::new(
http_types::Method::Get,
format!("http://example.com{}", endpoint).parse().unwrap(),
Expand Down Expand Up @@ -107,3 +106,29 @@ fn successfully_set_multiple_cookies() {
assert_eq!(cookie1, "C2=V2");
}
}

#[test]
fn nested_cookies() {
let mut inner = tide::new();
inner.at("/2").get(|_req| async move {
let mut r = Response::new(StatusCode::Ok);
r.set_cookie(Cookie::new("snack", "tuna"));
Ok(r.body_string(String::from("ok")))
});

let mut outer = app();
outer.at("/1").nest(inner);
let mut server = outer.into_mock().unwrap();

let req = http_types::Request::new(
http_types::Method::Get,
"http://example.com/1/2".parse().unwrap(),
);
let res = server.simulate(req).unwrap();

let cookie_header = res.header(&http_types::headers::SET_COOKIE);
let cookies = cookie_header.unwrap().iter().collect::<Vec<_>>();
assert_eq!(cookies.len(), 1, "{:?}", &cookies);
let cookie = cookies[0].as_str();
assert_eq!(cookie, "snack=tuna");
}

0 comments on commit 41bfe18

Please sign in to comment.