@@ -82,26 +82,29 @@ impl Transport {
8282 let mut content_length = None;
8383 loop {
8484 buffer.truncate(0);
85− reader.read_line(buffer).await?;
86− let header = buffer.trim();
85+ if reader.read_line(buffer).await? == 0 {
86+ return Err(Error::StreamClosed);
87+ };
8788
88− if header.is_empty() {
89+ if buffer == "\r\n" {
90+ // look for an empty CRLF line
8991 break;
9092 }
9193
92− let mut parts = header.split(": ");
94+ let header = buffer.trim();
95+ let parts = header.split_once(": ");
9396
94− match (parts.next(), parts.next(), parts.next()) {
95− (Some("Content-Length"), Some(value), None) => {
97+ match parts {
98+ Some(("Content-Length", value)) => {
9699 content_length = Some(value.parse().context("invalid content length")?);
97100 }
98− (Some(_), Some(_), None) => {}
99− _ => {
100− return Err(std::io::Error::new(
101− std::io::ErrorKind::Other,
102− "Failed to parse header",
103− )
104− .into());
101+ Some((_, _)) => {}
102+ None => {
103+ // Workaround: Some non-conformant language servers will output logging and other garbage
104+ // into the same stream as JSON-RPC messages. This can also happen from shell scripts that spawn
105+ // the server. Skip such lines and log a warning.
106+
107+ // warn!("Failed to parse header: {:?}", header);
105108 }
106109 }
107110 }
@@ -126,7 +129,9 @@ impl Transport {
126129 buffer: &mut String,
127130 ) -> Result<()> {
128131 buffer.truncate(0);
129− err.read_line(buffer).await?;
132+ if err.read_line(buffer).await? == 0 {
133+ return Err(Error::StreamClosed);
134+ };
130135 error!("err <- {}", buffer);
131136
132137 Ok(())