diff --git a/src/client/response/header.rs b/src/client/response/header.rs index a415d80..969696d 100644 --- a/src/client/response/header.rs +++ b/src/client/response/header.rs @@ -53,13 +53,13 @@ impl Header { match Status::from_header(&buffer) { Ok(status) => Ok(Self { status, - meta: match Meta::from_header(&buffer) { + meta: match Meta::from(&buffer) { Ok(meta) => Some(meta), - Err(_) => None, + Err(_) => None, // @TODO handle }, mime: match Mime::from_header(&buffer) { Ok(mime) => Some(mime), - Err(_) => None, + Err(_) => None, // @TODO handle }, }), Err(reason) => Err(( diff --git a/src/client/response/header/meta.rs b/src/client/response/header/meta.rs index 4cded7d..c82f61e 100644 --- a/src/client/response/header/meta.rs +++ b/src/client/response/header/meta.rs @@ -9,27 +9,50 @@ use glib::GString; /// * placeholder for 10, 11 status /// * URL for 30, 31 status pub struct Meta { - buffer: Vec, + value: Option, } impl Meta { - pub fn from_header(buffer: &[u8]) -> Result { + /// Parse Meta from UTF-8 + pub fn from(buffer: &[u8]) -> Result { + // Init bytes buffer + let mut bytes: Vec = Vec::new(); + + // Skip status code match buffer.get(3..) { - Some(value) => Ok(Self { - buffer: value.to_vec(), - }), - None => return Err(Error::Protocol), // @TODO optional + Some(slice) => { + for (count, &byte) in slice.iter().enumerate() { + // Validate length + if count > 0x400 { + // 1024 + return Err(Error::Protocol); + } + + // End of line, done + if byte == b'\r' { + break; + } + + // Append + bytes.push(byte); + } + + // Assumes the bytes are valid UTF-8 + match GString::from_utf8(bytes) { + Ok(value) => Ok(Self { + value: match value.is_empty() { + true => None, + false => Some(value), + }, + }), + Err(_) => Err(Error::Decode), + } + } + None => Err(Error::Protocol), } } - pub fn to_gstring(&self) -> Result { - match GString::from_utf8(self.buffer.clone()) { - Ok(result) => Ok(result), - Err(_) => Err(Error::Decode), - } - } - - pub fn buffer(&self) -> &[u8] { - &self.buffer + pub fn value(&self) -> &Option { + &self.value } }