diff --git a/src/helpers.rs b/src/helpers.rs index 947851ea9..25e22b8fe 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -74,6 +74,7 @@ impl SharedMessagePool { SharedMessagePool(RefCell::new(VecDeque::with_capacity(128))) } + #[inline] pub fn get(&self) -> Rc { if let Some(msg) = self.0.borrow_mut().pop_front() { msg @@ -82,6 +83,7 @@ impl SharedMessagePool { } } + #[inline] pub fn release(&self, mut msg: Rc) { let v = &mut self.0.borrow_mut(); if v.len() < 128 { diff --git a/src/router.rs b/src/router.rs index b1e31151d..2c1f24032 100644 --- a/src/router.rs +++ b/src/router.rs @@ -21,6 +21,7 @@ struct Inner { named: HashMap, patterns: Vec, srv: ServerSettings, + hasroutes: bool, } impl Router { @@ -55,6 +56,7 @@ impl Router { regset: RegexSet::new(&paths).unwrap(), named: named, patterns: patterns, + hasroutes: !paths.is_empty(), srv: settings })), resources) } @@ -72,6 +74,7 @@ impl Router { /// Query for matched resource pub fn recognize(&self, req: &mut HttpRequest) -> Option { + if !self.0.hasroutes { return None } let mut idx = None; { if self.0.prefix_len > req.path().len() { diff --git a/src/server/h1writer.rs b/src/server/h1writer.rs index 165f28e0c..aa9c819d7 100644 --- a/src/server/h1writer.rs +++ b/src/server/h1writer.rs @@ -1,4 +1,4 @@ -use std::io; +use std::{io, mem}; use bytes::BufMut; use futures::{Async, Poll}; use tokio_io::AsyncWrite; @@ -135,38 +135,60 @@ impl Writer for H1Writer { // status line helpers::write_status_line(version, msg.status().as_u16(), &mut buffer); - buffer.extend_from_slice(msg.reason().as_bytes()); + SharedBytes::extend_from_slice_(buffer, msg.reason().as_bytes()); match body { Body::Empty => if req.method != Method::HEAD { - buffer.extend_from_slice(b"\r\ncontent-length: 0\r\n"); + SharedBytes::extend_from_slice_(buffer, b"\r\ncontent-length: 0\r\n"); } else { - buffer.extend_from_slice(b"\r\n"); + SharedBytes::extend_from_slice_(buffer, b"\r\n"); }, Body::Binary(ref bytes) => helpers::write_content_length(bytes.len(), &mut buffer), _ => - buffer.extend_from_slice(b"\r\n"), + SharedBytes::extend_from_slice_(buffer, b"\r\n"), } // write headers + let mut pos = 0; + let mut remaining = buffer.remaining_mut(); + let mut buf: &mut [u8] = unsafe{ mem::transmute(buffer.bytes_mut()) }; for (key, value) in msg.headers() { let v = value.as_ref(); let k = key.as_str().as_bytes(); - buffer.reserve(k.len() + v.len() + 4); - buffer.put_slice(k); - buffer.put_slice(b": "); - buffer.put_slice(v); - buffer.put_slice(b"\r\n"); + let len = k.len() + v.len() + 4; + if len > remaining { + unsafe{buffer.advance_mut(pos)}; + pos = 0; + buffer.reserve(len); + remaining = buffer.remaining_mut(); + buf = unsafe{ mem::transmute(buffer.bytes_mut()) }; + } + + buf[pos..pos+k.len()].copy_from_slice(k); + pos += k.len(); + buf[pos..pos+2].copy_from_slice(b": "); + pos += 2; + buf[pos..pos+v.len()].copy_from_slice(v); + pos += v.len(); + buf[pos..pos+2].copy_from_slice(b"\r\n"); + pos += 2; + remaining -= len; + + //buffer.put_slice(k); + //buffer.put_slice(b": "); + //buffer.put_slice(v); + //buffer.put_slice(b"\r\n"); } + unsafe{buffer.advance_mut(pos)}; // using helpers::date is quite a lot faster if !msg.headers().contains_key(DATE) { helpers::date(&mut buffer); } else { // msg eof - buffer.extend_from_slice(b"\r\n"); + SharedBytes::extend_from_slice_(buffer, b"\r\n"); } self.headers_size = buffer.len() as u32; } diff --git a/src/server/shared.rs b/src/server/shared.rs index 22851a10c..f39a31605 100644 --- a/src/server/shared.rs +++ b/src/server/shared.rs @@ -2,7 +2,7 @@ use std::mem; use std::cell::RefCell; use std::rc::Rc; use std::collections::VecDeque; -use bytes::BytesMut; +use bytes::{BufMut, BytesMut}; use body::Binary; @@ -98,12 +98,32 @@ impl SharedBytes { #[inline] #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] pub fn extend(&self, data: Binary) { - self.get_mut().extend_from_slice(data.as_ref()); + let buf = self.get_mut(); + let data = data.as_ref(); + buf.reserve(data.len()); + SharedBytes::put_slice(buf, data); } #[inline] pub fn extend_from_slice(&self, data: &[u8]) { - self.get_mut().extend_from_slice(data); + let buf = self.get_mut(); + buf.reserve(data.len()); + SharedBytes::put_slice(buf, data); + } + + #[inline] + pub(crate) fn put_slice(buf: &mut BytesMut, src: &[u8]) { + let len = src.len(); + unsafe { + buf.bytes_mut()[..len].copy_from_slice(src); + buf.advance_mut(len); + } + } + + #[inline] + pub(crate) fn extend_from_slice_(buf: &mut BytesMut, data: &[u8]) { + buf.reserve(data.len()); + SharedBytes::put_slice(buf, data); } }