rust/hedgewars-server/src/protocol.rs
author unc0rr
Wed, 30 Jun 2021 00:18:53 +0200
changeset 15810 ee84e417d8d0
parent 15804 747278149393
child 15831 7d0f747afcb8
permissions -rw-r--r--
Add parser and idempotention tests for server messages
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
15804
747278149393 Extract network protocol into a separate crate
unc0rr
parents: 15795
diff changeset
     1
use hedgewars_network_protocol::{
747278149393 Extract network protocol into a separate crate
unc0rr
parents: 15795
diff changeset
     2
    messages::HwProtocolMessage,
747278149393 Extract network protocol into a separate crate
unc0rr
parents: 15795
diff changeset
     3
    parser::{malformed_message, message},
747278149393 Extract network protocol into a separate crate
unc0rr
parents: 15795
diff changeset
     4
};
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
     5
use log::*;
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
     6
use netbuf;
14457
98ef2913ec73 Apply rustfmt to all files
unc0rr
parents: 14415
diff changeset
     7
use std::io::{Read, Result};
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
     8
12136
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
     9
pub struct ProtocolDecoder {
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    10
    buf: netbuf::Buf,
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    11
    is_recovering: bool,
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    12
}
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    13
12136
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    14
impl ProtocolDecoder {
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    15
    pub fn new() -> ProtocolDecoder {
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    16
        ProtocolDecoder {
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    17
            buf: netbuf::Buf::new(),
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    18
            is_recovering: false,
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    19
        }
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    20
    }
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    21
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    22
    fn recover(&mut self) -> bool {
15804
747278149393 Extract network protocol into a separate crate
unc0rr
parents: 15795
diff changeset
    23
        self.is_recovering = match malformed_message(&self.buf[..]) {
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    24
            Ok((tail, ())) => {
15439
a158ff8f84ef refactor the lobby handler
alfadur
parents: 15123
diff changeset
    25
                let length = tail.len();
a158ff8f84ef refactor the lobby handler
alfadur
parents: 15123
diff changeset
    26
                self.buf.consume(self.buf.len() - length);
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    27
                false
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    28
            }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    29
            _ => {
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    30
                self.buf.consume(self.buf.len());
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    31
                true
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    32
            }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    33
        };
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    34
        !self.is_recovering
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    35
    }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    36
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    37
    pub fn read_from<R: Read>(&mut self, stream: &mut R) -> Result<usize> {
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    38
        let count = self.buf.read_from(stream)?;
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    39
        if count > 0 && self.is_recovering {
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    40
            self.recover();
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    41
        }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    42
        Ok(count)
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    43
    }
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    44
15804
747278149393 Extract network protocol into a separate crate
unc0rr
parents: 15795
diff changeset
    45
    pub fn extract_messages(&mut self) -> Vec<HwProtocolMessage> {
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    46
        let mut messages = vec![];
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    47
        if !self.is_recovering {
15123
1aa3b44c0441 fix parser getting stuck
alfadur
parents: 15114
diff changeset
    48
            while !self.buf.is_empty() {
15804
747278149393 Extract network protocol into a separate crate
unc0rr
parents: 15795
diff changeset
    49
                match message(&self.buf[..]) {
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    50
                    Ok((tail, message)) => {
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    51
                        messages.push(message);
15439
a158ff8f84ef refactor the lobby handler
alfadur
parents: 15123
diff changeset
    52
                        let length = tail.len();
a158ff8f84ef refactor the lobby handler
alfadur
parents: 15123
diff changeset
    53
                        self.buf.consume(self.buf.len() - length);
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    54
                    }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    55
                    Err(nom::Err::Incomplete(_)) => break,
15795
40929af15167 find excuses to use shiny new 🦀 features
alfadur
parents: 15439
diff changeset
    56
                    Err(nom::Err::Failure(e) | nom::Err::Error(e)) => {
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    57
                        debug!("Invalid message: {:?}", e);
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    58
                        if !self.recover() || self.buf.is_empty() {
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    59
                            break;
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    60
                        }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    61
                    }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    62
                }
14457
98ef2913ec73 Apply rustfmt to all files
unc0rr
parents: 14415
diff changeset
    63
            }
12136
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    64
        }
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    65
        messages
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    66
    }
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    67
}