1
0
mirror of https://github.com/actix/actix-website synced 2025-02-02 12:19:04 +01:00
actix-website/examples/testing/src/stream_response.rs

91 lines
2.7 KiB
Rust
Raw Normal View History

2019-06-17 15:39:58 -04:00
// <stream-response>
2020-11-27 01:10:05 +00:00
use std::task::Poll;
2019-06-17 15:39:58 -04:00
2022-02-26 03:56:24 +00:00
use actix_web::{
http::{self, header::ContentEncoding, StatusCode},
web, App, Error, HttpRequest, HttpResponse,
};
use futures::stream;
2019-06-17 15:39:58 -04:00
async fn sse(_req: HttpRequest) -> HttpResponse {
2019-06-24 17:43:31 -04:00
let mut counter: usize = 5;
2019-06-17 15:39:58 -04:00
2019-06-24 17:43:31 -04:00
// yields `data: N` where N in [5; 1]
2022-02-26 03:56:24 +00:00
let server_events =
stream::poll_fn(move |_cx| -> Poll<Option<Result<web::Bytes, Error>>> {
if counter == 0 {
return Poll::Ready(None);
}
let payload = format!("data: {}\n\n", counter);
counter -= 1;
Poll::Ready(Some(Ok(web::Bytes::from(payload))))
});
2019-06-17 15:39:58 -04:00
2019-06-24 17:43:31 -04:00
HttpResponse::build(StatusCode::OK)
2022-02-26 03:56:24 +00:00
.insert_header((http::header::CONTENT_TYPE, "text/event-stream"))
.insert_header(ContentEncoding::Identity)
2019-06-24 17:43:31 -04:00
.streaming(server_events)
}
2019-06-17 15:39:58 -04:00
2019-06-24 17:43:31 -04:00
pub fn main() {
App::new().route("/", web::get().to(sse));
}
2019-06-17 15:39:58 -04:00
2019-06-24 17:43:31 -04:00
#[cfg(test)]
mod tests {
use super::*;
use actix_web::{body, body::MessageBody as _, rt::pin, test, web, App};
2022-02-26 03:56:24 +00:00
use futures::future;
2022-02-26 03:56:24 +00:00
#[actix_web::test]
async fn test_stream_chunk() {
2022-02-26 03:56:24 +00:00
let app = test::init_service(App::new().route("/", web::get().to(sse))).await;
2019-06-24 17:43:31 -04:00
let req = test::TestRequest::get().to_request();
2022-02-26 03:56:24 +00:00
let resp = test::call_service(&app, req).await;
assert!(resp.status().is_success());
2022-02-26 03:56:24 +00:00
let body = resp.into_body();
pin!(body);
// first chunk
2022-02-26 03:56:24 +00:00
let bytes = future::poll_fn(|cx| body.as_mut().poll_next(cx)).await;
2020-11-27 01:10:05 +00:00
assert_eq!(
bytes.unwrap().unwrap(),
web::Bytes::from_static(b"data: 5\n\n")
);
// second chunk
2022-02-26 03:56:24 +00:00
let bytes = future::poll_fn(|cx| body.as_mut().poll_next(cx)).await;
2020-11-27 01:10:05 +00:00
assert_eq!(
bytes.unwrap().unwrap(),
web::Bytes::from_static(b"data: 4\n\n")
);
// remaining part
for i in 0..3 {
let expected_data = format!("data: {}\n\n", 3 - i);
let bytes = future::poll_fn(|cx| body.as_mut().poll_next(cx)).await;
assert_eq!(bytes.unwrap().unwrap(), web::Bytes::from(expected_data));
}
}
#[actix_web::test]
async fn test_stream_full_payload() {
let app = test::init_service(App::new().route("/", web::get().to(sse))).await;
let req = test::TestRequest::get().to_request();
let resp = test::call_service(&app, req).await;
assert!(resp.status().is_success());
let body = resp.into_body();
let bytes = body::to_bytes(body).await;
assert_eq!(
bytes.unwrap(),
web::Bytes::from_static(b"data: 5\n\ndata: 4\n\ndata: 3\n\ndata: 2\n\ndata: 1\n\n")
);
2019-06-24 17:43:31 -04:00
}
}
2019-06-17 15:39:58 -04:00
// </stream-response>