Skip to content

Commit

Permalink
Use safina v0.6. Use safina::async_test.
Browse files Browse the repository at this point in the history
  • Loading branch information
mleonhard committed Nov 3, 2024
1 parent 07c24eb commit e134152
Show file tree
Hide file tree
Showing 13 changed files with 355 additions and 384 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ include_dir = { version = "0.7", optional = true }
permit = "^0.2"
rand = { version = "0.8", features = ["small_rng"] }
safe-regex = "0.3"
safina = { version = "0.4", path = "../safina-rs/safina", features = ["executor", "sync", "timer"] }
safina = { version = "0.6", path = "../safina-rs/safina", features = ["executor", "sync", "timer"] }
serde = { version = "1", optional = true, features = ["derive"] }
# TODO: Prevent these deps from appearing as features.
serde_json = { version = "1", optional = true }
Expand All @@ -35,6 +35,7 @@ temp-file = "0.1"
url = "2"

[dev-dependencies]
safina = { version = "0.6", path = "../safina-rs/safina", features = ["async_test"] }

[[example]]
name = "html_form"
Expand Down
13 changes: 8 additions & 5 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,12 @@ Symbols:
Functions Expressions Impls Traits Methods Dependency
0/0 0/0 0/0 0/0 0/0 🔒 servlin 0.6.0
0/0 0/0 0/0 0/0 0/0 🔒 ├── safina 0.4.0
0/0 0/0 0/0 0/0 0/0 🔒 ├── safina 0.6.0
0/0 0/0 0/0 0/0 0/0 🔒 │ └── safina-macros 0.1.3
0/0 0/0 0/0 0/0 0/0 🔒 │ ├── safe-proc-macro2 1.0.67
0/0 4/4 0/0 0/0 0/0 ☢️ │ │ └── unicode-ident 1.0.13
0/0 0/0 0/0 0/0 0/0 🔒 │ └── safe-quote 1.0.15
0/0 0/0 0/0 0/0 0/0 🔒 │ └── safe-proc-macro2 1.0.67
0/0 0/0 0/0 0/0 0/0 🔒 ├── async-fs 2.1.2
4/4 222/222 40/40 0/0 13/13 ☢️ │ ├── async-lock 3.4.0
0/0 2/2 0/0 0/0 0/0 ☢️ │ │ ├── event-listener-strategy 0.5.2
Expand Down Expand Up @@ -202,11 +207,9 @@ Functions Expressions Impls Traits Methods Dependency
0/0 0/0 0/0 0/0 0/0 🔒 ├── safe-regex 0.3.0
0/0 0/0 0/0 0/0 0/0 🔒 │ └── safe-regex-macro 0.3.0
0/0 0/0 0/0 0/0 0/0 🔒 │ ├── safe-proc-macro2 1.0.67
0/0 4/4 0/0 0/0 0/0 ☢️ │ │ └── unicode-ident 1.0.13
0/0 0/0 0/0 0/0 0/0 🔒 │ └── safe-regex-compiler 0.3.0
0/0 0/0 0/0 0/0 0/0 🔒 │ ├── safe-proc-macro2 1.0.67
0/0 0/0 0/0 0/0 0/0 🔒 │ └── safe-quote 1.0.15
0/0 0/0 0/0 0/0 0/0 🔒 │ └── safe-proc-macro2 1.0.67
0/0 5/5 0/0 0/0 0/0 ☢️ ├── serde 1.0.210
0/0 66/69 0/0 0/0 0/0 ☢️ ├── serde_json 1.0.132
0/0 7/7 0/0 0/0 0/0 ☢️ │ ├── itoa 1.0.11
Expand Down Expand Up @@ -240,9 +243,9 @@ Functions Expressions Impls Traits Methods Dependency
See [rust-webserver-comparison.md](https://github.com/mleonhard/servlin/blob/main/rust-webserver-comparison.md).

# Changelog
- v0.6.0 2024-10-26
- v0.6.0 2024-11-02
- Remove `servlin::reexports` module.
- Use `safina` v0.4.0.
- Use `safina` v0.6.0.
- v0.5.1 2024-10-26 - Remove dependency on `once_cell`.
- v0.5.0 2024-10-21 - Remove `LogFileWriterBuilder`.
- v0.4.3 - Implement `From<Cow<'_, str>>` and `From<&Path>` for `TagValue`.
Expand Down
2 changes: 1 addition & 1 deletion examples/async-handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@

pub fn main() {
// safina::timer::start_timer_thread();
// let executor = safina::executor::Executor::default();
// let executor: Arc<Executor> = Arc::default();
// let cache_dir = TempDir::new().unwrap();
// let state = Arc::new(State {
// upload_count: AtomicUsize::new(0),
Expand Down
3 changes: 2 additions & 1 deletion examples/events-sse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
//! ```
#![forbid(unsafe_code)]
use permit::Permit;
use safina::executor::Executor;
use servlin::log::log_request_and_response;
use servlin::{
socket_addr_127_0_0_1, Error, Event, EventSender, HttpServerBuilder, Request, Response,
Expand Down Expand Up @@ -83,7 +84,7 @@ pub fn main() {
let state_clone = state.clone();
std::thread::spawn(move || event_sender_thread(state_clone, event_sender_thread_permit));
safina::timer::start_timer_thread();
let executor = safina::executor::Executor::default();
let executor: Arc<Executor> = Arc::default();
let request_handler =
move |req: Request| log_request_and_response(req, |req| handle_req(state, req)).unwrap();
executor
Expand Down
3 changes: 2 additions & 1 deletion examples/html_form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
//! Access the form with your web browser:
//! <http://127.0.0.1:8000/>
#![forbid(unsafe_code)]
use safina::executor::Executor;
use serde::Deserialize;
use servlin::log::log_request_and_response;
use servlin::{socket_addr_127_0_0_1, Error, HttpServerBuilder, Request, Response};
Expand Down Expand Up @@ -111,7 +112,7 @@ fn handle_req(state: Arc<State>, req: Request) -> Result<Response, Error> {
pub fn main() {
println!("Access the server at http://127.0.0.1:8000/");
safina::timer::start_timer_thread();
let executor = safina::executor::Executor::default();
let executor: Arc<Executor> = Arc::default();
let state = Arc::new(State::new());
let request_handler =
move |req: Request| log_request_and_response(req, |req| handle_req(state, req)).unwrap();
Expand Down
3 changes: 2 additions & 1 deletion examples/http-put.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
//! $
//! ```
#![forbid(unsafe_code)]
use safina::executor::Executor;
use servlin::log::{log_request_and_response, set_global_logger, LogFileWriter};
use servlin::{socket_addr_127_0_0_1, Error, HttpServerBuilder, Request, Response};
use std::io::Read;
Expand Down Expand Up @@ -83,7 +84,7 @@ pub fn main() {
)
.unwrap();
safina::timer::start_timer_thread();
let executor = safina::executor::Executor::default();
let executor: Arc<Executor> = Arc::default();
let cache_dir = TempDir::new().unwrap();
let state = Arc::new(State::new());
let request_handler =
Expand Down
5 changes: 3 additions & 2 deletions examples/json_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
//! {"count":5}
//! ```
#![forbid(unsafe_code)]
use safina::executor::Executor;
use serde::Deserialize;
use serde_json::json;
use servlin::log::log_request_and_response;
Expand Down Expand Up @@ -90,7 +91,7 @@ fn add(state: Arc<State>, req: Request) -> Result<Response, Error> {
input.num
};
state.add(num);
Ok(Response::json(200, json!({ "count": state.get() })).unwrap())
Response::json(200, json!({ "count": state.get() }))
}

fn handle_req(state: Arc<State>, req: Request) -> Result<Response, Error> {
Expand All @@ -106,7 +107,7 @@ fn handle_req(state: Arc<State>, req: Request) -> Result<Response, Error> {
pub fn main() {
println!("Access the API at http://127.0.0.1:8000/");
safina::timer::start_timer_thread();
let executor = safina::executor::Executor::default();
let executor: Arc<Executor> = Arc::default();
let state = Arc::new(State::new());
let request_handler =
move |req: Request| log_request_and_response(req, |req| handle_req(state, req)).unwrap();
Expand Down
4 changes: 3 additions & 1 deletion examples/minimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@
//! $
//! ```
#![forbid(unsafe_code)]
use safina::executor::Executor;
use servlin::{socket_addr_127_0_0_1, HttpServerBuilder, Request, Response};
use std::sync::Arc;

pub fn main() {
safina::timer::start_timer_thread();
let executor = safina::executor::Executor::default();
let executor: Arc<Executor> = Arc::default();
executor
.block_on(
HttpServerBuilder::new()
Expand Down
25 changes: 15 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@
//! See [rust-webserver-comparison.md](https://github.com/mleonhard/servlin/blob/main/rust-webserver-comparison.md).
//!
//! # Changelog
//! - v0.6.0 2024-10-26
//! - v0.6.0 2024-11-02
//! - Remove `servlin::reexports` module.
//! - Use `safina` v0.4.0.
//! - Use `safina` v0.6.0.
//! - v0.5.1 2024-10-26 - Remove dependency on `once_cell`.
//! - v0.5.0 2024-10-21 - Remove `LogFileWriterBuilder`.
//! - v0.4.3 - Implement `From<Cow<'_, str>>` and `From<&Path>` for `TagValue`.
Expand Down Expand Up @@ -298,12 +298,15 @@ impl HttpServerBuilder {
/// # drop(permit);
/// # });
/// safina::timer::start_timer_thread();
/// safina::executor::Executor::default().block_on(
/// safina::executor::Executor::new(1, 1)
/// .unwrap()
/// .block_on(
/// HttpServerBuilder::new()
/// # .permit(server_permit)
/// .receive_large_bodies(cache_dir.path())
/// .spawn_and_join(handler)
/// ).unwrap();
/// # .permit(server_permit)
/// .receive_large_bodies(cache_dir.path())
/// .spawn_and_join(handler)
/// )
/// .unwrap();
/// ```
#[must_use]
pub fn receive_large_bodies(mut self, cache_dir: &std::path::Path) -> Self {
Expand Down Expand Up @@ -334,13 +337,15 @@ impl HttpServerBuilder {
///
/// # Example
/// ```
/// use servlin::{Response, HttpServerBuilder};
/// use std::net::SocketAddr;
/// use permit::Permit;
/// use std::sync::Arc;
/// use permit::Permit;
/// use safina::executor::Executor;
/// use servlin::{Response, HttpServerBuilder};
/// # fn do_some_requests(addr: SocketAddr) -> Result<(),()> { Ok(()) }
///
/// safina::timer::start_timer_thread();
/// let executor = safina::executor::Executor::default();
/// let executor: Arc<Executor> = Arc::default();
/// let permit = Permit::new();
/// let (addr, stopped_receiver) = executor.block_on(
/// HttpServerBuilder::new()
Expand Down
143 changes: 66 additions & 77 deletions tests/head.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ mod test_util;
use crate::test_util::TestServer;
use fixed_buffer::FixedBuf;
use futures_lite::AsyncWriteExt;
use safina::async_test;
use safina::sync::Receiver;
use safina::timer::sleep_for;
use servlin::internal::{read_http_head, Head, HeadError, HttpError};
use servlin::{AsciiString, Response};
use std::time::Duration;
use test_util::{async_test, connected_streams};
use test_util::connected_streams;

#[test]
fn request_line() {
Expand Down Expand Up @@ -252,92 +253,80 @@ async fn read_http_head_task() -> (async_net::TcpStream, Receiver<Result<Head, H
(stream1, receiver)
}

#[test]
fn read_http_head_ok() {
async_test(async {
let (mut stream, mut receiver) = read_http_head_task().await;
stream.write_all(b"M / HTTP/1.1\r\n\r\n").await.unwrap();
let head = receiver.async_recv().await.unwrap().unwrap();
assert_eq!("M", head.method);
assert_eq!("/", head.url.path());
assert!(head.headers.is_empty());
});
#[async_test]
async fn read_http_head_ok() {
let (mut stream, mut receiver) = read_http_head_task().await;
stream.write_all(b"M / HTTP/1.1\r\n\r\n").await.unwrap();
let head = receiver.async_recv().await.unwrap().unwrap();
assert_eq!("M", head.method);
assert_eq!("/", head.url.path());
assert!(head.headers.is_empty());
}

#[test]
fn read_http_head_error() {
async_test(async {
let (mut stream, mut receiver) = read_http_head_task().await;
stream.write_all(b"M / BADPROTO\r\n\r\n").await.unwrap();
assert_eq!(
Err(HttpError::UnsupportedProtocol),
receiver.async_recv().await.unwrap()
);
});
#[async_test]
async fn read_http_head_error() {
let (mut stream, mut receiver) = read_http_head_task().await;
stream.write_all(b"M / BADPROTO\r\n\r\n").await.unwrap();
assert_eq!(
Err(HttpError::UnsupportedProtocol),
receiver.async_recv().await.unwrap()
);
}

#[test]
fn read_http_head_too_long() {
async_test(async {
let (mut stream, mut receiver) = read_http_head_task().await;
stream.write_all(&[b'a'; 10_000]).await.unwrap();
assert_eq!(
Err(HttpError::HeadTooLong),
receiver.async_recv().await.unwrap()
);
});
#[async_test]
async fn read_http_head_too_long() {
let (mut stream, mut receiver) = read_http_head_task().await;
stream.write_all(&[b'a'; 10_000]).await.unwrap();
assert_eq!(
Err(HttpError::HeadTooLong),
receiver.async_recv().await.unwrap()
);
}

#[test]
fn read_http_head_truncated() {
async_test(async {
let (mut stream, mut receiver) = read_http_head_task().await;
stream.write_all(b"M / HTTP/1.1\r\n\r").await.unwrap();
drop(stream);
assert_eq!(
Err(HttpError::Truncated),
receiver.async_recv().await.unwrap()
);
});
#[async_test]
async fn read_http_head_truncated() {
let (mut stream, mut receiver) = read_http_head_task().await;
stream.write_all(b"M / HTTP/1.1\r\n\r").await.unwrap();
drop(stream);
assert_eq!(
Err(HttpError::Truncated),
receiver.async_recv().await.unwrap()
);
}

#[test]
fn read_http_head_multiple_writes() {
async_test(async {
let (mut stream, mut receiver) = read_http_head_task().await;
stream.write_all(b"M / HTTP/1.1\r\n").await.unwrap();
stream.flush().await.unwrap();
sleep_for(Duration::from_millis(100)).await;
stream.write_all(b"\r\n").await.unwrap();
stream.flush().await.unwrap();
let head = receiver.async_recv().await.unwrap().unwrap();
assert_eq!("M", head.method);
assert_eq!("/", head.url.path());
assert!(head.headers.is_empty());
});
#[async_test]
async fn read_http_head_multiple_writes() {
let (mut stream, mut receiver) = read_http_head_task().await;
stream.write_all(b"M / HTTP/1.1\r\n").await.unwrap();
stream.flush().await.unwrap();
sleep_for(Duration::from_millis(100)).await;
stream.write_all(b"\r\n").await.unwrap();
stream.flush().await.unwrap();
let head = receiver.async_recv().await.unwrap().unwrap();
assert_eq!("M", head.method);
assert_eq!("/", head.url.path());
assert!(head.headers.is_empty());
}

#[test]
fn read_http_head_subsequent() {
async_test(async {
let (mut stream, mut receiver) = read_http_head_task().await;
stream.write_all(b"M /1 HTTP/1.1\r\n\r\n").await.unwrap();
assert_eq!(
"/1",
receiver.async_recv().await.unwrap().unwrap().url.path()
);
stream.write_all(b"M /2 HTTP/1.1\r\n\r\n").await.unwrap();
assert_eq!(
"/2",
receiver.async_recv().await.unwrap().unwrap().url.path()
);
drop(stream);
assert_eq!(
Err(HttpError::Disconnected),
receiver.async_recv().await.unwrap()
);
receiver.async_recv().await.unwrap_err();
});
#[async_test]
async fn read_http_head_subsequent() {
let (mut stream, mut receiver) = read_http_head_task().await;
stream.write_all(b"M /1 HTTP/1.1\r\n\r\n").await.unwrap();
assert_eq!(
"/1",
receiver.async_recv().await.unwrap().unwrap().url.path()
);
stream.write_all(b"M /2 HTTP/1.1\r\n\r\n").await.unwrap();
assert_eq!(
"/2",
receiver.async_recv().await.unwrap().unwrap().url.path()
);
drop(stream);
assert_eq!(
Err(HttpError::Disconnected),
receiver.async_recv().await.unwrap()
);
receiver.async_recv().await.unwrap_err();
}

#[test]
Expand Down
Loading

0 comments on commit e134152

Please sign in to comment.