From 07d4721ffd992808e114572256a5de8f968ccade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 24 Nov 2019 14:52:58 +0100 Subject: [PATCH] Add type aliases for Response/Request with a fixed body type Simplifies correct usage of the API. --- src/client.rs | 41 ++++++++++++++++++++--------------------- src/handshake/client.rs | 20 +++++++++++++------- src/handshake/server.rs | 41 +++++++++++++++++++++++++---------------- 3 files changed, 58 insertions(+), 44 deletions(-) diff --git a/src/client.rs b/src/client.rs index 66b73fd..200ca53 100644 --- a/src/client.rs +++ b/src/client.rs @@ -4,11 +4,12 @@ use std::io::{Read, Write}; use std::net::{SocketAddr, TcpStream, ToSocketAddrs}; use std::result::Result as StdResult; -use http::{Request, Response, Uri}; +use http::Uri; use log::*; use url::Url; +use crate::handshake::client::{Request, Response}; use crate::protocol::WebSocketConfig; #[cfg(feature = "tls")] @@ -88,8 +89,8 @@ use crate::stream::{Mode, NoDelay}; pub fn connect_with_config( request: Req, config: Option, -) -> Result<(WebSocket, Response<()>)> { - let request: Request<()> = request.into_client_request()?; +) -> Result<(WebSocket, Response)> { + let request: Request = request.into_client_request()?; let uri = request.uri(); let mode = uri_mode(uri)?; let host = request @@ -121,9 +122,7 @@ pub fn connect_with_config( /// This function uses `native_tls` to do TLS. If you want to use other TLS libraries, /// use `client` instead. There is no need to enable the "tls" feature if you don't call /// `connect` since it's the only function that uses native_tls. -pub fn connect( - request: Req, -) -> Result<(WebSocket, Response<()>)> { +pub fn connect(request: Req) -> Result<(WebSocket, Response)> { connect_with_config(request, None) } @@ -164,7 +163,7 @@ pub fn client_with_config( request: Req, stream: Stream, config: Option, -) -> StdResult<(WebSocket, Response<()>), HandshakeError>> +) -> StdResult<(WebSocket, Response), HandshakeError>> where Stream: Read + Write, Req: IntoClientRequest, @@ -180,7 +179,7 @@ where pub fn client( request: Req, stream: Stream, -) -> StdResult<(WebSocket, Response<()>), HandshakeError>> +) -> StdResult<(WebSocket, Response), HandshakeError>> where Stream: Read + Write, Req: IntoClientRequest, @@ -193,12 +192,12 @@ where /// This trait is implemented by default for string slices, strings, `url::Url`, `http::Uri` and /// `http::Request<()>`. pub trait IntoClientRequest { - /// Convert into a `Request<()>` that can be used for a client connection. - fn into_client_request(self) -> Result>; + /// Convert into a `Request` that can be used for a client connection. + fn into_client_request(self) -> Result; } impl<'a> IntoClientRequest for &'a str { - fn into_client_request(self) -> Result> { + fn into_client_request(self) -> Result { let uri: Uri = self.parse()?; Ok(Request::get(uri).body(())?) @@ -206,7 +205,7 @@ impl<'a> IntoClientRequest for &'a str { } impl<'a> IntoClientRequest for &'a String { - fn into_client_request(self) -> Result> { + fn into_client_request(self) -> Result { let uri: Uri = self.parse()?; Ok(Request::get(uri).body(())?) @@ -214,7 +213,7 @@ impl<'a> IntoClientRequest for &'a String { } impl IntoClientRequest for String { - fn into_client_request(self) -> Result> { + fn into_client_request(self) -> Result { let uri: Uri = self.parse()?; Ok(Request::get(uri).body(())?) @@ -222,19 +221,19 @@ impl IntoClientRequest for String { } impl<'a> IntoClientRequest for &'a Uri { - fn into_client_request(self) -> Result> { + fn into_client_request(self) -> Result { Ok(Request::get(self.clone()).body(())?) } } impl IntoClientRequest for Uri { - fn into_client_request(self) -> Result> { + fn into_client_request(self) -> Result { Ok(Request::get(self).body(())?) } } impl<'a> IntoClientRequest for &'a Url { - fn into_client_request(self) -> Result> { + fn into_client_request(self) -> Result { let uri: Uri = self.as_str().parse()?; Ok(Request::get(uri).body(())?) @@ -242,22 +241,22 @@ impl<'a> IntoClientRequest for &'a Url { } impl IntoClientRequest for Url { - fn into_client_request(self) -> Result> { + fn into_client_request(self) -> Result { let uri: Uri = self.as_str().parse()?; Ok(Request::get(uri).body(())?) } } -impl IntoClientRequest for Request<()> { - fn into_client_request(self) -> Result> { +impl IntoClientRequest for Request { + fn into_client_request(self) -> Result { Ok(self) } } impl<'h, 'b> IntoClientRequest for httparse::Request<'h, 'b> { - fn into_client_request(self) -> Result> { + fn into_client_request(self) -> Result { use crate::handshake::headers::FromHttparse; - Request::<()>::from_httparse(self) + Request::from_httparse(self) } } diff --git a/src/handshake/client.rs b/src/handshake/client.rs index a0bb951..e6c8ad5 100644 --- a/src/handshake/client.rs +++ b/src/handshake/client.rs @@ -3,7 +3,7 @@ use std::io::{Read, Write}; use std::marker::PhantomData; -use http::{HeaderMap, Request, Response, StatusCode}; +use http::{HeaderMap, Request as HttpRequest, Response as HttpResponse, StatusCode}; use httparse::Status; use log::*; @@ -13,6 +13,12 @@ use super::{convert_key, HandshakeRole, MidHandshake, ProcessingResult}; use crate::error::{Error, Result}; use crate::protocol::{Role, WebSocket, WebSocketConfig}; +/// Client request type. +pub type Request = HttpRequest<()>; + +/// Client response type. +pub type Response = HttpResponse<()>; + /// Client handshake role. #[derive(Debug)] pub struct ClientHandshake { @@ -25,7 +31,7 @@ impl ClientHandshake { /// Initiate a client handshake. pub fn start( stream: S, - request: Request<()>, + request: Request, config: Option, ) -> Result> { if request.method() != http::Method::GET { @@ -93,9 +99,9 @@ impl ClientHandshake { } impl HandshakeRole for ClientHandshake { - type IncomingData = Response<()>; + type IncomingData = Response; type InternalStream = S; - type FinalResult = (WebSocket, Response<()>); + type FinalResult = (WebSocket, Response); fn stage_finished( &mut self, finish: StageResult, @@ -127,7 +133,7 @@ struct VerifyData { } impl VerifyData { - pub fn verify_response(&self, response: &Response<()>) -> Result<()> { + pub fn verify_response(&self, response: &Response) -> Result<()> { // 1. If the status code received from the server is not 101, the // client handles the response per HTTP [RFC2616] procedures. (RFC 6455) if response.status() != StatusCode::SWITCHING_PROTOCOLS { @@ -194,7 +200,7 @@ impl VerifyData { } } -impl TryParse for Response<()> { +impl TryParse for Response { fn try_parse(buf: &[u8]) -> Result> { let mut hbuffer = [httparse::EMPTY_HEADER; MAX_HEADERS]; let mut req = httparse::Response::new(&mut hbuffer); @@ -205,7 +211,7 @@ impl TryParse for Response<()> { } } -impl<'h, 'b: 'h> FromHttparse> for Response<()> { +impl<'h, 'b: 'h> FromHttparse> for Response { fn from_httparse(raw: httparse::Response<'h, 'b>) -> Result { if raw.version.expect("Bug: no HTTP version") < /*1.*/1 { return Err(Error::Protocol( diff --git a/src/handshake/server.rs b/src/handshake/server.rs index c2b7af4..f3e937e 100644 --- a/src/handshake/server.rs +++ b/src/handshake/server.rs @@ -4,7 +4,7 @@ use std::io::{self, Read, Write}; use std::marker::PhantomData; use std::result::Result as StdResult; -use http::{HeaderMap, Request, Response, StatusCode}; +use http::{HeaderMap, Request as HttpRequest, Response as HttpResponse, StatusCode}; use httparse::Status; use log::*; @@ -14,8 +14,17 @@ use super::{convert_key, HandshakeRole, MidHandshake, ProcessingResult}; use crate::error::{Error, Result}; use crate::protocol::{Role, WebSocket, WebSocketConfig}; +/// Server request type. +pub type Request = HttpRequest<()>; + +/// Server response type. +pub type Response = HttpResponse<()>; + +/// Server error response type. +pub type ErrorResponse = HttpResponse>; + /// Create a response for the request. -pub fn create_response(request: &Request<()>) -> Result> { +pub fn create_response(request: &Request) -> Result { if request.method() != http::Method::GET { return Err(Error::Protocol("Method is not GET".into())); } @@ -78,7 +87,7 @@ pub fn create_response(request: &Request<()>) -> Result> { } // Assumes that this is a valid response -fn write_response(w: &mut dyn io::Write, response: &Response) -> Result<()> { +fn write_response(w: &mut dyn io::Write, response: &HttpResponse) -> Result<()> { writeln!( w, "{version:?} {status} {reason}\r", @@ -96,7 +105,7 @@ fn write_response(w: &mut dyn io::Write, response: &Response) -> Result<() Ok(()) } -impl TryParse for Request<()> { +impl TryParse for Request { fn try_parse(buf: &[u8]) -> Result> { let mut hbuffer = [httparse::EMPTY_HEADER; MAX_HEADERS]; let mut req = httparse::Request::new(&mut hbuffer); @@ -107,7 +116,7 @@ impl TryParse for Request<()> { } } -impl<'h, 'b: 'h> FromHttparse> for Request<()> { +impl<'h, 'b: 'h> FromHttparse> for Request { fn from_httparse(raw: httparse::Request<'h, 'b>) -> Result { if raw.method.expect("Bug: no method in header") != "GET" { return Err(Error::Protocol("Method is not GET".into())); @@ -145,20 +154,20 @@ pub trait Callback: Sized { /// Returning an error resulting in rejecting the incoming connection. fn on_request( self, - request: &Request<()>, - response: Response<()>, - ) -> StdResult, Response>>; + request: &Request, + response: Response, + ) -> StdResult; } impl Callback for F where - F: FnOnce(&Request<()>, Response<()>) -> StdResult, Response>>, + F: FnOnce(&Request, Response) -> StdResult, { fn on_request( self, - request: &Request<()>, - response: Response<()>, - ) -> StdResult, Response>> { + request: &Request, + response: Response, + ) -> StdResult { self(request, response) } } @@ -170,9 +179,9 @@ pub struct NoCallback; impl Callback for NoCallback { fn on_request( self, - _request: &Request<()>, - response: Response<()>, - ) -> StdResult, Response>> { + _request: &Request, + response: Response, + ) -> StdResult { Ok(response) } } @@ -213,7 +222,7 @@ impl ServerHandshake { } impl HandshakeRole for ServerHandshake { - type IncomingData = Request<()>; + type IncomingData = Request; type InternalStream = S; type FinalResult = WebSocket;