Skip to main content

dap/
server.rs

1use std::{
2    fmt::Debug,
3    io::{BufRead, BufReader, BufWriter, Read, Write},
4    sync::{Arc, Mutex},
5};
6
7use serde_json;
8
9use crate::{
10    base_message::{BaseMessage, Sendable},
11    errors::{DeserializationError, ServerError},
12    events::Event,
13    requests::Request,
14    responses::Response,
15    reverse_requests::ReverseRequest,
16};
17
18#[derive(Debug)]
19enum ServerState {
20    /// Expecting a header
21    Header,
22    /// Expecting content
23    Content,
24}
25
26/// Handles message encoding and decoding of messages.
27///
28/// The `Server` is responsible for reading the incoming bytestream and constructing deserialized
29/// requests from it, as well as constructing and serializing outgoing messages.
30pub struct Server<R: Read, W: Write> {
31    input_buffer: BufReader<R>,
32
33    /// A sharable `ServerOutput` object for sending messages and events from
34    /// other threads.
35    pub output: Arc<Mutex<ServerOutput<W>>>,
36}
37
38/// Handles emission of messages through the connection.
39///
40/// `ServerOutput` is responsible for sending messages to the connection.
41/// It's only accessible through a mutex that can be shared with other
42/// threads. This makes it possible to send e.g. events while the server is
43/// blocked polling requests.
44pub struct ServerOutput<W: Write> {
45    output_buffer: BufWriter<W>,
46    sequence_number: i64,
47}
48
49impl<R: Read, W: Write> Server<R, W> {
50    /// Construct a new Server using the given input and output streams.
51    pub fn new(input: BufReader<R>, output: BufWriter<W>) -> Self {
52        let server_output = Arc::new(Mutex::new(ServerOutput {
53            output_buffer: output,
54            sequence_number: 0,
55        }));
56
57        Self {
58            input_buffer: input,
59            output: server_output,
60        }
61    }
62
63    /// Wait for a request from the development tool
64    ///
65    /// This will start reading the `input` buffer that is passed to it and will try to interpret
66    /// the incoming bytes according to the DAP protocol.
67    pub fn poll_request(&mut self) -> Result<Option<Request>, ServerError> {
68        let mut state = ServerState::Header;
69        let mut buffer = String::new();
70        let mut content_length: usize = 0;
71
72        loop {
73            match self.input_buffer.read_line(&mut buffer) {
74                Ok(read_size) => {
75                    if read_size == 0 {
76                        break Ok(None);
77                    }
78                    match state {
79                        ServerState::Header => {
80                            let parts: Vec<&str> = buffer.trim_end().split(':').collect();
81                            if parts.len() == 2 {
82                                match parts[0] {
83                                    "Content-Length" => {
84                                        content_length = match parts[1].trim().parse() {
85                                            Ok(val) => val,
86                                            Err(_) => {
87                                                return Err(ServerError::HeaderParseError {
88                                                    line: buffer,
89                                                });
90                                            }
91                                        };
92                                        buffer.clear();
93                                        buffer.reserve(content_length);
94                                        state = ServerState::Content;
95                                    }
96                                    other => {
97                                        return Err(ServerError::UnknownHeader {
98                                            header: other.to_string(),
99                                        });
100                                    }
101                                }
102                            } else {
103                                return Err(ServerError::HeaderParseError { line: buffer });
104                            }
105                        }
106                        ServerState::Content => {
107                            buffer.clear();
108                            let mut content = vec![0; content_length];
109                            self.input_buffer
110                                .read_exact(content.as_mut_slice())
111                                .map_err(ServerError::IoError)?;
112
113                            let content = std::str::from_utf8(content.as_slice()).map_err(|e| {
114                                ServerError::ParseError(DeserializationError::DecodingError(e))
115                            })?;
116                            eprintln!(
117                                "[DAP-RS] Received content ({content_length} bytes): {content}"
118                            );
119                            // Deserialize seq and command separately to avoid serde
120                            // #[serde(flatten)] issues with newer serde versions (>=1.0.171)
121                            // where flatten + adjacently-tagged enums can fail.
122                            let raw: serde_json::Value =
123                                serde_json::from_str(content).map_err(|e| {
124                                    eprintln!("[DAP-RS] JSON parse error: {e}");
125                                    ServerError::ParseError(DeserializationError::SerdeError(e))
126                                })?;
127                            let seq = raw.get("seq").and_then(|v| v.as_i64()).ok_or_else(|| {
128                                eprintln!("[DAP-RS] Missing seq field");
129                                ServerError::ParseError(DeserializationError::SerdeError(
130                                    serde_json::from_str::<()>("\"missing seq field\"")
131                                        .unwrap_err(),
132                                ))
133                            })?;
134                            // Handle the conflict between unit variants (e.g. ConfigurationDone)
135                            // and struct variants with all-optional fields (e.g. Launch):
136                            // - Unit variants fail with "arguments": {} ("invalid type: map, expected unit variant")
137                            // - Struct variants fail without "arguments" ("missing field `arguments`")
138                            // When arguments is an empty object, try without it first (unit variant),
139                            // then fall back to keeping it (struct variant with optional fields).
140                            let command: crate::requests::Command = if raw
141                                .get("arguments")
142                                .and_then(|v| v.as_object())
143                                .is_some_and(|m| m.is_empty())
144                            {
145                                let mut without_args = raw.clone();
146                                without_args.as_object_mut().unwrap().remove("arguments");
147                                match serde_json::from_value::<crate::requests::Command>(
148                                    without_args,
149                                ) {
150                                    Ok(cmd) => cmd,
151                                    Err(_) => serde_json::from_value(raw.clone()).map_err(|e| {
152                                        eprintln!("[DAP-RS] Command deserialize error: {e}");
153                                        ServerError::ParseError(DeserializationError::SerdeError(e))
154                                    })?,
155                                }
156                            } else {
157                                serde_json::from_value(raw.clone()).map_err(|e| {
158                                    eprintln!("[DAP-RS] Command deserialize error: {e}");
159                                    ServerError::ParseError(DeserializationError::SerdeError(e))
160                                })?
161                            };
162                            eprintln!("[DAP-RS] Successfully parsed request seq={seq}");
163                            let request = Request { seq, command };
164                            return Ok(Some(request));
165                        }
166                    }
167                }
168                Err(e) => return Err(ServerError::IoError(e)),
169            }
170        }
171    }
172
173    pub fn send(&mut self, body: Sendable) -> Result<(), ServerError> {
174        let mut output = self.output.lock().map_err(|_| ServerError::OutputLockError)?;
175        output.send(body)
176    }
177
178    pub fn respond(&mut self, response: Response) -> Result<(), ServerError> {
179        self.send(Sendable::Response(response))
180    }
181
182    pub fn send_event(&mut self, event: Event) -> Result<(), ServerError> {
183        self.send(Sendable::Event(event))
184    }
185
186    pub fn send_reverse_request(&mut self, request: ReverseRequest) -> Result<(), ServerError> {
187        self.send(Sendable::ReverseRequest(request))
188    }
189}
190
191impl<W: Write> ServerOutput<W> {
192    pub fn send(&mut self, body: Sendable) -> Result<(), ServerError> {
193        self.sequence_number += 1;
194
195        let message = BaseMessage {
196            seq: self.sequence_number,
197            message: body,
198        };
199
200        let resp_json = serde_json::to_string(&message).map_err(ServerError::SerializationError)?;
201        write!(self.output_buffer, "Content-Length: {}\r\n\r\n", resp_json.len())
202            .map_err(ServerError::IoError)?;
203
204        write!(self.output_buffer, "{}\r\n", resp_json).map_err(ServerError::IoError)?;
205        self.output_buffer.flush().map_err(ServerError::IoError)?;
206        Ok(())
207    }
208
209    pub fn respond(&mut self, response: Response) -> Result<(), ServerError> {
210        self.send(Sendable::Response(response))
211    }
212
213    pub fn send_event(&mut self, event: Event) -> Result<(), ServerError> {
214        self.send(Sendable::Event(event))
215    }
216
217    pub fn send_reverse_request(&mut self, request: ReverseRequest) -> Result<(), ServerError> {
218        self.send(Sendable::ReverseRequest(request))
219    }
220}
221
222#[cfg(test)]
223mod tests {
224
225    use std::io::Cursor;
226
227    use serde_json::Value;
228
229    use super::*;
230    use crate::requests::{AttachOrLaunchArguments, Command, RestartArguments};
231
232    fn simulate_poll_request(input: &str) -> Request {
233        let mut server_in = Cursor::new(input.as_bytes().to_vec());
234        let server_out = Vec::new();
235        let mut server = Server::new(BufReader::new(&mut server_in), BufWriter::new(server_out));
236
237        server.poll_request().unwrap().unwrap()
238    }
239
240    #[test]
241    fn test_server_init_request() {
242        let req = simulate_poll_request(
243            "Content-Length: 155\r\n\r\n{\"seq\": 152,\"type\": \"request\",\"command\": \
244             \"initialize\",\"arguments\": {\"adapterID\": \
245             \"0001e357-72c7-4f03-ae8f-c5b54bd8dabf\", \"clientName\": \"Some Cool Editor\"}}",
246        );
247
248        assert_eq!(req.seq, 152);
249        assert!(matches!(req.command, Command::Initialize { .. }));
250    }
251
252    #[test]
253    fn test_server_restart_request() {
254        let req = simulate_poll_request(
255            "Content-Length: 67\r\n\r\n{\"seq\": 152,\"type\": \"request\",\"command\": \
256             \"restart\",\"arguments\": {}}",
257        );
258
259        assert!(matches!(
260            req.command,
261            Command::Restart {
262                0: RestartArguments { arguments: None }
263            }
264        ));
265
266        // Restarting a launch request
267        let req = simulate_poll_request(
268            "Content-Length: 96\r\n\r\n{\"seq\": 152,\"type\": \"request\",\"command\": \
269             \"restart\",\"arguments\": {\"arguments\": {\"noDebug\":true}}}",
270        );
271        assert!(matches!(
272            req.command,
273            Command::Restart {
274                0: RestartArguments {
275                    arguments: Some(AttachOrLaunchArguments {
276                        no_debug: Some(_),
277                        ..
278                    })
279                }
280            }
281        ));
282
283        // Restarting a launch or attach request
284        let req = simulate_poll_request(
285            "Content-Length: 98\r\n\r\n{\"seq\": 152,\"type\": \"request\",\"command\": \
286             \"restart\",\"arguments\": {\"arguments\": {\"__restart\":true}}}",
287        );
288        assert!(matches!(
289            req.command,
290            Command::Restart {
291                0: RestartArguments {
292                    arguments: Some(AttachOrLaunchArguments {
293                        restart_data: Some(Value::Bool(true)),
294                        ..
295                    })
296                }
297            }
298        ));
299    }
300}