MCPcopy Create free account
hub / github.com/ScriptedAlchemy/tracedecay / read_message_until

Function read_message_until

src/diagnostics/lsp/client.rs:427–490  ·  view source on GitHub ↗
(
    reader: &mut BufReader<tokio::process::ChildStdout>,
    deadline: tokio::time::Instant,
    timeouts: LspRefreshTimeouts,
)

Source from the content-addressed store, hash-verified

425}
426
427async fn read_message_until(
428 reader: &mut BufReader<tokio::process::ChildStdout>,
429 deadline: tokio::time::Instant,
430 timeouts: LspRefreshTimeouts,
431) -> Result<Option<JsonRpcMessage>> {
432 let mut header = Vec::new();
433 while !header.ends_with(b"\r\n\r\n") && !header.ends_with(b"\n\n") {
434 let Some(byte) = read_byte_until(reader, deadline, !header.is_empty(), timeouts).await?
435 else {
436 return Ok(None);
437 };
438 header.push(byte);
439 if header.len() > 16 * 1024 {
440 return Err(TraceDecayError::Config {
441 message: "LSP message header exceeded 16 KiB".to_string(),
442 });
443 }
444 }
445
446 let header = String::from_utf8_lossy(&header);
447 let content_length = header.lines().find_map(|line| {
448 let (name, value) = line.split_once(':')?;
449 name.eq_ignore_ascii_case("content-length")
450 .then(|| value.trim().parse::<usize>().ok())
451 .flatten()
452 });
453 let Some(length) = content_length else {
454 return Err(TraceDecayError::Config {
455 message: "LSP message missing Content-Length header".to_string(),
456 });
457 };
458
459 let mut body = vec![0_u8; length];
460 let mut read = 0;
461 while read < length {
462 let now = tokio::time::Instant::now();
463 if now >= deadline {
464 return Err(refresh_timed_out(timeouts));
465 }
466 let remaining = deadline.saturating_duration_since(now);
467 let bytes_read = match tokio::time::timeout(remaining, reader.read(&mut body[read..])).await
468 {
469 Ok(Ok(bytes_read)) => bytes_read,
470 Ok(Err(err)) => {
471 return Err(TraceDecayError::Config {
472 message: format!("failed to read LSP body: {err}"),
473 });
474 }
475 Err(_) => return Err(refresh_timed_out(timeouts)),
476 };
477 if bytes_read == 0 {
478 return Err(TraceDecayError::Config {
479 message: "LSP server closed before completing message body".to_string(),
480 });
481 }
482 read += bytes_read;
483 }
484

Callers 1

Calls 5

read_byte_untilFunction · 0.85
refresh_timed_outFunction · 0.85
pushMethod · 0.80
is_emptyMethod · 0.45
readMethod · 0.45

Tested by

no test coverage detected