mirror of
https://github.com/actix/actix-web.git
synced 2024-12-18 22:26:37 +00:00
optimize http message serialization
This commit is contained in:
parent
4d81186059
commit
6ee14efbe2
4 changed files with 61 additions and 14 deletions
|
@ -74,6 +74,7 @@ impl SharedMessagePool {
|
|||
SharedMessagePool(RefCell::new(VecDeque::with_capacity(128)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get(&self) -> Rc<HttpMessage> {
|
||||
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<HttpMessage>) {
|
||||
let v = &mut self.0.borrow_mut();
|
||||
if v.len() < 128 {
|
||||
|
|
|
@ -21,6 +21,7 @@ struct Inner {
|
|||
named: HashMap<String, (Pattern, bool)>,
|
||||
patterns: Vec<Pattern>,
|
||||
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<S>(&self, req: &mut HttpRequest<S>) -> Option<usize> {
|
||||
if !self.0.hasroutes { return None }
|
||||
let mut idx = None;
|
||||
{
|
||||
if self.0.prefix_len > req.path().len() {
|
||||
|
|
|
@ -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<T: AsyncWrite> Writer for H1Writer<T> {
|
|||
|
||||
// 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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue