Introduced ClientProtocolError
This commit is contained in:
@ -17,6 +17,7 @@ pub enum Kind {
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum Class {
|
||||
ClientProtocolError,
|
||||
ClientError,
|
||||
ServerError,
|
||||
}
|
||||
@ -110,7 +111,7 @@ impl From<std::io::Error> for Error {
|
||||
kind: Kind::IoError,
|
||||
msg: Some(error.to_string()),
|
||||
desc: Some(error.to_string()),
|
||||
class: Class::ClientError,
|
||||
class: Class::ClientProtocolError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,7 +122,7 @@ impl From<serde_json::Error> for Error {
|
||||
kind: Kind::JsonParseError,
|
||||
msg: Some("Unable to parse JSON data".to_string()),
|
||||
desc: Some(error.to_string()),
|
||||
class: Class::ClientError,
|
||||
class: Class::ClientProtocolError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -156,7 +157,7 @@ impl From<std::string::FromUtf8Error> for Error {
|
||||
kind: Kind::Utf8DecodeError,
|
||||
msg: Some("Unable to decode UTF-8 data".to_string()),
|
||||
desc: Some(error.to_string()),
|
||||
class: Class::ClientError,
|
||||
class: Class::ClientProtocolError,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,10 +75,10 @@ fn request_handler(client: &mut super::HttpStream) {
|
||||
_ => {
|
||||
res.status(405);
|
||||
res.header.add_field("Allow", "POST");
|
||||
error = Some(Error::new(Kind::UsimpProtocolError, Class::ClientError))
|
||||
error = Some(Error::new(Kind::UsimpProtocolError, Class::ClientProtocolError))
|
||||
}
|
||||
},
|
||||
_ => error = Some(Error::new(Kind::InvalidEndpointError, Class::ClientError)),
|
||||
_ => error = Some(Error::new(Kind::InvalidEndpointError, Class::ClientProtocolError)),
|
||||
}
|
||||
|
||||
if let Some(error) = error {
|
||||
@ -112,10 +112,15 @@ fn request_handler(client: &mut super::HttpStream) {
|
||||
pub fn error_handler(client: &mut super::HttpStream, mut res: super::Response, error: Error) {
|
||||
println!("{}", error.to_string());
|
||||
match &error.class() {
|
||||
Class::ClientError => {
|
||||
Class::ClientProtocolError => {
|
||||
if res.status.code < 400 || res.status.code >= 499 {
|
||||
res.status(400)
|
||||
}
|
||||
},
|
||||
Class::ClientError => {
|
||||
if res.status.code < 200 || res.status.code >= 299 {
|
||||
res.status(200)
|
||||
}
|
||||
}
|
||||
Class::ServerError => {
|
||||
if res.status.code < 500 || res.status.code > 599 {
|
||||
@ -128,6 +133,7 @@ pub fn error_handler(client: &mut super::HttpStream, mut res: super::Response, e
|
||||
let mut obj = serde_json::Value::Object(serde_json::Map::new());
|
||||
obj["status"] = serde_json::Value::String("error".to_string());
|
||||
obj["message"] = serde_json::Value::String(error.to_string());
|
||||
obj["data"] = serde_json::Value::Null;
|
||||
let buf = obj.to_string() + "\r\n";
|
||||
|
||||
let length = buf.as_bytes().len();
|
||||
@ -157,7 +163,7 @@ fn endpoint_handler(
|
||||
return error_handler(
|
||||
client,
|
||||
res,
|
||||
Error::new(Kind::HttpRequestParseError, Class::ClientError)
|
||||
Error::new(Kind::HttpRequestParseError, Class::ClientProtocolError)
|
||||
.set_desc("field 'Content-Length' missing".to_string()),
|
||||
)
|
||||
}
|
||||
@ -169,7 +175,7 @@ fn endpoint_handler(
|
||||
return error_handler(
|
||||
client,
|
||||
res,
|
||||
Error::new(Kind::HttpRequestParseError, Class::ClientError).set_desc(
|
||||
Error::new(Kind::HttpRequestParseError, Class::ClientProtocolError).set_desc(
|
||||
format!("unable to parse field 'Content-Length': {}", &e).to_string(),
|
||||
),
|
||||
)
|
||||
@ -198,7 +204,7 @@ fn endpoint_handler(
|
||||
return error_handler(
|
||||
client,
|
||||
res,
|
||||
Error::new(Kind::UsimpProtocolError, Class::ClientError)
|
||||
Error::new(Kind::UsimpProtocolError, Class::ClientProtocolError)
|
||||
.set_desc("Unable to find field 'From-Domain'".to_string())
|
||||
);
|
||||
}
|
||||
@ -210,7 +216,7 @@ fn endpoint_handler(
|
||||
return error_handler(
|
||||
client,
|
||||
res,
|
||||
Error::new(Kind::UsimpProtocolError, Class::ClientError)
|
||||
Error::new(Kind::UsimpProtocolError, Class::ClientProtocolError)
|
||||
.set_desc("Unable to find field 'To-Domain'".to_string())
|
||||
);
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ pub fn parse_response(stream: &mut http::Stream) -> Result<http::Response, Error
|
||||
let status_code = match status_code.parse::<u16>() {
|
||||
Ok(v) => v,
|
||||
Err(error) => {
|
||||
return Err(Error::new(Kind::HttpRequestParseError, Class::ClientError)
|
||||
return Err(Error::new(Kind::HttpRequestParseError, Class::ClientProtocolError)
|
||||
.set_desc(error.to_string()))
|
||||
}
|
||||
};
|
||||
@ -132,7 +132,7 @@ impl Parser<'_> {
|
||||
match self.state {
|
||||
State::Finish => return Ok(self.header_size),
|
||||
State::Error => {
|
||||
return Err(Error::new(Kind::HttpRequestParseError, Class::ClientError)
|
||||
return Err(Error::new(Kind::HttpRequestParseError, Class::ClientProtocolError)
|
||||
.set_desc(format!(
|
||||
"invalid character at position {}",
|
||||
self.header_size - 1
|
||||
@ -141,7 +141,7 @@ impl Parser<'_> {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
return Err(Error::new(Kind::HttpRequestParseError, Class::ClientError)
|
||||
return Err(Error::new(Kind::HttpRequestParseError, Class::ClientProtocolError)
|
||||
.set_desc("input too short".to_string()));
|
||||
}
|
||||
|
||||
|
@ -16,14 +16,21 @@ pub struct Envelope {
|
||||
|
||||
pub fn endpoint(envelope: Envelope) -> Result<serde_json::Value, Error> {
|
||||
// TODO check authorization
|
||||
// TODO domain_check
|
||||
match envelope.endpoint.as_str() {
|
||||
"echo" => Ok(serde_json::to_value(echo(serde_json::from_value(envelope.data)?)?)?),
|
||||
"authenticate" => Ok(serde_json::to_value(authenticate(serde_json::from_value(envelope.data)?)?)?),
|
||||
"subscribe" => Ok(serde_json::to_value(subscribe(serde_json::from_value(envelope.data)?)?)?),
|
||||
"send_event" => Ok(serde_json::to_value(send_event(serde_json::from_value(envelope.data)?)?)?),
|
||||
_ => return Err(Error::new(Kind::InvalidEndpointError, Class::ClientError)),
|
||||
}
|
||||
// TODO check from/to domain
|
||||
let out = match envelope.endpoint.as_str() {
|
||||
"echo" => serde_json::to_value(echo(serde_json::from_value(envelope.data)?)?)?,
|
||||
"authenticate" => serde_json::to_value(authenticate(serde_json::from_value(envelope.data)?)?)?,
|
||||
"subscribe" => serde_json::to_value(subscribe(serde_json::from_value(envelope.data)?)?)?,
|
||||
"send_event" => serde_json::to_value(send_event(serde_json::from_value(envelope.data)?)?)?,
|
||||
_ => return Err(Error::new(Kind::InvalidEndpointError, Class::ClientProtocolError)),
|
||||
};
|
||||
|
||||
let mut envelope = serde_json::Value::Object(serde_json::Map::new());
|
||||
envelope["status"] = serde_json::Value::String("success".to_string());
|
||||
envelope["message"] = serde_json::Value::Null;
|
||||
envelope["data"] = out;
|
||||
|
||||
Ok(envelope)
|
||||
}
|
||||
|
||||
pub fn get_id(input: &str) -> String {
|
||||
|
@ -15,10 +15,10 @@ pub fn recv_message(client: &mut http::HttpStream) -> Result<Message, Error> {
|
||||
|
||||
// FIXME control frames may show up in a fragmented stream
|
||||
if msg_type != 0 && header.opcode != 0 {
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientError)
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientProtocolError)
|
||||
.set_desc("continuation frame expected".to_string()));
|
||||
} else if header.opcode >= 8 && (!header.fin || header.payload_len >= 126) {
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientError)
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientProtocolError)
|
||||
.set_desc("invalid control frame".to_string()));
|
||||
}
|
||||
|
||||
@ -26,12 +26,12 @@ pub fn recv_message(client: &mut http::HttpStream) -> Result<Message, Error> {
|
||||
0 => {}, // cont
|
||||
1 => {}, // text
|
||||
2 => // binary
|
||||
return Err(Error::new(Kind::UsimpProtocolError, Class::ClientError)
|
||||
return Err(Error::new(Kind::UsimpProtocolError, Class::ClientProtocolError)
|
||||
.set_desc("binary frames must not be sent on a usimp connection".to_string())),
|
||||
8 => {}, // close
|
||||
9 => {}, // ping
|
||||
10 => {}, // pong
|
||||
_ => return Err(Error::new(Kind::WebSocketError, Class::ClientError)
|
||||
_ => return Err(Error::new(Kind::WebSocketError, Class::ClientProtocolError)
|
||||
.set_desc("invalid opcode".to_string())),
|
||||
}
|
||||
|
||||
@ -101,37 +101,37 @@ pub fn handshake(
|
||||
} else {
|
||||
res.status(405);
|
||||
res.header.add_field("Allow", "GET");
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientError)
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientProtocolError)
|
||||
.set_desc("method not allowed".to_string()));
|
||||
}
|
||||
|
||||
if let Some(_) = req.header.find_field("Connection") {
|
||||
if !req.header.field_has_value("Connection", "upgrade") {
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientError)
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientProtocolError)
|
||||
.set_desc("invalid value for header field 'Connection'".to_string()));
|
||||
}
|
||||
} else {
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientError)
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientProtocolError)
|
||||
.set_desc("unable to find header field 'Connection'".to_string()));
|
||||
}
|
||||
|
||||
if let Some(upgrade) = req.header.find_field("Upgrade") {
|
||||
if !upgrade.eq_ignore_ascii_case("websocket") {
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientError)
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientProtocolError)
|
||||
.set_desc("invalid value for header field 'Upgrade'".to_string()));
|
||||
}
|
||||
} else {
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientError)
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientProtocolError)
|
||||
.set_desc("unable to find header field 'Upgrade'".to_string()));
|
||||
}
|
||||
|
||||
if let Some(version) = req.header.find_field("Sec-WebSocket-Version") {
|
||||
if !version.eq("13") {
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientError)
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientProtocolError)
|
||||
.set_desc("invalid value for header field 'Sec-WebSocket-Key'".to_string()));
|
||||
}
|
||||
} else {
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientError)
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientProtocolError)
|
||||
.set_desc("unable to find header field 'Sec-WebSocket-Version'".to_string()));
|
||||
}
|
||||
|
||||
@ -145,7 +145,7 @@ pub fn handshake(
|
||||
let key = base64::encode(result);
|
||||
res.header.add_field("Sec-WebSocket-Accept", key.as_str());
|
||||
} else {
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientError)
|
||||
return Err(Error::new(Kind::WebSocketError, Class::ClientProtocolError)
|
||||
.set_desc("unable to find header field 'Sec-WebSocket-Key'".to_string()));
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user