on master help sign in
Port over parsing improvements from the LSP
ea59f77Blaž Hrastnik
helix-dap/src/transport.rs+19−14
@@ -82,26 +82,29 @@ impl Transport {
82 let mut content_length = None;
82 let mut content_length = None;
83 loop {
83 loop {
84 buffer.truncate(0);
84 buffer.truncate(0);
85− reader.read_line(buffer).await?;
85+ if reader.read_line(buffer).await? == 0 {
86− let header = buffer.trim();
86+ return Err(Error::StreamClosed);
87+ };
87
88
88− if header.is_empty() {
89+ if buffer == "\r\n" {
90+ // look for an empty CRLF line
89 break;
91 break;
90 }
92 }
91
93
94+ let header = buffer.trim();
92− let mut parts = header.split(": ");
95+ let parts = header.split_once(": ");
93
96
94− match (parts.next(), parts.next(), parts.next()) {
97+ match parts {
95− (Some("Content-Length"), Some(value), None) => {
98+ Some(("Content-Length", value)) => {
96 content_length = Some(value.parse().context("invalid content length")?);
99 content_length = Some(value.parse().context("invalid content length")?);
97 }
100 }
101+ Some((_, _)) => {}
98− (Some(_), Some(_), None) => {}
102+ None => {
99− _ => {
103+ // Workaround: Some non-conformant language servers will output logging and other garbage
100− return Err(std::io::Error::new(
104+ // into the same stream as JSON-RPC messages. This can also happen from shell scripts that spawn
101− std::io::ErrorKind::Other,
105+ // the server. Skip such lines and log a warning.
106+
102− "Failed to parse header",
107+ // warn!("Failed to parse header: {:?}", header);
103− )
104− .into());
105 }
108 }
106 }
109 }
107 }
110 }
@@ -126,7 +129,9 @@ impl Transport {
126 buffer: &mut String,
129 buffer: &mut String,
127 ) -> Result<()> {
130 ) -> Result<()> {
128 buffer.truncate(0);
131 buffer.truncate(0);
129− err.read_line(buffer).await?;
132+ if err.read_line(buffer).await? == 0 {
133+ return Err(Error::StreamClosed);
134+ };
130 error!("err <- {}", buffer);
135 error!("err <- {}", buffer);
131
136
132 Ok(())
137 Ok(())