From 0abb3863dc0a1b9911c1d9ce6f4e278277ef54c8 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Thu, 7 Dec 2017 17:38:18 -0800 Subject: [PATCH] simplify api --- src/encoding.rs | 26 ++++++++++++++------------ src/h1writer.rs | 22 +++++++++++----------- src/h2writer.rs | 16 ++++++++-------- src/httprequest.rs | 26 +++++++++----------------- src/httpresponse.rs | 6 +++--- src/middlewares/logger.rs | 10 ++++------ 6 files changed, 49 insertions(+), 57 deletions(-) diff --git a/src/encoding.rs b/src/encoding.rs index 4774b4c7a..2768dfd18 100644 --- a/src/encoding.rs +++ b/src/encoding.rs @@ -346,7 +346,7 @@ impl PayloadEncoder { }; // Enable content encoding only if response does not contain Content-Encoding header - let mut encoding = if has_body && !resp.headers.contains_key(CONTENT_ENCODING) { + let mut encoding = if has_body && !resp.headers().contains_key(CONTENT_ENCODING) { let encoding = match *resp.content_encoding() { ContentEncoding::Auto => { // negotiate content-encoding @@ -362,7 +362,8 @@ impl PayloadEncoder { } encoding => encoding, }; - resp.headers.insert(CONTENT_ENCODING, HeaderValue::from_static(encoding.as_str())); + resp.headers_mut().insert( + CONTENT_ENCODING, HeaderValue::from_static(encoding.as_str())); encoding } else { ContentEncoding::Identity @@ -377,8 +378,8 @@ impl PayloadEncoder { if resp.chunked() { error!("Chunked transfer is enabled but body is set to Empty"); } - resp.headers.insert(CONTENT_LENGTH, HeaderValue::from_static("0")); - resp.headers.remove(TRANSFER_ENCODING); + resp.headers_mut().insert(CONTENT_LENGTH, HeaderValue::from_static("0")); + resp.headers_mut().remove(TRANSFER_ENCODING); TransferEncoding::length(0) }, Body::Binary(ref mut bytes) => { @@ -399,31 +400,31 @@ impl PayloadEncoder { let _ = enc.write_eof(); let b = enc.get_mut().take(); - resp.headers.insert( + resp.headers_mut().insert( CONTENT_LENGTH, HeaderValue::from_str(format!("{}", b.len()).as_str()).unwrap()); *bytes = Binary::from(b); encoding = ContentEncoding::Identity; TransferEncoding::eof() } else { - resp.headers.insert( + resp.headers_mut().insert( CONTENT_LENGTH, HeaderValue::from_str(format!("{}", bytes.len()).as_str()).unwrap()); - resp.headers.remove(TRANSFER_ENCODING); + resp.headers_mut().remove(TRANSFER_ENCODING); TransferEncoding::length(bytes.len() as u64) } } Body::Streaming(_) | Body::StreamingContext => { if resp.chunked() { - resp.headers.remove(CONTENT_LENGTH); + resp.headers_mut().remove(CONTENT_LENGTH); if version != Version::HTTP_11 { error!("Chunked transfer encoding is forbidden for {:?}", version); } if version == Version::HTTP_2 { - resp.headers.remove(TRANSFER_ENCODING); + resp.headers_mut().remove(TRANSFER_ENCODING); TransferEncoding::eof() } else { - resp.headers.insert( + resp.headers_mut().insert( TRANSFER_ENCODING, HeaderValue::from_static("chunked")); TransferEncoding::chunked() } @@ -447,11 +448,12 @@ impl PayloadEncoder { if version == Version::HTTP_2 { error!("Connection upgrade is forbidden for HTTP/2"); } else { - resp.headers.insert(CONNECTION, HeaderValue::from_static("upgrade")); + resp.headers_mut().insert( + CONNECTION, HeaderValue::from_static("upgrade")); } if encoding != ContentEncoding::Identity { encoding = ContentEncoding::Identity; - resp.headers.remove(CONTENT_ENCODING); + resp.headers_mut().remove(CONTENT_ENCODING); } TransferEncoding::eof() } diff --git a/src/h1writer.rs b/src/h1writer.rs index 63c98e876..447758cf6 100644 --- a/src/h1writer.rs +++ b/src/h1writer.rs @@ -116,7 +116,7 @@ impl Writer for H1Writer { fn start(&mut self, req: &mut HttpRequest, msg: &mut HttpResponse) -> Result { - trace!("Prepare response with status: {:?}", msg.status); + trace!("Prepare response with status: {:?}", msg.status()); // prepare task self.started = true; @@ -126,32 +126,32 @@ impl Writer for H1Writer { // Connection upgrade let version = msg.version().unwrap_or_else(|| req.version()); if msg.upgrade() { - msg.headers.insert(CONNECTION, HeaderValue::from_static("upgrade")); + msg.headers_mut().insert(CONNECTION, HeaderValue::from_static("upgrade")); } // keep-alive else if self.keepalive { if version < Version::HTTP_11 { - msg.headers.insert(CONNECTION, HeaderValue::from_static("keep-alive")); + msg.headers_mut().insert(CONNECTION, HeaderValue::from_static("keep-alive")); } } else if version >= Version::HTTP_11 { - msg.headers.insert(CONNECTION, HeaderValue::from_static("close")); + msg.headers_mut().insert(CONNECTION, HeaderValue::from_static("close")); } // render message { let buffer = self.encoder.get_mut(); if let Body::Binary(ref bytes) = *msg.body() { - buffer.reserve(100 + msg.headers.len() * AVERAGE_HEADER_SIZE + bytes.len()); + buffer.reserve(100 + msg.headers().len() * AVERAGE_HEADER_SIZE + bytes.len()); } else { - buffer.reserve(100 + msg.headers.len() * AVERAGE_HEADER_SIZE); + buffer.reserve(100 + msg.headers().len() * AVERAGE_HEADER_SIZE); } - if version == Version::HTTP_11 && msg.status == StatusCode::OK { + if version == Version::HTTP_11 && msg.status() == StatusCode::OK { buffer.extend(b"HTTP/1.1 200 OK\r\n"); } else { - let _ = write!(buffer, "{:?} {}\r\n", version, msg.status); + let _ = write!(buffer, "{:?} {}\r\n", version, msg.status()); } - for (key, value) in &msg.headers { + for (key, value) in msg.headers() { let t: &[u8] = key.as_ref(); buffer.extend(t); buffer.extend(b": "); @@ -161,7 +161,7 @@ impl Writer for H1Writer { // using http::h1::date is quite a lot faster than generating // a unique Date header each time like req/s goes up about 10% - if !msg.headers.contains_key(DATE) { + if !msg.headers().contains_key(DATE) { buffer.reserve(date::DATE_VALUE_LENGTH + 8); buffer.extend(b"Date: "); let mut bytes = [0u8; 29]; @@ -171,7 +171,7 @@ impl Writer for H1Writer { } // default content-type - if !msg.headers.contains_key(CONTENT_TYPE) { + if !msg.headers().contains_key(CONTENT_TYPE) { buffer.extend(b"ContentType: application/octet-stream\r\n".as_ref()); } diff --git a/src/h2writer.rs b/src/h2writer.rs index e3e04bd77..82a1b96e0 100644 --- a/src/h2writer.rs +++ b/src/h2writer.rs @@ -108,7 +108,7 @@ impl Writer for H2Writer { fn start(&mut self, req: &mut HttpRequest, msg: &mut HttpResponse) -> Result { - trace!("Prepare response with status: {:?}", msg.status); + trace!("Prepare response with status: {:?}", msg.status()); // prepare response self.started = true; @@ -116,25 +116,25 @@ impl Writer for H2Writer { self.eof = if let Body::Empty = *msg.body() { true } else { false }; // http2 specific - msg.headers.remove(CONNECTION); - msg.headers.remove(TRANSFER_ENCODING); + msg.headers_mut().remove(CONNECTION); + msg.headers_mut().remove(TRANSFER_ENCODING); // using http::h1::date is quite a lot faster than generating // a unique Date header each time like req/s goes up about 10% - if !msg.headers.contains_key(DATE) { + if !msg.headers().contains_key(DATE) { let mut bytes = [0u8; 29]; date::extend(&mut bytes[..]); - msg.headers.insert(DATE, HeaderValue::try_from(&bytes[..]).unwrap()); + msg.headers_mut().insert(DATE, HeaderValue::try_from(&bytes[..]).unwrap()); } // default content-type - if !msg.headers.contains_key(CONTENT_TYPE) { - msg.headers.insert( + if !msg.headers().contains_key(CONTENT_TYPE) { + msg.headers_mut().insert( CONTENT_TYPE, HeaderValue::from_static("application/octet-stream")); } let mut resp = Response::new(()); - *resp.status_mut() = msg.status; + *resp.status_mut() = msg.status(); *resp.version_mut() = Version::HTTP_2; for (key, value) in msg.headers().iter() { resp.headers_mut().insert(key, value.clone()); diff --git a/src/httprequest.rs b/src/httprequest.rs index 284adf9cb..36dcf22c4 100644 --- a/src/httprequest.rs +++ b/src/httprequest.rs @@ -97,11 +97,13 @@ impl HttpRequest { HttpRequest(Rc::clone(&self.0), Rc::new(()), None) } - /// get mutable reference for inner message + // get mutable reference for inner message + // mutable reference should not be returned as result for request's method #[inline] - fn as_mut(&mut self) -> &mut HttpMessage { + #[allow(mutable_transmutes)] + #[cfg_attr(feature = "cargo-clippy", allow(mut_from_ref))] + fn as_mut(&self) -> &mut HttpMessage { let r: &HttpMessage = self.0.as_ref(); - #[allow(mutable_transmutes)] unsafe{mem::transmute(r)} } @@ -158,18 +160,8 @@ impl HttpRequest { self.0.uri.path() } - /// Get previously loaded *ConnectionInfo*. - #[inline] - pub fn connection_info(&self) -> Option<&ConnectionInfo> { - if self.0.info.is_none() { - None - } else { - self.0.info.as_ref() - } - } - - /// Load *ConnectionInfo* for currect request. - pub fn load_connection_info(&mut self) -> &ConnectionInfo { + /// Get *ConnectionInfo* for currect request. + pub fn connection_info(&self) -> &ConnectionInfo { if self.0.info.is_none() { let info: ConnectionInfo<'static> = unsafe{ mem::transmute(ConnectionInfo::new(self))}; @@ -178,7 +170,7 @@ impl HttpRequest { self.0.info.as_ref().unwrap() } - pub fn url_for(&mut self, name: &str, elements: U) -> Result + pub fn url_for(&self, name: &str, elements: U) -> Result where U: IntoIterator, I: AsRef, { @@ -187,7 +179,7 @@ impl HttpRequest { } else { let path = self.router().unwrap().resource_path(name, elements)?; if path.starts_with('/') { - let conn = self.load_connection_info(); + let conn = self.connection_info(); Ok(Url::parse(&format!("{}://{}{}", conn.scheme(), conn.host(), path))?) } else { Ok(Url::parse(&path)?) diff --git a/src/httpresponse.rs b/src/httpresponse.rs index 0f01d96fa..e877a761a 100644 --- a/src/httpresponse.rs +++ b/src/httpresponse.rs @@ -29,9 +29,9 @@ pub enum ConnectionType { /// An HTTP Response pub struct HttpResponse { - pub version: Option, - pub headers: HeaderMap, - pub status: StatusCode, + version: Option, + headers: HeaderMap, + status: StatusCode, reason: Option<&'static str>, body: Body, chunked: bool, diff --git a/src/middlewares/logger.rs b/src/middlewares/logger.rs index a18e8ad15..5e443fce6 100644 --- a/src/middlewares/logger.rs +++ b/src/middlewares/logger.rs @@ -102,7 +102,6 @@ impl Logger { impl Middleware for Logger { fn start(&self, req: &mut HttpRequest) -> Started { - req.load_connection_info(); req.extensions().insert(StartTime(time::now())); Started::Done } @@ -237,12 +236,11 @@ impl FormatText { fmt.write_fmt(format_args!("{:.6}", response_time_ms)) }, FormatText::RemoteAddr => { - if let Some(addr) = req.connection_info() { - if let Some(remote) = addr.remote() { - return remote.fmt(fmt); - } + if let Some(remote) = req.connection_info().remote() { + return remote.fmt(fmt); + } else { + "-".fmt(fmt) } - "-".fmt(fmt) } FormatText::RequestTime => { entry_time.strftime("[%d/%b/%Y:%H:%M:%S %z]")