use super::*;
use tokio::io::{AsyncWriteExt, BufReader};
#[tokio::test]
async fn test20079_messages_are_read_whole_or_refused() {
let (mut tx, rx) = tokio::io::duplex(64);
let mut reader = BufReader::new(rx);
let one = serde_json::json!({ "jsonrpc": "2.0", "id": 1, "result": { "text": "é😀" } });
let body = serde_json::to_vec(&one).unwrap();
tokio::spawn(async move {
let framed = [format!("Content-Type: application/vscode-jsonrpc\r\nContent-Length: {}\r\n\r\n", body.len()).into_bytes(), body].concat();
for chunk in framed.chunks(7) {
tx.write_all(chunk).await.unwrap();
tx.flush().await.unwrap();
}
write(&mut tx, &serde_json::json!({ "jsonrpc": "2.0", "method": "x" })).await.unwrap();
});
assert_eq!(read(&mut reader).await.unwrap(), Some(one));
assert_eq!(read(&mut reader).await.unwrap(), Some(serde_json::json!({ "jsonrpc": "2.0", "method": "x" })));
assert!(read(&mut reader).await.unwrap().is_none(), "the end between messages is the end");
let refused = |bytes: &'static [u8]| async move { read(&mut BufReader::new(bytes)).await };
assert!(matches!(refused(b"Content-Type: x\r\n\r\n{}").await, Err(FramingError::NoLength)));
assert!(matches!(refused(b"Content-Length: 10\r\n\r\n{}").await, Err(FramingError::Truncated)));
assert!(matches!(refused(b"Content-Length: 2\r\n").await, Err(FramingError::Truncated)));
assert!(matches!(refused(b"Content-Length: x\r\n\r\n").await, Err(FramingError::Header(_))));
assert!(matches!(refused(b"Content-Length: 99999999999\r\n\r\n").await, Err(FramingError::TooLarge(_))));
assert!(matches!(refused(b"Content-Length: 2\r\n\r\n{]").await, Err(FramingError::Json(_))));
}