feat: error type returns `Vec<u8>` instead of `Option<String>`

pull/298/head
Josiah Bull 2 years ago
parent 4a7beaa897
commit 36ab770059
No known key found for this signature in database
GPG Key ID: 10FCCC1BF551A8A8
  1. 2
      examples/callback-error.rs
  2. 2
      src/error.rs
  3. 17
      src/handshake/client.rs
  4. 6
      src/handshake/server.rs

@ -13,7 +13,7 @@ fn main() {
let callback = |_req: &Request, _resp| { let callback = |_req: &Request, _resp| {
let resp = Response::builder() let resp = Response::builder()
.status(StatusCode::FORBIDDEN) .status(StatusCode::FORBIDDEN)
.body(Some("Access denied".into())) .body("Access denied".into())
.unwrap(); .unwrap();
Err(resp) Err(resp)
}; };

@ -65,7 +65,7 @@ pub enum Error {
/// HTTP error. /// HTTP error.
#[error("HTTP error: {}", .0.status())] #[error("HTTP error: {}", .0.status())]
#[cfg(feature = "handshake")] #[cfg(feature = "handshake")]
Http(Response<Option<String>>), Http(Response<Vec<u8>>),
/// HTTP format error. /// HTTP format error.
#[error("HTTP format error: {0}")] #[error("HTTP format error: {0}")]
#[cfg(feature = "handshake")] #[cfg(feature = "handshake")]

@ -26,7 +26,7 @@ use crate::{
pub type Request = HttpRequest<()>; pub type Request = HttpRequest<()>;
/// Client response type. /// Client response type.
pub type Response = HttpResponse<Option<String>>; pub type Response = HttpResponse<Vec<u8>>;
/// Client handshake role. /// Client handshake role.
#[derive(Debug)] #[derive(Debug)]
@ -83,7 +83,15 @@ impl<S: Read + Write> HandshakeRole for ClientHandshake<S> {
ProcessingResult::Continue(HandshakeMachine::start_read(stream)) ProcessingResult::Continue(HandshakeMachine::start_read(stream))
} }
StageResult::DoneReading { stream, result, tail } => { StageResult::DoneReading { stream, result, tail } => {
let result = self.verify_data.verify_response(result, &tail)?; let result = match self.verify_data.verify_response(result) {
Ok(r) => r,
Err(Error::Http(mut e)) => {
*e.body_mut() = tail;
return Err(Error::Http(e))
},
Err(e) => return Err(e),
};
debug!("Client handshake done."); debug!("Client handshake done.");
let websocket = let websocket =
WebSocket::from_partially_read(stream, tail, Role::Client, self.config); WebSocket::from_partially_read(stream, tail, Role::Client, self.config);
@ -178,11 +186,10 @@ struct VerifyData {
} }
impl VerifyData { impl VerifyData {
pub fn verify_response(&self, mut response: Response, tail: &[u8]) -> Result<Response> { pub fn verify_response(&self, response: Response) -> Result<Response> {
// 1. If the status code received from the server is not 101, the // 1. If the status code received from the server is not 101, the
// client handles the response per HTTP [RFC2616] procedures. (RFC 6455) // client handles the response per HTTP [RFC2616] procedures. (RFC 6455)
if response.status() != StatusCode::SWITCHING_PROTOCOLS { if response.status() != StatusCode::SWITCHING_PROTOCOLS {
*response.body_mut() = Some(String::from_utf8_lossy(tail).to_string());
return Err(Error::Http(response)); return Err(Error::Http(response));
} }
@ -256,7 +263,7 @@ impl<'h, 'b: 'h> FromHttparse<httparse::Response<'h, 'b>> for Response {
let headers = HeaderMap::from_httparse(raw.headers)?; let headers = HeaderMap::from_httparse(raw.headers)?;
let mut response = Response::new(None); let mut response = Response::new(vec![]);
*response.status_mut() = StatusCode::from_u16(raw.code.expect("Bug: no HTTP status code"))?; *response.status_mut() = StatusCode::from_u16(raw.code.expect("Bug: no HTTP status code"))?;
*response.headers_mut() = headers; *response.headers_mut() = headers;
// TODO: httparse only supports HTTP 0.9/1.0/1.1 but not HTTP 2.0 // TODO: httparse only supports HTTP 0.9/1.0/1.1 but not HTTP 2.0

@ -30,7 +30,7 @@ pub type Request = HttpRequest<()>;
pub type Response = HttpResponse<()>; pub type Response = HttpResponse<()>;
/// Server error response type. /// Server error response type.
pub type ErrorResponse = HttpResponse<Option<String>>; pub type ErrorResponse = HttpResponse<Vec<u8>>;
fn create_parts<T>(request: &HttpRequest<T>) -> Result<Builder> { fn create_parts<T>(request: &HttpRequest<T>) -> Result<Builder> {
if request.method() != http::Method::GET { if request.method() != http::Method::GET {
@ -265,9 +265,7 @@ impl<S: Read + Write, C: Callback> HandshakeRole for ServerHandshake<S, C> {
let mut output = vec![]; let mut output = vec![];
write_response(&mut output, resp)?; write_response(&mut output, resp)?;
if let Some(body) = resp.body() { output.extend_from_slice(resp.body());
output.extend_from_slice(body.as_bytes());
}
ProcessingResult::Continue(HandshakeMachine::start_write(stream, output)) ProcessingResult::Continue(HandshakeMachine::start_write(stream, output))
} }

Loading…
Cancel
Save