<commit_before>use std::cmp::min;
use std::str::from_utf8;

use netbuf::MAX_BUF_SIZE;
use rotor::Scope;
use rotor_stream::{Protocol, StreamSocket, Deadline, Expectation as E};
use rotor_stream::{Request, Transport};
use hyper::status::StatusCode::{PayloadTooLarge, BadRequest};
use hyper::method::Method::Head;
use hyper::header::Expect;

use super::{MAX_HEADERS_SIZE, MAX_CHUNK_HEAD};
use super::{Response};
use super::protocol::{Server, RecvMode};
use super::context::Context;
use super::request::Head;
use super::body::BodyKind;
use super::ResponseImpl;

struct ReadBody<M: Sized> {
    machine: Option<M>,
    deadline: Deadline,
    progress: BodyProgress,
    response: ResponseImpl,
}

pub enum BodyProgress {
    /// Buffered fixed-size request (bytes left)
    BufferFixed(usize),
    /// Buffered request till end of input (byte limit)
    BufferEOF(usize),
    /// Buffered request with chunked encoding
    /// (limit, bytes buffered, bytes left for current chunk)
    BufferChunked(usize, usize, usize),
    /// Progressive fixed-size request (size hint, bytes left)
    ProgressiveFixed(usize, u64),
    /// Progressive till end of input (size hint)
    ProgressiveEOF(usize),
    /// Progressive with chunked encoding (hint, bytes left for current chunk)
    // To be able to merge chunks, should add offset here
    ProgressiveChunked(usize, u64),
}

pub struct Parser<M: Sized>(ParserImpl<M>);

enum ParserImpl<M: Sized> {
    Idle,
    ReadHeaders,
    ReadingBody(ReadBody<M>),
    /// Close connection after buffer is flushed. In other cases -> Idle
    Processing(M, ResponseImpl, Deadline),
    DoneResponse,
}

impl<M> Parser<M>
{
    fn flush<C>(scope: &mut Scope<C>) -> Request<Parser<M>>
        where C: Context
    {
        Some((Parser(ParserImpl::DoneResponse), E::Flush(0),
              Deadline::now() + scope.byte_timeout()))
    }
    fn bad_request<'x, C>(scope: &mut Scope<C>, mut response: Response<'x>)
        -> Request<Parser<M>>
        where C: Context
    {
        if !response.is_started() {
            scope.emit_error_page(BadRequest, &mut response);
        }
        response.finish();
        Some((Parser(ParserImpl::DoneResponse), E::Flush(0),
              Deadline::now() + scope.byte_timeout()))
    }
}

fn start_headers<C: Context, M: Sized>(scope: &mut Scope<C>)
    -> Request<Parser<M>>
{
    Some((Parser(ParserImpl::ReadHeaders),
          E::Delimiter(0, b"\r\n\r\n", MAX_HEADERS_SIZE),
          Deadline::now() + scope.byte_timeout()))
}

fn start_body(mode: RecvMode, body: BodyKind) -> BodyProgress {
    use super::body::BodyKind::*;
    use super::protocol::RecvMode::*;
    use self::BodyProgress::*;

    match (mode, body) {
        // The size of Fixed(x) is checked in parse_headers
        (Buffered(_), Fixed(y)) => BufferFixed(y as usize),
        (Buffered(x), Chunked) => BufferChunked(x, 0, 0),
        (Buffered(x), Eof) => BufferEOF(x),
        (Progressive(x), Fixed(y)) => ProgressiveFixed(x, y),
        (Progressive(x), Chunked) => ProgressiveChunked(x, 0),
        (Progressive(x), Eof) => ProgressiveEOF(x),
        (_, Upgrade) => unimplemented!(),
    }
}

// Parses headers
//
// On error returns bool, which is true if keep-alive connection can be
// carried on.
fn parse_headers<C, M, S>(transport: &mut Transport<S>, end: usize,
    scope: &mut Scope<C>) -> Result<ReadBody<M>, bool>
    where M: Server<C>,
          S: StreamSocket,
          C: Context,
{
    // Determines if we can keep-alive after error response.
    // We may not be able to keep keep-alive for multiple reasons:
    //
    // 1. When request headers are too wrong
    //    (probably client connects with wrong protocol)
    //
    // 2. When request contains non-empty request body (we don't
    //    want to wait until it is uploaded just to send error)
    //
    // Note we definitely can't keep alive if we can't say
    // whether request method is HEAD
    //
    // All of these are important to avoid cache poisoning attacks
    // on proxy servers.
    let mut can_keep_alive = false;
    // Determines if we can safely send the response body
    let mut is_head = false;

    let status = match Head::parse(&transport.input()[..end+4]) {
        Ok(head) => {
            is_head = head.method == Head;
            match M::headers_received(&head, scope) {
                Ok((_, RecvMode::Buffered(x), _)) if x >= MAX_BUF_SIZE
                => panic!("Can't buffer {} bytes, max {}",
                          x, MAX_BUF_SIZE),
                Ok((m, mode, dline)) => {
                    match BodyKind::parse(&head) {
                        Ok(body) => {
                            // TODO(tailhook)
                            // Probably can handle small
                            // request bodies that are already
                            // in the buffer
                            if body == BodyKind::Fixed(0) {
                                can_keep_alive = true;
                            }
                            match (body, mode) {
                                (BodyKind::Fixed(x), RecvMode::Buffered(y))
                                if x >= y as u64 => {
                                    Err(PayloadTooLarge)
                                }
                                _ => {
                                    Ok((head, body, m, mode, dline))
                                }
                            }
                        }
                        Err(status) => Err(status),
                    }
                }
                Err(status) => Err(status),
            }
        }
        Err(status) => Err(status),
    };
    transport.input().consume(end+4);
    match status {
        Ok((head, body, m, mode, dline)) => {
            if head.headers.get::<Expect>() == Some(&Expect::Continue) {
                // Handler has already approved request, so just push it
                transport.output().extend(
                    format!("{} 100 Continue\r\n\r\n", head.version)
                    .as_bytes());
            }
            let mut resp = Response::new(transport.output(), &head);
            Ok(ReadBody {
                machine: m.request_start(head, &mut resp, scope),
                deadline: dline,
                progress: start_body(mode, body),
                response: resp.internal(),
            })
        }
        Err(status) => {
            let mut resp = Response::simple(transport.output(), is_head);
            scope.emit_error_page(status, &mut resp);
            let okay = resp.finish();
            Err(can_keep_alive && okay)
        }
    }
}

impl<M> ParserImpl<M>
{
    fn request<C>(self, scope: &mut Scope<C>) -> Request<Parser<M>>
        where C: Context
    {
        use rotor_stream::Expectation::*;
        use self::ParserImpl::*;
        use self::BodyProgress::*;
        let (exp, dline) = match self {
            Idle => (Bytes(0), None),
            ReadHeaders => (Delimiter(0, b"\r\n\r\n", MAX_HEADERS_SIZE), None),
            ReadingBody(ref b) => {
                let exp = match *&b.progress {
                    BufferFixed(x) => Bytes(x),
                    BufferEOF(x) => Eof(x),
                    BufferChunked(_, off, 0)
                    => Delimiter(off, b"\r\n", off+MAX_CHUNK_HEAD),
                    BufferChunked(_, off, y) => Bytes(off + y),
                    ProgressiveFixed(hint, left)
                    => Bytes(min(hint as u64, left) as usize),
                    ProgressiveEOF(hint) => Eof(hint),
                    ProgressiveChunked(_, 0)
                    => Delimiter(0, b"\r\n", 0+MAX_CHUNK_HEAD),
                    ProgressiveChunked(hint, left)
                    => Bytes(min(hint as u64, left) as usize)
                };
                (exp, Some(b.deadline))
            }
            Processing(..) => unreachable!(),
            /// TODO(tailhook) fix output timeout
            DoneResponse => (Flush(0), None),
        };

        let byte_dline = Deadline::now() + scope.byte_timeout();
        let deadline = dline.map_or_else(
            || byte_dline,
            |x| min(byte_dline, x));
        Some((Parser(self), exp, deadline))
    }
}

impl<C, M, S> Protocol<C, S> for Parser<M>
    where M: Server<C>,
          S: StreamSocket,
          C: Context,
{
    type Seed = ();
    fn create(_seed: (), _sock: &mut S, scope: &mut Scope<C>)
        -> Request<Self>
    {
        Some((Parser(ParserImpl::Idle), E::Bytes(1),
            Deadline::now() + scope.byte_timeout()))
    }
    fn bytes_read(self, transport: &mut Transport<S>,
                  end: usize, scope: &mut Scope<C>)
        -> Request<Self>
    {
        use self::ParserImpl::*;
        use self::BodyProgress::*;
        match self.0 {
            Idle => {
                start_headers(scope)
            }
            ReadHeaders => {
                match parse_headers::<C, M, S>(transport, end, scope) {
                    Ok(body) => {
                        ReadingBody(body).request(scope)
                    }
                    Err(can_keep_alive) => {
                        if can_keep_alive {
                            Idle.request(scope)
                        } else {
                            Parser::flush(scope)
                        }
                    }
                }
            }
            ReadingBody(rb) => {
                let (inp, out) = transport.buffers();
                let mut resp = rb.response.with(out);
                let (m, progress) = match rb.progress {
                    BufferFixed(x) => {
                        let m = rb.machine.and_then(
                            |m| m.request_received(
                                            &inp[..x], &mut resp, scope));
                        (m, None)
                    }
                    BufferEOF(_) => {
                        let len = inp.len();
                        let m = rb.machine.and_then(
                            |m| m.request_received(
                                            &inp[..len], &mut resp, scope));
                        (m, None)
                    }
                    BufferChunked(limit, off, 0) => {
                        let clen_end = inp[off..end].iter()
                            .position(|&x| x == b';')
                            .map(|x| x + off).unwrap_or(end);
                        let val_opt = from_utf8(&inp[off..clen_end]).ok()
                            .and_then(|x| u64::from_str_radix(x, 16).ok());
                        match val_opt {
                            Some(chunk_len) => {
                                if off as u64 + chunk_len > limit as u64 {
                                    rb.machine.map(
                                        |m| m.bad_request(&mut resp, scope));
                                    return Parser::bad_request(scope, resp);
                                }
                                inp.remove_range(off..end);
                                (rb.machine,
                                    Some(BufferChunked(limit, off,
                                                  chunk_len as usize)))
                            }
                            None => {
                                rb.machine.map(
                                    |m| m.bad_request(&mut resp, scope));
                                return Parser::bad_request(scope, resp);
                            }
                        }
                    }
                    BufferChunked(limit, off, _) => {
                        (rb.machine, Some(BufferChunked(limit, off, 0)))
                    }
                    ProgressiveFixed(..) => unimplemented!(),
                    ProgressiveEOF(..) => unimplemented!(),
                    ProgressiveChunked(..) => unimplemented!(),
                };
                match progress {
                    Some(p) => {
                        ReadingBody(ReadBody {
                            machine: m,
                            deadline: rb.deadline,
                            progress: p,
                            response: resp.internal(),
                        }).request(scope)
                    }
                    None => match m {
                        Some(m) => {
                            Some((Parser(Processing(
                                        m, resp.internal(), rb.deadline)),
                                 E::Sleep, rb.deadline))
                        }
                        None => {
                            Idle.request(scope)
                        }
                    }
                }
            }
            // Spurious event?
            me @ DoneResponse => me.request(scope),
            Processing(m, r, dline) => Some((Parser(Processing(m, r, dline)),
                                             E::Sleep, dline)),
        }
    }
    fn bytes_flushed(self, _transport: &mut Transport<S>,
                     scope: &mut Scope<C>)
        -> Request<Self>
    {
        match self.0 {
            ParserImpl::DoneResponse => None,
            me => me.request(scope),
        }
    }
    fn timeout(self, _transport: &mut Transport<S>,
        _scope: &mut Scope<C>)
        -> Request<Self>
    {
        unimplemented!();
    }
    fn delimiter_not_found(self, _transport: &mut Transport<S>,
        scope: &mut Scope<C>)
        -> Request<Self>
    {
        use self::ParserImpl::*;
        use self::BodyProgress::*;
        // We may just flush and exit in every state. But:
        // 1. The match asserts that we know which state parser may be in
        // 2. We may send more specific response, so that browser will not
        //    retry ugly request multiple times
        match self.0 {
            ReadHeaders
                // TODO(tailhook) send RequestHeaderFieldsTooLarge
            | ReadingBody( ReadBody { progress: ProgressiveChunked(_, 0), ..})
            | ReadingBody( ReadBody { progress: BufferChunked(_, _, 0), ..})
                // TODO(tailhook) send BadRequest ?
            => {
                // Should we flush or just close?
                // Probably closing is useful because previous responses might
                // be absolutely valid, and we've got invalid pipelined
                // request
                Parser::flush(scope)
            }
            // TODO(tailhook) Any other weird cases?
            _ => unreachable!(),
        }
    }
    fn wakeup(self, _transport: &mut Transport<S>, scope: &mut Scope<C>)
        -> Request<Self>
    {
        use self::ParserImpl::*;
        match self.0 {
            me@Idle | me@ReadHeaders | me@DoneResponse => me.request(scope),
            ReadingBody(_reader) => {
                unimplemented!();
            }
            Processing(..) => {
                unimplemented!();
            }
        }
    }
}
<commit_msg>WIP: Another chunk of unimlemented code removed<commit_after>use std::cmp::min;
use std::str::from_utf8;

use netbuf::MAX_BUF_SIZE;
use rotor::Scope;
use rotor_stream::{Protocol, StreamSocket, Deadline, Expectation as E};
use rotor_stream::{Request, Transport};
use hyper::status::StatusCode::{PayloadTooLarge, BadRequest};
use hyper::method::Method::Head;
use hyper::header::Expect;

use super::{MAX_HEADERS_SIZE, MAX_CHUNK_HEAD};
use super::{Response};
use super::protocol::{Server, RecvMode};
use super::context::Context;
use super::request::Head;
use super::body::BodyKind;
use super::ResponseImpl;

struct ReadBody<M: Sized> {
    machine: Option<M>,
    deadline: Deadline,
    progress: BodyProgress,
    response: ResponseImpl,
}

pub enum BodyProgress {
    /// Buffered fixed-size request (bytes left)
    BufferFixed(usize),
    /// Buffered request till end of input (byte limit)
    BufferEOF(usize),
    /// Buffered request with chunked encoding
    /// (limit, bytes buffered, bytes left for current chunk)
    BufferChunked(usize, usize, usize),
    /// Progressive fixed-size request (size hint, bytes left)
    ProgressiveFixed(usize, u64),
    /// Progressive till end of input (size hint)
    ProgressiveEOF(usize),
    /// Progressive with chunked encoding (hint, bytes left for current chunk)
    // To be able to merge chunks, should add offset here
    ProgressiveChunked(usize, u64),
}

pub struct Parser<M: Sized>(ParserImpl<M>);

enum ParserImpl<M: Sized> {
    Idle,
    ReadHeaders,
    ReadingBody(ReadBody<M>),
    /// Close connection after buffer is flushed. In other cases -> Idle
    Processing(M, ResponseImpl, Deadline),
    DoneResponse,
}

impl<M> Parser<M>
{
    fn flush<C>(scope: &mut Scope<C>) -> Request<Parser<M>>
        where C: Context
    {
        Some((Parser(ParserImpl::DoneResponse), E::Flush(0),
              Deadline::now() + scope.byte_timeout()))
    }
    fn bad_request<'x, C>(scope: &mut Scope<C>, mut response: Response<'x>)
        -> Request<Parser<M>>
        where C: Context
    {
        if !response.is_started() {
            scope.emit_error_page(BadRequest, &mut response);
        }
        response.finish();
        Some((Parser(ParserImpl::DoneResponse), E::Flush(0),
              Deadline::now() + scope.byte_timeout()))
    }
}

fn start_headers<C: Context, M: Sized>(scope: &mut Scope<C>)
    -> Request<Parser<M>>
{
    Some((Parser(ParserImpl::ReadHeaders),
          E::Delimiter(0, b"\r\n\r\n", MAX_HEADERS_SIZE),
          Deadline::now() + scope.byte_timeout()))
}

fn start_body(mode: RecvMode, body: BodyKind) -> BodyProgress {
    use super::body::BodyKind::*;
    use super::protocol::RecvMode::*;
    use self::BodyProgress::*;

    match (mode, body) {
        // The size of Fixed(x) is checked in parse_headers
        (Buffered(_), Fixed(y)) => BufferFixed(y as usize),
        (Buffered(x), Chunked) => BufferChunked(x, 0, 0),
        (Buffered(x), Eof) => BufferEOF(x),
        (Progressive(x), Fixed(y)) => ProgressiveFixed(x, y),
        (Progressive(x), Chunked) => ProgressiveChunked(x, 0),
        (Progressive(x), Eof) => ProgressiveEOF(x),
        (_, Upgrade) => unimplemented!(),
    }
}

// Parses headers
//
// On error returns bool, which is true if keep-alive connection can be
// carried on.
fn parse_headers<C, M, S>(transport: &mut Transport<S>, end: usize,
    scope: &mut Scope<C>) -> Result<ReadBody<M>, bool>
    where M: Server<C>,
          S: StreamSocket,
          C: Context,
{
    // Determines if we can keep-alive after error response.
    // We may not be able to keep keep-alive for multiple reasons:
    //
    // 1. When request headers are too wrong
    //    (probably client connects with wrong protocol)
    //
    // 2. When request contains non-empty request body (we don't
    //    want to wait until it is uploaded just to send error)
    //
    // Note we definitely can't keep alive if we can't say
    // whether request method is HEAD
    //
    // All of these are important to avoid cache poisoning attacks
    // on proxy servers.
    let mut can_keep_alive = false;
    // Determines if we can safely send the response body
    let mut is_head = false;

    let status = match Head::parse(&transport.input()[..end+4]) {
        Ok(head) => {
            is_head = head.method == Head;
            match M::headers_received(&head, scope) {
                Ok((_, RecvMode::Buffered(x), _)) if x >= MAX_BUF_SIZE
                => panic!("Can't buffer {} bytes, max {}",
                          x, MAX_BUF_SIZE),
                Ok((m, mode, dline)) => {
                    match BodyKind::parse(&head) {
                        Ok(body) => {
                            // TODO(tailhook)
                            // Probably can handle small
                            // request bodies that are already
                            // in the buffer
                            if body == BodyKind::Fixed(0) {
                                can_keep_alive = true;
                            }
                            match (body, mode) {
                                (BodyKind::Fixed(x), RecvMode::Buffered(y))
                                if x >= y as u64 => {
                                    Err(PayloadTooLarge)
                                }
                                _ => {
                                    Ok((head, body, m, mode, dline))
                                }
                            }
                        }
                        Err(status) => Err(status),
                    }
                }
                Err(status) => Err(status),
            }
        }
        Err(status) => Err(status),
    };
    transport.input().consume(end+4);
    match status {
        Ok((head, body, m, mode, dline)) => {
            if head.headers.get::<Expect>() == Some(&Expect::Continue) {
                // Handler has already approved request, so just push it
                transport.output().extend(
                    format!("{} 100 Continue\r\n\r\n", head.version)
                    .as_bytes());
            }
            let mut resp = Response::new(transport.output(), &head);
            Ok(ReadBody {
                machine: m.request_start(head, &mut resp, scope),
                deadline: dline,
                progress: start_body(mode, body),
                response: resp.internal(),
            })
        }
        Err(status) => {
            let mut resp = Response::simple(transport.output(), is_head);
            scope.emit_error_page(status, &mut resp);
            let okay = resp.finish();
            Err(can_keep_alive && okay)
        }
    }
}

impl<M> ParserImpl<M>
{
    fn request<C>(self, scope: &mut Scope<C>) -> Request<Parser<M>>
        where C: Context
    {
        use rotor_stream::Expectation::*;
        use self::ParserImpl::*;
        use self::BodyProgress::*;
        let (exp, dline) = match self {
            Idle => (Bytes(0), None),
            ReadHeaders => (Delimiter(0, b"\r\n\r\n", MAX_HEADERS_SIZE), None),
            ReadingBody(ref b) => {
                let exp = match *&b.progress {
                    BufferFixed(x) => Bytes(x),
                    BufferEOF(x) => BufferEof(x),
                    BufferChunked(_, off, 0)
                    => Delimiter(off, b"\r\n", off+MAX_CHUNK_HEAD),
                    BufferChunked(_, off, y) => Bytes(off + y),
                    ProgressiveFixed(hint, left)
                    => Bytes(min(hint as u64, left) as usize),
                    ProgressiveEOF(hint) => Eof(hint),
                    ProgressiveChunked(_, 0)
                    => Delimiter(0, b"\r\n", 0+MAX_CHUNK_HEAD),
                    ProgressiveChunked(hint, left)
                    => Bytes(min(hint as u64, left) as usize)
                };
                (exp, Some(b.deadline))
            }
            Processing(..) => unreachable!(),
            /// TODO(tailhook) fix output timeout
            DoneResponse => (Flush(0), None),
        };

        let byte_dline = Deadline::now() + scope.byte_timeout();
        let deadline = dline.map_or_else(
            || byte_dline,
            |x| min(byte_dline, x));
        Some((Parser(self), exp, deadline))
    }
}

impl<C, M, S> Protocol<C, S> for Parser<M>
    where M: Server<C>,
          S: StreamSocket,
          C: Context,
{
    type Seed = ();
    fn create(_seed: (), _sock: &mut S, scope: &mut Scope<C>)
        -> Request<Self>
    {
        Some((Parser(ParserImpl::Idle), E::Bytes(1),
            Deadline::now() + scope.byte_timeout()))
    }
    fn bytes_read(self, transport: &mut Transport<S>,
                  end: usize, scope: &mut Scope<C>)
        -> Request<Self>
    {
        use self::ParserImpl::*;
        use self::BodyProgress::*;
        match self.0 {
            Idle => {
                start_headers(scope)
            }
            ReadHeaders => {
                match parse_headers::<C, M, S>(transport, end, scope) {
                    Ok(body) => {
                        ReadingBody(body).request(scope)
                    }
                    Err(can_keep_alive) => {
                        if can_keep_alive {
                            Idle.request(scope)
                        } else {
                            Parser::flush(scope)
                        }
                    }
                }
            }
            ReadingBody(rb) => {
                let (inp, out) = transport.buffers();
                let mut resp = rb.response.with(out);
                let (m, progress) = match rb.progress {
                    BufferFixed(x) => {
                        let m = rb.machine.and_then(
                            |m| m.request_received(
                                            &inp[..x], &mut resp, scope));
                        inp.consume(x);
                        (m, None)
                    }
                    BufferEOF(_) => {
                        let len = inp.len();
                        let m = rb.machine.and_then(
                            |m| m.request_received(
                                            &inp[..len], &mut resp, scope));
                        inp.consume(len);
                        (m, None)
                    }
                    BufferChunked(limit, off, 0) => {
                        let clen_end = inp[off..end].iter()
                            .position(|&x| x == b';')
                            .map(|x| x + off).unwrap_or(end);
                        let val_opt = from_utf8(&inp[off..clen_end]).ok()
                            .and_then(|x| u64::from_str_radix(x, 16).ok());
                        match val_opt {
                            Some(0) => {
                                inp.remove_range(off..);
                                let m = rb.machine.and_then(
                                    |m| m.request_received(
                                        &inp[..off], &mut resp, scope));
                                inp.consume(off);
                                (m, None)
                            }
                            Some(chunk_len) => {
                                if off as u64 + chunk_len > limit as u64 {
                                    inp.consume(end+2);
                                    rb.machine.map(
                                        |m| m.bad_request(&mut resp, scope));
                                    return Parser::bad_request(scope, resp);
                                }
                                (rb.machine,
                                    Some(BufferChunked(limit, off,
                                                  chunk_len as usize)))
                            }
                            None => {
                                inp.consume(end+2);
                                rb.machine.map(
                                    |m| m.bad_request(&mut resp, scope));
                                return Parser::bad_request(scope, resp);
                            }
                        }
                    }
                    BufferChunked(limit, off, _) => {
                        (rb.machine, Some(BufferChunked(limit, off, 0)))
                    }
                    ProgressiveFixed(hint, mut left) => {
                        let real_bytes = min(inp.len() as u64, left) as usize;
                        let m = rb.machine.and_then(
                            |m| m.request_chunk(
                                &inp[..real_bytes], &mut resp, scope));
                        inp.consume(real_bytes);
                        left -= real_bytes as u64;
                        if left == 0 {
                            let m = m.and_then(
                                |m| m.request_end(&mut resp, scope));
                            (m, None)
                        } else {
                            (m, Some(ProgressiveFixed(hint, left)))
                        }
                    }
                    ProgressiveEOF(_hint) => {
                        // TODO(tailhook) probably stream.eof should be impl
                        unimplemented!();
                    }
                    ProgressiveChunked(_hints, _left) => unimplemented!(),
                };
                match progress {
                    Some(p) => {
                        ReadingBody(ReadBody {
                            machine: m,
                            deadline: rb.deadline,
                            progress: p,
                            response: resp.internal(),
                        }).request(scope)
                    }
                    None => match m {
                        Some(m) => {
                            Some((Parser(Processing(
                                        m, resp.internal(), rb.deadline)),
                                 E::Sleep, rb.deadline))
                        }
                        None => {
                            assert!(resp.is_complete());
                            Idle.request(scope)
                        }
                    }
                }
            }
            // Spurious event?
            me @ DoneResponse => me.request(scope),
            Processing(m, r, dline) => Some((Parser(Processing(m, r, dline)),
                                             E::Sleep, dline)),
        }
    }
    fn bytes_flushed(self, _transport: &mut Transport<S>,
                     scope: &mut Scope<C>)
        -> Request<Self>
    {
        match self.0 {
            ParserImpl::DoneResponse => None,
            me => me.request(scope),
        }
    }
    fn timeout(self, _transport: &mut Transport<S>,
        _scope: &mut Scope<C>)
        -> Request<Self>
    {
        unimplemented!();
    }
    fn delimiter_not_found(self, _transport: &mut Transport<S>,
        scope: &mut Scope<C>)
        -> Request<Self>
    {
        use self::ParserImpl::*;
        use self::BodyProgress::*;
        // We may just flush and exit in every state. But:
        // 1. The match asserts that we know which state parser may be in
        // 2. We may send more specific response, so that browser will not
        //    retry ugly request multiple times
        match self.0 {
            ReadHeaders
                // TODO(tailhook) send RequestHeaderFieldsTooLarge
            | ReadingBody( ReadBody { progress: ProgressiveChunked(_, 0), ..})
            | ReadingBody( ReadBody { progress: BufferChunked(_, _, 0), ..})
                // TODO(tailhook) send BadRequest ?
            => {
                // Should we flush or just close?
                // Probably closing is useful because previous responses might
                // be absolutely valid, and we've got invalid pipelined
                // request
                Parser::flush(scope)
            }
            // TODO(tailhook) Any other weird cases?
            _ => unreachable!(),
        }
    }
    fn wakeup(self, _transport: &mut Transport<S>, scope: &mut Scope<C>)
        -> Request<Self>
    {
        use self::ParserImpl::*;
        match self.0 {
            me@Idle | me@ReadHeaders | me@DoneResponse => me.request(scope),
            ReadingBody(_reader) => {
                unimplemented!();
            }
            Processing(..) => {
                unimplemented!();
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

use std::sync::{Arc, RwLock};
use std::sync::mpsc::Sender;
use std::boxed::Box;
use std::net::{SocketAddr, IpAddr};
use std::str::FromStr;

use grpc::{Server as GrpcServer, ServerBuilder, Environment, ChannelBuilder};
use kvproto::tikvpb_grpc::*;
use util::worker::Worker;
use storage::Storage;
use raftstore::store::{SnapshotStatusMsg, SnapManager};

use super::{Result, Config};
use super::coprocessor::{EndPointHost, EndPointTask};
use super::grpc_service::Service;
use super::transport::{RaftStoreRouter, ServerTransport};
use super::resolve::StoreAddrResolver;
use super::snap::{Task as SnapTask, Runner as SnapHandler};
use super::raft_client::RaftClient;

const DEFAULT_COPROCESSOR_BATCH: usize = 50;
const MAX_GRPC_RECV_MSG_LEN: usize = 10 * 1024 * 1024;
const MAX_GRPC_SEND_MSG_LEN: usize = 128 * 1024 * 1024;

pub struct Server<T: RaftStoreRouter + 'static, S: StoreAddrResolver + 'static> {
    env: Arc<Environment>,
    // Grpc server.
    grpc_server: GrpcServer,
    local_addr: SocketAddr,
    // Transport.
    trans: ServerTransport<T, S>,
    raft_router: T,
    // The kv storage.
    storage: Storage,
    // For handling coprocessor requests.
    end_point_worker: Worker<EndPointTask>,
    // For sending/receiving snapshots.
    snap_mgr: SnapManager,
    snap_worker: Worker<SnapTask>,
}

impl<T: RaftStoreRouter, S: StoreAddrResolver + 'static> Server<T, S> {
    pub fn new(cfg: &Config,
               storage: Storage,
               raft_router: T,
               snapshot_status_sender: Sender<SnapshotStatusMsg>,
               resolver: S,
               snap_mgr: SnapManager)
               -> Result<Server<T, S>> {
        let env = Arc::new(Environment::new(cfg.grpc_concurrency));
        let raft_client = Arc::new(RwLock::new(RaftClient::new(env.clone(), cfg.clone())));
        let end_point_worker = Worker::new("end-point-worker");
        let snap_worker = Worker::new("snap-handler");

        let h = Service::new(storage.clone(),
                             end_point_worker.scheduler(),
                             raft_router.clone(),
                             snap_worker.scheduler());
        let addr = try!(SocketAddr::from_str(&cfg.addr));
        let ip = format!("{}", addr.ip());
        let channel_args = ChannelBuilder::new(env.clone())
            .stream_initial_window_size(cfg.grpc_stream_initial_window_size)
            .max_concurrent_stream(cfg.grpc_concurrent_stream)
            .max_receive_message_len(MAX_GRPC_RECV_MSG_LEN)
            .max_send_message_len(MAX_GRPC_SEND_MSG_LEN)
            .build_args();
        let grpc_server = try!(ServerBuilder::new(env.clone())
            .register_service(create_tikv(h))
            .bind(ip, addr.port())
            .channel_args(channel_args)
            .build());

        let addr = {
            let (ref host, port) = grpc_server.bind_addrs()[0];
            SocketAddr::new(try!(IpAddr::from_str(host)), port as u16)
        };

        let trans = ServerTransport::new(raft_client,
                                         snap_worker.scheduler(),
                                         raft_router.clone(),
                                         snapshot_status_sender,
                                         resolver);

        let svr = Server {
            env: env.clone(),
            grpc_server: grpc_server,
            local_addr: addr,
            trans: trans,
            raft_router: raft_router,
            storage: storage,
            end_point_worker: end_point_worker,
            snap_mgr: snap_mgr,
            snap_worker: snap_worker,
        };

        Ok(svr)
    }

    pub fn transport(&self) -> ServerTransport<T, S> {
        self.trans.clone()
    }

    pub fn start(&mut self, cfg: &Config) -> Result<()> {
        let end_point = EndPointHost::new(self.storage.get_engine(),
                                          self.end_point_worker.scheduler(),
                                          cfg.end_point_concurrency,
                                          cfg.end_point_txn_concurrency_on_busy,
                                          cfg.end_point_small_txn_tasks_limit);
        box_try!(self.end_point_worker.start_batch(end_point, DEFAULT_COPROCESSOR_BATCH));
        let snap_runner = SnapHandler::new(self.env.clone(),
                                           self.snap_mgr.clone(),
                                           self.raft_router.clone());
        box_try!(self.snap_worker.start(snap_runner));
        self.grpc_server.start();
        info!("TiKV is ready to serve");
        Ok(())
    }

    pub fn stop(&mut self) -> Result<()> {
        self.end_point_worker.stop();
        self.snap_worker.stop();
        if let Err(e) = self.storage.stop() {
            error!("failed to stop store: {:?}", e);
        }
        self.grpc_server.shutdown();
        Ok(())
    }

    // Return listening address, this may only be used for outer test
    // to get the real address because we may use "127.0.0.1:0"
    // in test to avoid port conflict.
    pub fn listening_addr(&self) -> SocketAddr {
        self.local_addr
    }
}

#[cfg(test)]
mod tests {
    use std::sync::{Arc, Mutex};
    use std::sync::mpsc::{self, Sender};
    use std::net::SocketAddr;
    use std::sync::atomic::{AtomicUsize, Ordering};

    use super::*;
    use super::super::{Result, Config};
    use super::super::transport::RaftStoreRouter;
    use super::super::resolve::{StoreAddrResolver, Callback as ResolveCallback};
    use storage::Storage;
    use kvproto::raft_serverpb::RaftMessage;
    use raftstore::Result as RaftStoreResult;
    use raftstore::store::Msg as StoreMsg;
    use raftstore::store::transport::Transport;

    struct MockResolver {
        addr: Arc<Mutex<Option<SocketAddr>>>,
    }

    impl StoreAddrResolver for MockResolver {
        fn resolve(&self, _: u64, cb: ResolveCallback) -> Result<()> {
            cb.call_box((self.addr.lock().unwrap().ok_or(box_err!("not set")),));
            Ok(())
        }
    }

    #[derive(Clone)]
    struct TestRaftStoreRouter {
        tx: Sender<usize>,
        report_unreachable_count: Arc<AtomicUsize>,
    }

    impl TestRaftStoreRouter {
        fn new(tx: Sender<usize>) -> TestRaftStoreRouter {
            TestRaftStoreRouter {
                tx: tx,
                report_unreachable_count: Arc::new(AtomicUsize::new(0)),
            }
        }
    }

    impl RaftStoreRouter for TestRaftStoreRouter {
        fn send(&self, _: StoreMsg) -> RaftStoreResult<()> {
            self.tx.send(1).unwrap();
            Ok(())
        }

        fn try_send(&self, _: StoreMsg) -> RaftStoreResult<()> {
            self.tx.send(1).unwrap();
            Ok(())
        }

        fn report_unreachable(&self, _: u64, _: u64, _: u64) -> RaftStoreResult<()> {
            let count = self.report_unreachable_count.clone();
            count.fetch_add(1, Ordering::SeqCst);
            Ok(())
        }
    }

    #[test]
    fn test_peer_resolve() {
        let mut cfg = Config::new();
        cfg.addr = "127.0.0.1:0".to_owned();

        let mut storage = Storage::new(&cfg.storage).unwrap();
        storage.start(&cfg.storage).unwrap();

        let (tx, rx) = mpsc::channel();
        let router = TestRaftStoreRouter::new(tx);
        let report_unreachable_count = router.report_unreachable_count.clone();
        let (snapshot_status_sender, _) = mpsc::channel();

        let addr = Arc::new(Mutex::new(None));
        let mut server =
            Server::new(&cfg,
                        storage,
                        router,
                        snapshot_status_sender,
                        MockResolver { addr: addr.clone() },
                        SnapManager::new("", None, cfg.raft_store.use_sst_file_snapshot))
                .unwrap();
        *addr.lock().unwrap() = Some(server.listening_addr());

        server.start(&cfg).unwrap();

        let trans = server.transport();
        for i in 0..10 {
            if i % 2 == 1 {
                trans.report_unreachable(RaftMessage::new());
            }
            assert_eq!(report_unreachable_count.load(Ordering::SeqCst), (i + 1) / 2);
        }
        let mut msg = RaftMessage::new();
        msg.set_region_id(1);
        trans.send(msg).unwrap();
        rx.recv().unwrap();
        server.stop().unwrap();
    }
}
<commit_msg>server/server: avoid test case hanging (#1946)<commit_after>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

use std::sync::{Arc, RwLock};
use std::sync::mpsc::Sender;
use std::boxed::Box;
use std::net::{SocketAddr, IpAddr};
use std::str::FromStr;

use grpc::{Server as GrpcServer, ServerBuilder, Environment, ChannelBuilder};
use kvproto::tikvpb_grpc::*;
use util::worker::Worker;
use storage::Storage;
use raftstore::store::{SnapshotStatusMsg, SnapManager};

use super::{Result, Config};
use super::coprocessor::{EndPointHost, EndPointTask};
use super::grpc_service::Service;
use super::transport::{RaftStoreRouter, ServerTransport};
use super::resolve::StoreAddrResolver;
use super::snap::{Task as SnapTask, Runner as SnapHandler};
use super::raft_client::RaftClient;

const DEFAULT_COPROCESSOR_BATCH: usize = 50;
const MAX_GRPC_RECV_MSG_LEN: usize = 10 * 1024 * 1024;
const MAX_GRPC_SEND_MSG_LEN: usize = 128 * 1024 * 1024;

pub struct Server<T: RaftStoreRouter + 'static, S: StoreAddrResolver + 'static> {
    env: Arc<Environment>,
    // Grpc server.
    grpc_server: GrpcServer,
    local_addr: SocketAddr,
    // Transport.
    trans: ServerTransport<T, S>,
    raft_router: T,
    // The kv storage.
    storage: Storage,
    // For handling coprocessor requests.
    end_point_worker: Worker<EndPointTask>,
    // For sending/receiving snapshots.
    snap_mgr: SnapManager,
    snap_worker: Worker<SnapTask>,
}

impl<T: RaftStoreRouter, S: StoreAddrResolver + 'static> Server<T, S> {
    pub fn new(cfg: &Config,
               storage: Storage,
               raft_router: T,
               snapshot_status_sender: Sender<SnapshotStatusMsg>,
               resolver: S,
               snap_mgr: SnapManager)
               -> Result<Server<T, S>> {
        let env = Arc::new(Environment::new(cfg.grpc_concurrency));
        let raft_client = Arc::new(RwLock::new(RaftClient::new(env.clone(), cfg.clone())));
        let end_point_worker = Worker::new("end-point-worker");
        let snap_worker = Worker::new("snap-handler");

        let h = Service::new(storage.clone(),
                             end_point_worker.scheduler(),
                             raft_router.clone(),
                             snap_worker.scheduler());
        let addr = try!(SocketAddr::from_str(&cfg.addr));
        let ip = format!("{}", addr.ip());
        let channel_args = ChannelBuilder::new(env.clone())
            .stream_initial_window_size(cfg.grpc_stream_initial_window_size)
            .max_concurrent_stream(cfg.grpc_concurrent_stream)
            .max_receive_message_len(MAX_GRPC_RECV_MSG_LEN)
            .max_send_message_len(MAX_GRPC_SEND_MSG_LEN)
            .build_args();
        let grpc_server = try!(ServerBuilder::new(env.clone())
            .register_service(create_tikv(h))
            .bind(ip, addr.port())
            .channel_args(channel_args)
            .build());

        let addr = {
            let (ref host, port) = grpc_server.bind_addrs()[0];
            SocketAddr::new(try!(IpAddr::from_str(host)), port as u16)
        };

        let trans = ServerTransport::new(raft_client,
                                         snap_worker.scheduler(),
                                         raft_router.clone(),
                                         snapshot_status_sender,
                                         resolver);

        let svr = Server {
            env: env.clone(),
            grpc_server: grpc_server,
            local_addr: addr,
            trans: trans,
            raft_router: raft_router,
            storage: storage,
            end_point_worker: end_point_worker,
            snap_mgr: snap_mgr,
            snap_worker: snap_worker,
        };

        Ok(svr)
    }

    pub fn transport(&self) -> ServerTransport<T, S> {
        self.trans.clone()
    }

    pub fn start(&mut self, cfg: &Config) -> Result<()> {
        let end_point = EndPointHost::new(self.storage.get_engine(),
                                          self.end_point_worker.scheduler(),
                                          cfg.end_point_concurrency,
                                          cfg.end_point_txn_concurrency_on_busy,
                                          cfg.end_point_small_txn_tasks_limit);
        box_try!(self.end_point_worker.start_batch(end_point, DEFAULT_COPROCESSOR_BATCH));
        let snap_runner = SnapHandler::new(self.env.clone(),
                                           self.snap_mgr.clone(),
                                           self.raft_router.clone());
        box_try!(self.snap_worker.start(snap_runner));
        self.grpc_server.start();
        info!("TiKV is ready to serve");
        Ok(())
    }

    pub fn stop(&mut self) -> Result<()> {
        self.end_point_worker.stop();
        self.snap_worker.stop();
        if let Err(e) = self.storage.stop() {
            error!("failed to stop store: {:?}", e);
        }
        self.grpc_server.shutdown();
        Ok(())
    }

    // Return listening address, this may only be used for outer test
    // to get the real address because we may use "127.0.0.1:0"
    // in test to avoid port conflict.
    pub fn listening_addr(&self) -> SocketAddr {
        self.local_addr
    }
}

#[cfg(test)]
mod tests {
    use std::time::Duration;
    use std::sync::{Arc, Mutex};
    use std::sync::mpsc::{self, Sender};
    use std::net::SocketAddr;
    use std::sync::atomic::{AtomicUsize, Ordering};

    use super::*;
    use super::super::{Result, Config};
    use super::super::transport::RaftStoreRouter;
    use super::super::resolve::{StoreAddrResolver, Callback as ResolveCallback};
    use storage::Storage;
    use kvproto::raft_serverpb::RaftMessage;
    use raftstore::Result as RaftStoreResult;
    use raftstore::store::Msg as StoreMsg;
    use raftstore::store::transport::Transport;

    struct MockResolver {
        addr: Arc<Mutex<Option<SocketAddr>>>,
    }

    impl StoreAddrResolver for MockResolver {
        fn resolve(&self, _: u64, cb: ResolveCallback) -> Result<()> {
            cb.call_box((self.addr.lock().unwrap().ok_or(box_err!("not set")),));
            Ok(())
        }
    }

    #[derive(Clone)]
    struct TestRaftStoreRouter {
        tx: Sender<usize>,
        report_unreachable_count: Arc<AtomicUsize>,
    }

    impl TestRaftStoreRouter {
        fn new(tx: Sender<usize>) -> TestRaftStoreRouter {
            TestRaftStoreRouter {
                tx: tx,
                report_unreachable_count: Arc::new(AtomicUsize::new(0)),
            }
        }
    }

    impl RaftStoreRouter for TestRaftStoreRouter {
        fn send(&self, _: StoreMsg) -> RaftStoreResult<()> {
            self.tx.send(1).unwrap();
            Ok(())
        }

        fn try_send(&self, _: StoreMsg) -> RaftStoreResult<()> {
            self.tx.send(1).unwrap();
            Ok(())
        }

        fn report_unreachable(&self, _: u64, _: u64, _: u64) -> RaftStoreResult<()> {
            let count = self.report_unreachable_count.clone();
            count.fetch_add(1, Ordering::SeqCst);
            Ok(())
        }
    }

    #[test]
    fn test_peer_resolve() {
        let mut cfg = Config::new();
        cfg.addr = "127.0.0.1:0".to_owned();

        let mut storage = Storage::new(&cfg.storage).unwrap();
        storage.start(&cfg.storage).unwrap();

        let (tx, rx) = mpsc::channel();
        let router = TestRaftStoreRouter::new(tx);
        let report_unreachable_count = router.report_unreachable_count.clone();
        let (snapshot_status_sender, _) = mpsc::channel();

        let addr = Arc::new(Mutex::new(None));
        let mut server =
            Server::new(&cfg,
                        storage,
                        router,
                        snapshot_status_sender,
                        MockResolver { addr: addr.clone() },
                        SnapManager::new("", None, cfg.raft_store.use_sst_file_snapshot))
                .unwrap();
        *addr.lock().unwrap() = Some(server.listening_addr());

        server.start(&cfg).unwrap();

        let trans = server.transport();
        for i in 0..10 {
            if i % 2 == 1 {
                trans.report_unreachable(RaftMessage::new());
            }
            assert_eq!(report_unreachable_count.load(Ordering::SeqCst), (i + 1) / 2);
        }
        let mut msg = RaftMessage::new();
        msg.set_region_id(1);
        trans.send(msg).unwrap();
        assert!(rx.recv_timeout(Duration::from_secs(5)).is_ok());
        server.stop().unwrap();
    }
}
<|endoftext|>


<commit_before>use std::num;

pub trait Addressable<ADDR: Int> {
	pub fn get (&self, addr: ADDR) -> u8;
	pub fn set (&mut self, addr: ADDR, data: u8);
}

// FIXME: With default methods, we won't need this anymore
pub trait AddressableUtil<ADDR: Int> {
	pub fn getx (&self, addr:ADDR, offset: int) -> u8;
	pub fn get_be<T: Int> (&self, addr: ADDR) -> T;
	pub fn get_le<T: Int> (&self, addr: ADDR) -> T;

	pub fn setx (&mut self, addr: ADDR, offset: int, data: u8);
	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T);
	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T);
}

impl<ADDR: Int, A: Addressable<ADDR>> AddressableUtil<ADDR> for A {
	pub fn getx (&self, addr:ADDR, offset: int) -> u8 {
		self.get(addr + num::cast(offset))
	}

	pub fn get_be<T: Int> (&self, addr: ADDR) -> T {
		let count = num::Primitive::bytes::<T>();
		let mut val = num::Zero::zero::<T>();
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast((count-i-1) * num::Primitive::bits::<u8>());
			let d: T = num::cast(self.get(addr + num::cast(i)));
			val = val + (d << shift);
		}
		val
	}

	pub fn get_le<T: Int> (&self, addr: ADDR) -> T {
		let count = num::Primitive::bytes::<T>();
		let mut val = num::Zero::zero::<T>();
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast(i * num::Primitive::bits::<u8>());
			let d: T = num::cast(self.get(addr + num::cast(i)));
			val = val + (d << shift);
		}
		val
	}

	pub fn setx (&mut self, addr: ADDR, offset: int, data: u8) {
		self.set(addr + num::cast(offset), data);
	}

	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T) {
		let count = num::Primitive::bytes::<T>();
		let mask = (1 << num::Primitive::bits::<u8>()) - 1;
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast((count-i-1) * num::Primitive::bits::<u8>());
			let d: u8 = num::cast((val >> shift) & num::cast(mask));
			self.set(addr + num::cast(i), d);
		}
	}

	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T) {
		let count = num::Primitive::bytes::<T>();
		let mask = (1 << num::Primitive::bits::<u8>()) - 1;
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast(i * num::Primitive::bits::<u8>());
			let d: u8 = num::cast((val >> shift) & num::cast(mask));
			self.set(addr + num::cast(i), d);
		}
	}
}

#[cfg(test)]
mod tests {
	use super::*;

	struct DummyData;
	impl Addressable<u16> for DummyData {
		pub fn get (&self, addr: u16) -> u8 {
			addr as u8
		}
		pub fn set (&mut self, addr: u16, data: u8) {
			assert_eq!(data, addr as u8);
		}
	}

	#[test]
	fn test_get () {
		let data = DummyData;
		assert_eq!(data.get(0x0012), 0x12);
		assert_eq!(data.get(0x1234), 0x34);
	}

	#[test]
	fn test_getx () {
		let data = DummyData;
		assert_eq!(data.getx(0x0012_u16, 5), 0x17);
		assert_eq!(data.getx(0x1234_u16, 5), 0x39);
	}

	#[test]
	fn test_get_big_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_be(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_be(0x0054_u16));
		assert_eq!(    0x0203_u16, data.get_be(0x0002_u16));
		assert_eq!(    0x5455_u16, data.get_be(0x0054_u16));
		assert_eq!(0x02030405_u32, data.get_be(0x0002_u16));
		assert_eq!(0x54555657_u32, data.get_be(0x0054_u16));
	}

	#[test]
	fn test_get_little_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_le(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_le(0x0054_u16));
		assert_eq!(    0x0302_u16, data.get_le(0x0002_u16));
		assert_eq!(    0x5554_u16, data.get_le(0x0054_u16));
		assert_eq!(0x05040302_u32, data.get_le(0x0002_u16));
		assert_eq!(0x57565554_u32, data.get_le(0x0054_u16));
	}

	#[test]
	fn test_set () {
		let mut data = DummyData;
		data.set(0x0012, 0x12);
		data.set(0x1234, 0x34);
	}

	#[test]
	fn test_setx () {
		let mut data = DummyData;
		data.setx(0x0012_u16, 5, 0x17);
		data.setx(0x1234_u16, 5, 0x39);
	}

	#[test]
	fn test_set_big_endian () {
		let mut data = DummyData;
		data.set_be(0x0002_u16, 0x02_u8);
		data.set_be(0x0054_u16, 0x54_u8);
		data.set_be(0x0002_u16, 0x0203_u16);
		data.set_be(0x0054_u16, 0x5455_u16);
		data.set_be(0x0002_u16, 0x02030405_u32);
		data.set_be(0x0054_u16, 0x54555657_u32);
	}

	#[test]
	fn test_set_little_endian () {
		let mut data = DummyData;
		data.set_le(0x0002_u16, 0x02_u8);
		data.set_le(0x0054_u16, 0x54_u8);
		data.set_le(0x0002_u16, 0x0302_u16);
		data.set_le(0x0054_u16, 0x5554_u16);
		data.set_le(0x0002_u16, 0x05040302_u32);
		data.set_le(0x0054_u16, 0x57565554_u32);
	}
}
<commit_msg>Refactored endianess aware methods in addressable trait<commit_after>use std::num;

pub trait Addressable<ADDR: Int> {
	pub fn get (&self, addr: ADDR) -> u8;
	pub fn set (&mut self, addr: ADDR, data: u8);
}

// FIXME: With default methods, we won't need this anymore
pub trait AddressableUtil<ADDR: Int> {
	pub fn getx (&self, addr:ADDR, offset: int) -> u8;
	pub fn get_be_n (&self, addr: ADDR, nbytes: uint) -> u64;
	pub fn get_be<T: Int> (&self, addr: ADDR) -> T;
	pub fn get_le_n (&self, addr: ADDR, nbytes: uint) -> u64;
	pub fn get_le<T: Int> (&self, addr: ADDR) -> T;

	pub fn setx (&mut self, addr: ADDR, offset: int, data: u8);
	pub fn set_be_n (&mut self, addr: ADDR, nbytes: uint, val: u64);
	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T);
	pub fn set_le_n (&mut self, addr: ADDR, nbytes: uint, val: u64);
	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T);
}

impl<ADDR: Int+Copy, A: Addressable<ADDR>> AddressableUtil<ADDR> for A {
	pub fn getx (&self, addr:ADDR, offset: int) -> u8 {
		self.get(addr + num::cast(offset))
	}

	pub fn get_be_n (&self, addr: ADDR, nbytes: uint) -> u64 {
		assert!(nbytes > 0 && nbytes < 8);
		let mut val = 0u64;
		let mut i = nbytes;
		while i > 0 {
			i -= 1;
			val |= self.get(addr + num::cast(i)) as u64 << (nbytes-i-1) * 8;
		}
		val
	}

	pub fn get_be<T: Int> (&self, addr: ADDR) -> T {
		num::cast(self.get_be_n(addr, num::Primitive::bytes::<T>()))
	}

	pub fn get_le_n (&self, addr: ADDR, nbytes: uint) -> u64 {
		assert!(nbytes > 0 && nbytes < 8);
		let mut val = 0u64;
		let mut i = nbytes;
		while i > 0 {
			i -= 1;
			val |= self.get(addr + num::cast(i)) as u64 << i * 8;
		}
		val
	}

	pub fn get_le<T: Int> (&self, addr: ADDR) -> T {
		num::cast(self.get_le_n(addr, num::Primitive::bytes::<T>()))
	}

	pub fn setx (&mut self, addr: ADDR, offset: int, data: u8) {
		self.set(addr + num::cast(offset), data);
	}

	pub fn set_be_n (&mut self, addr: ADDR, nbytes: uint, val: u64) {
		assert!(nbytes > 0 && nbytes < 8);
		let mut i = nbytes;
		while i > 0 {
			i -= 1;
			self.set(addr + num::cast(i), (val >> (nbytes-i-1) * 8) as u8);
		}
	}

	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T) {
		self.set_be_n(addr, num::Primitive::bytes::<T>(), num::cast(val));
	}

	pub fn set_le_n (&mut self, addr: ADDR, nbytes: uint, val: u64) {
		assert!(nbytes > 0 && nbytes < 8);
		let mut i = nbytes;
		while i > 0 {
			i -= 1;
			self.set(addr + num::cast(i), (val >> i * 8) as u8);
		}
	}

	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T) {
		self.set_le_n(addr, num::Primitive::bytes::<T>(), num::cast(val));
	}
}

#[cfg(test)]
mod tests {
	use super::*;

	struct DummyData;
	impl Addressable<u16> for DummyData {
		pub fn get (&self, addr: u16) -> u8 {
			addr as u8
		}
		pub fn set (&mut self, addr: u16, data: u8) {
			assert_eq!(data, addr as u8);
		}
	}

	#[test]
	fn test_get () {
		let data = DummyData;
		assert_eq!(data.get(0x0012), 0x12);
		assert_eq!(data.get(0x1234), 0x34);
	}

	#[test]
	fn test_getx () {
		let data = DummyData;
		assert_eq!(data.getx(0x0012_u16, 5), 0x17);
		assert_eq!(data.getx(0x1234_u16, 5), 0x39);
	}

	#[test]
	fn test_get_big_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_be(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_be(0x0054_u16));
		assert_eq!(    0x0203_u16, data.get_be(0x0002_u16));
		assert_eq!(    0x5455_u16, data.get_be(0x0054_u16));
		assert_eq!(0x02030405_u32, data.get_be(0x0002_u16));
		assert_eq!(0x54555657_u32, data.get_be(0x0054_u16));
	}

	#[test]
	fn test_get_little_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_le(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_le(0x0054_u16));
		assert_eq!(    0x0302_u16, data.get_le(0x0002_u16));
		assert_eq!(    0x5554_u16, data.get_le(0x0054_u16));
		assert_eq!(0x05040302_u32, data.get_le(0x0002_u16));
		assert_eq!(0x57565554_u32, data.get_le(0x0054_u16));
	}

	#[test]
	fn test_set () {
		let mut data = DummyData;
		data.set(0x0012, 0x12);
		data.set(0x1234, 0x34);
	}

	#[test]
	fn test_setx () {
		let mut data = DummyData;
		data.setx(0x0012_u16, 5, 0x17);
		data.setx(0x1234_u16, 5, 0x39);
	}

	#[test]
	fn test_set_big_endian () {
		let mut data = DummyData;
		data.set_be(0x0002_u16, 0x02_u8);
		data.set_be(0x0054_u16, 0x54_u8);
		data.set_be(0x0002_u16, 0x0203_u16);
		data.set_be(0x0054_u16, 0x5455_u16);
		data.set_be(0x0002_u16, 0x02030405_u32);
		data.set_be(0x0054_u16, 0x54555657_u32);
	}

	#[test]
	fn test_set_little_endian () {
		let mut data = DummyData;
		data.set_le(0x0002_u16, 0x02_u8);
		data.set_le(0x0054_u16, 0x54_u8);
		data.set_le(0x0002_u16, 0x0302_u16);
		data.set_le(0x0054_u16, 0x5554_u16);
		data.set_le(0x0002_u16, 0x05040302_u32);
		data.set_le(0x0054_u16, 0x57565554_u32);
	}
}
<|endoftext|>


<commit_before>extern crate libnewsboat;

use std::env;

struct EnvVariable{
    name: String,
    value: String,
    was_set: bool,
}

impl EnvVariable {

    fn new(name:String) -> EnvVariable {
        match env::var(&name) {
            Ok(val) => EnvVariable{
                name:name,
                value:val,
                was_set:true,
            },
            Err(_) => EnvVariable{
                name:name,
                value:String::new(),
                was_set:false,
            },
        }
    }

    fn set(&self,new_value:&String) {
        env::set_var(&self.name, new_value)
    }

    fn unset(&self) {
        env::remove_var(&self.name)
    }
}

impl Drop for EnvVariable {

    fn drop(&mut self){
        if self.was_set {
            env::set_var(&self.name,&self.value);
        }
    }
}

#[test]
fn t_get_default_browser() {
    use libnewsboat::utils;
    let key = String::from("BROWSER");
    let firefox = String::from("firefox");
    let opera = String::from("opera");

    let env_var = EnvVariable::new(key);
    env_var.unset();
    assert_eq!(utils::get_default_browser(),String::from("lynx"));

    env_var.set(&firefox);
    assert_eq!(utils::get_default_browser(), firefox);
    env_var.set(&opera);
    assert_eq!(utils::get_default_browser(), opera);
}<commit_msg>EnvVariable removed<commit_after>extern crate libnewsboat;

#[test]
fn t_get_default_browser() {
    use libnewsboat::utils;
    use std::env;

    let key = String::from("BROWSER");
    let firefox = String::from("firefox");
    let opera = String::from("opera");
    let lynx = String::from("lynx");

    env::remove_var(&key);
    assert_eq!(utils::get_default_browser(),lynx);

    env::set_var(&key, &firefox);
    assert_eq!(utils::get_default_browser(), firefox);
    env::set_var(&key, &opera);
    assert_eq!(utils::get_default_browser(), opera);
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::io::{self, Write};
use std::net::Shutdown;
use std::rc::Rc;
use mio::Token;
use mio::net::TcpStream;
use mio::{Event, PollOpt, Ready};

use super::binary;
use super::close_listener::CloseListener;
use super::ipv4_packet::MAX_PACKET_LENGTH;
use super::ipv4_packet_buffer::IPv4PacketBuffer;
use super::selector::Selector;
use super::stream_buffer::StreamBuffer;

const TAG: &'static str = "Client";

pub struct Client {
    id: u32,
    stream: TcpStream,
    client_to_network: IPv4PacketBuffer,
    network_to_client: StreamBuffer,
    closed: bool,
    close_listener: Box<CloseListener<Client>>,
    token: Token,
    // number of remaining bytes of "id" to send to the client before relaying any data
    pending_id_bytes: usize,
}

impl Client {
    pub fn new<C>(id: u32, selector: &mut Selector, stream: TcpStream, close_listener: C) -> io::Result<Rc<RefCell<Self>>>
            where C: CloseListener<Client> + 'static {
        let rc = Rc::new(RefCell::new(Self {
            id: id,
            stream: stream,
            client_to_network: IPv4PacketBuffer::new(),
            network_to_client: StreamBuffer::new(16 * MAX_PACKET_LENGTH),
            closed: false,
            close_listener: Box::new(close_listener),
            token: Token(0), // default value, will be set afterwards
            pending_id_bytes: 4,
        }));
        let rc_clone = rc.clone();
        let handler = move |selector: &mut Selector, ready| {
            let mut self_ref = rc_clone.borrow_mut();
            self_ref.on_ready(selector, ready);
        };
        {
            let mut self_ref = rc.borrow_mut();
            // on start, we are interested only in writing (we must first send the client id)
            let token = selector.register(&self_ref.stream, handler, Ready::writable(), PollOpt::level())?;
            self_ref.token = token;
        }
        Ok(rc)
    }

    pub fn get_id(&self) -> u32 {
        return self.id;
    }

    fn close(&mut self, selector: &mut Selector) {
        self.closed = true;
        selector.deregister(&self.stream, self.token);
        // shutdown only (there is no close), the socket will be closed on drop
        self.stream.shutdown(Shutdown::Both);
        // TODO router.clear();
        self.close_listener.on_closed(self);
    }

    fn process_send(&mut self, selector: &mut Selector) {
        if self.must_send_id() {
            match self.send_id() {
                Ok(_) => {
                    if self.pending_id_bytes == 0 {
                        debug!("Client id #{} sent to client", self.id);
                    }
                }
                Err(_) => {
                    error!(target: TAG, "Cannot write client id #{}", self.id);
                    self.close(selector);
                }
            }
        } else {
            match self.write() {
                Ok(_) => self.process_pending(),
                Err(_) => {
                    error!(target: TAG, "Cannot write");
                    self.close(selector);
                }
            }
        }
    }

    fn process_receive(&mut self, selector: &mut Selector) {
        match self.read() {
            Ok(_) => self.push_to_network(selector),
            Err(_) => {
                error!(target: TAG, "Cannot read");
                self.close(selector);
            }
        }
    }

    fn send_id(&mut self) -> io::Result<()> {
        assert!(self.must_send_id());
        let raw_id = binary::to_byte_array(self.id);
        let w = self.stream.write(&raw_id[4 - self.pending_id_bytes..])?;
        self.pending_id_bytes -= w;
        Ok(())
    }

    fn update_interests(&mut self, selector: &mut Selector) -> io::Result<()> {
        let ready = if self.network_to_client.is_empty() {
            Ready::readable()
        } else {
            Ready::readable() | Ready::writable()
        };
        selector.reregister(&self.stream, self.token, ready, PollOpt::level())
    }

    fn read(&mut self) -> io::Result<()> {
        self.client_to_network.read_from(&mut self.stream)
    }

    fn write(&mut self) -> io::Result<()> {
        self.network_to_client.write_to(&mut self.stream)?;
        Ok(())
    }

    fn push_to_network(&mut self, selector: &mut Selector) {
        while self.push_one_packet_to_network(selector) {
            self.client_to_network.next();
        }
    }

    fn push_one_packet_to_network(&mut self, selector: &mut Selector) -> bool {
        match self.client_to_network.as_ipv4_packet() {
            Some(ref packet) => {
                // router.send_to_network(packet);
                true
            },
            None => false
        }
    }

    fn on_ready(&mut self, selector: &mut Selector, event: Event) {
        assert!(!self.closed);
        let ready = event.readiness();
        if ready.is_writable() {
            self.process_send(selector);
        }
        if !self.closed && ready.is_readable() {
            self.process_receive(selector);
        }
        if !self.closed {
            self.update_interests(selector);
        }
    }

    fn process_pending(&mut self) {
        // TODO
    }

    fn clean_expired_connections() {
        // TODO
    }

    fn must_send_id(&self) -> bool{
        self.pending_id_bytes > 0
    }
}
<commit_msg>Remove useless ","<commit_after>use std::cell::RefCell;
use std::io::{self, Write};
use std::net::Shutdown;
use std::rc::Rc;
use mio::Token;
use mio::net::TcpStream;
use mio::{Event, PollOpt, Ready};

use super::binary;
use super::close_listener::CloseListener;
use super::ipv4_packet::MAX_PACKET_LENGTH;
use super::ipv4_packet_buffer::IPv4PacketBuffer;
use super::selector::Selector;
use super::stream_buffer::StreamBuffer;

const TAG: &'static str = "Client";

pub struct Client {
    id: u32,
    stream: TcpStream,
    client_to_network: IPv4PacketBuffer,
    network_to_client: StreamBuffer,
    closed: bool,
    close_listener: Box<CloseListener<Client>>,
    token: Token,
    // number of remaining bytes of "id" to send to the client before relaying any data
    pending_id_bytes: usize,
}

impl Client {
    pub fn new<C>(id: u32, selector: &mut Selector, stream: TcpStream, close_listener: C) -> io::Result<Rc<RefCell<Self>>>
            where C: CloseListener<Client> + 'static {
        let rc = Rc::new(RefCell::new(Self {
            id: id,
            stream: stream,
            client_to_network: IPv4PacketBuffer::new(),
            network_to_client: StreamBuffer::new(16 * MAX_PACKET_LENGTH),
            closed: false,
            close_listener: Box::new(close_listener),
            token: Token(0), // default value, will be set afterwards
            pending_id_bytes: 4,
        }));
        let rc_clone = rc.clone();
        let handler = move |selector: &mut Selector, ready| {
            let mut self_ref = rc_clone.borrow_mut();
            self_ref.on_ready(selector, ready);
        };
        {
            let mut self_ref = rc.borrow_mut();
            // on start, we are interested only in writing (we must first send the client id)
            let token = selector.register(&self_ref.stream, handler, Ready::writable(), PollOpt::level())?;
            self_ref.token = token;
        }
        Ok(rc)
    }

    pub fn get_id(&self) -> u32 {
        return self.id;
    }

    fn close(&mut self, selector: &mut Selector) {
        self.closed = true;
        selector.deregister(&self.stream, self.token);
        // shutdown only (there is no close), the socket will be closed on drop
        self.stream.shutdown(Shutdown::Both);
        // TODO router.clear();
        self.close_listener.on_closed(self);
    }

    fn process_send(&mut self, selector: &mut Selector) {
        if self.must_send_id() {
            match self.send_id() {
                Ok(_) => {
                    if self.pending_id_bytes == 0 {
                        debug!("Client id #{} sent to client", self.id);
                    }
                }
                Err(_) => {
                    error!(target: TAG, "Cannot write client id #{}", self.id);
                    self.close(selector);
                }
            }
        } else {
            match self.write() {
                Ok(_) => self.process_pending(),
                Err(_) => {
                    error!(target: TAG, "Cannot write");
                    self.close(selector);
                }
            }
        }
    }

    fn process_receive(&mut self, selector: &mut Selector) {
        match self.read() {
            Ok(_) => self.push_to_network(selector),
            Err(_) => {
                error!(target: TAG, "Cannot read");
                self.close(selector);
            }
        }
    }

    fn send_id(&mut self) -> io::Result<()> {
        assert!(self.must_send_id());
        let raw_id = binary::to_byte_array(self.id);
        let w = self.stream.write(&raw_id[4 - self.pending_id_bytes..])?;
        self.pending_id_bytes -= w;
        Ok(())
    }

    fn update_interests(&mut self, selector: &mut Selector) -> io::Result<()> {
        let ready = if self.network_to_client.is_empty() {
            Ready::readable()
        } else {
            Ready::readable() | Ready::writable()
        };
        selector.reregister(&self.stream, self.token, ready, PollOpt::level())
    }

    fn read(&mut self) -> io::Result<()> {
        self.client_to_network.read_from(&mut self.stream)
    }

    fn write(&mut self) -> io::Result<()> {
        self.network_to_client.write_to(&mut self.stream)?;
        Ok(())
    }

    fn push_to_network(&mut self, selector: &mut Selector) {
        while self.push_one_packet_to_network(selector) {
            self.client_to_network.next();
        }
    }

    fn push_one_packet_to_network(&mut self, selector: &mut Selector) -> bool {
        match self.client_to_network.as_ipv4_packet() {
            Some(ref packet) => {
                // router.send_to_network(packet);
                true
            }
            None => false
        }
    }

    fn on_ready(&mut self, selector: &mut Selector, event: Event) {
        assert!(!self.closed);
        let ready = event.readiness();
        if ready.is_writable() {
            self.process_send(selector);
        }
        if !self.closed && ready.is_readable() {
            self.process_receive(selector);
        }
        if !self.closed {
            self.update_interests(selector);
        }
    }

    fn process_pending(&mut self) {
        // TODO
    }

    fn clean_expired_connections() {
        // TODO
    }

    fn must_send_id(&self) -> bool{
        self.pending_id_bytes > 0
    }
}
<|endoftext|>


<commit_before>#![feature(test)] extern crate test;
extern crate bk_tree;
extern crate rand;

use bk_tree::BKTree;
use bk_tree::metrics::levenshtein;
use test::Bencher;
use rand::{thread_rng, Rng};

fn make_words<R: Rng>(rng: &mut R, n: i32) -> Vec<String> {
    let mut words: Vec<String> = Vec::new();
    for _ in 1..n {
        let l = rng.gen_range(4, 12);
        let s: String = rng.gen_ascii_chars().take(l).collect();
        words.push(s);
    }
    words
}

#[bench]
fn bench_find_exact(b: &mut Bencher) {
    let mut tree: BKTree<String> = BKTree::new(levenshtein);
    let words = make_words(&mut thread_rng(), 1000);
    tree.extend(words.clone());
    let word = words.last().unwrap();

    b.iter(move || {
        tree.find_exact(word.clone())
    });
}

#[bench]
fn bench_find_tol_one(b: &mut Bencher) {
    let mut tree: BKTree<String> = BKTree::new(levenshtein);
    let words = make_words(&mut thread_rng(), 1000);
    tree.extend(words.clone());
    let word = words.last().unwrap();

    b.iter(move || {
        tree.find(word.clone(), 1)
    });
}

#[bench]
fn bench_find_tol_two(b: &mut Bencher) {
    let mut tree: BKTree<String> = BKTree::new(levenshtein);
    let words = make_words(&mut thread_rng(), 1000);
    tree.extend(words.clone());
    let word = words.last().unwrap();

    b.iter(move || {
        tree.find(word.clone(), 2)
    });
}

#[bench]
fn bench_add(b: &mut Bencher) {
    let words = make_words(&mut thread_rng(), 1000);

    b.iter(move || {
        let mut tree: BKTree<String> = BKTree::new(levenshtein);
        for word in words.clone() {
            tree.add(word);
        }
    });
}

#[bench]
fn bench_extend(b: &mut Bencher) {
    let words = make_words(&mut thread_rng(), 1000);

    b.iter(move || {
        let mut tree: BKTree<String> = BKTree::new(levenshtein);
        tree.extend(words.clone());
    });
}
<commit_msg>Get benchmarks building again<commit_after>#![feature(test)] extern crate test;
extern crate bk_tree;
extern crate rand;

use bk_tree::BKTree;
use bk_tree::metrics::Levenshtein;
use test::Bencher;
use rand::{thread_rng, Rng};

fn make_words<R: Rng>(rng: &mut R, n: i32) -> Vec<String> {
    let mut words: Vec<String> = Vec::new();
    for _ in 1..n {
        let l = rng.gen_range(4, 12);
        let s: String = rng.gen_ascii_chars().take(l).collect();
        words.push(s);
    }
    words
}

#[bench]
fn bench_find_exact(b: &mut Bencher) {
    let mut tree: BKTree<String> = BKTree::new(Levenshtein);
    let words = make_words(&mut thread_rng(), 1000);
    let word = words.last().unwrap().clone();
    tree.extend(words);

    b.iter(|| {
        tree.find_exact(&word)
    });
}

#[bench]
fn bench_find_tol_one(b: &mut Bencher) {
    let mut tree: BKTree<String> = BKTree::new(Levenshtein);
    let words = make_words(&mut thread_rng(), 1000);
    let word = words.last().unwrap().clone();
    tree.extend(words);

    b.iter(|| {
        tree.find(&word, 1)
    });
}

#[bench]
fn bench_find_tol_two(b: &mut Bencher) {
    let mut tree: BKTree<String> = BKTree::new(Levenshtein);
    let words = make_words(&mut thread_rng(), 1000);
    let word = words.last().unwrap().clone();
    tree.extend(words);

    b.iter(|| {
        tree.find(&word, 2)
    });
}

#[bench]
fn bench_add(b: &mut Bencher) {
    let words = make_words(&mut thread_rng(), 1000);

    b.iter(move || {
        let mut tree: BKTree<String> = BKTree::new(Levenshtein);
        for word in words.clone() {
            tree.add(word);
        }
    });
}

#[bench]
fn bench_extend(b: &mut Bencher) {
    let words = make_words(&mut thread_rng(), 1000);

    b.iter(move || {
        let mut tree: BKTree<String> = BKTree::new(Levenshtein);
        tree.extend(words.clone());
    });
}
<|endoftext|>


<commit_before>extern crate iron;
extern crate postgres;
extern crate iron_postgres_middleware as pg_middleware;

use iron::prelude::*;
use iron::status;
use pg_middleware::{PostgresMiddleware, PostgresReqExt};

fn main() {
    let mut chain = Chain::new(name_list);

    let pg_middleware = PostgresMiddleware::new("postgres://postgres@localhost/example");

    {
        let conn = pg_middleware.pool.get().unwrap();
        conn.execute(
            "CREATE TABLE IF NOT EXISTS names (
                id SERIAL PRIMARY KEY,
                name VARCHAR(255) NOT NULL
            )",
        &[]).unwrap();
        conn.execute("INSERT INTO names(name) VALUES ($1)", &[&"Joe Smith".to_string()]).unwrap();
    }

    chain.link_before(pg_middleware);

    Iron::new(chain).http("localhost:3000").unwrap();
}

fn name_list(req: &mut Request) -> IronResult<Response> {
    let conn = req.db_conn();
    let stmt = conn.prepare("SELECT id, name FROM names").unwrap();
    let rows = stmt.query(&[]).unwrap();

    let mut resp_str = "Names:\n".to_string();

    for row in rows {
        let id: i32 = row.get(0);
        let name: String = row.get(1);
        let name_format = format!("{}: {}\n", id, name);
        resp_str.push_str(&name_format);
    }

    Ok(Response::with((status::Ok, resp_str)))
}
<commit_msg>Update example code<commit_after>extern crate iron;
extern crate postgres;
extern crate iron_postgres_middleware as pg_middleware;

use std::error::Error;
use iron::prelude::*;
use iron::status;
use pg_middleware::{PostgresMiddleware, PostgresReqExt};

fn main() {
    let mut chain = Chain::new(name_list);

    match PostgresMiddleware::new("postgres://postgres@localhost/example") {
        Ok(pg_middleware) => {
            {
                let conn = pg_middleware.pool.get().unwrap();
                conn.execute(
                    "CREATE TABLE IF NOT EXISTS names (
                        id SERIAL PRIMARY KEY,
                        name VARCHAR(255) NOT NULL
                    )",
                &[]).unwrap();
                conn.execute("INSERT INTO names(name) VALUES ($1)", &[&"Joe Smith".to_string()]).unwrap();
            }
            chain.link_before(pg_middleware);
        },
        Err(err) => {
            panic!("Database error: {:}", err.description());
        }
    }

    Iron::new(chain).http("localhost:3000").unwrap();
}

fn name_list(req: &mut Request) -> IronResult<Response> {
    let conn = req.db_conn();
    let stmt = conn.prepare("SELECT id, name FROM names").unwrap();
    let rows = stmt.query(&[]).unwrap();

    let mut resp_str = "Names:\n".to_string();

    for row in rows {
        let id: i32 = row.get(0);
        let name: String = row.get(1);
        let name_format = format!("{}: {}\n", id, name);
        resp_str.push_str(&name_format);
    }

    Ok(Response::with((status::Ok, resp_str)))
}
<|endoftext|>


<commit_before>pub struct DeviceToken {
    pub token: String,
}

impl DeviceToken {
    pub fn new<S>(token: S) -> DeviceToken where S: Into<String> {
        DeviceToken {token: token.into()}
    }
}
<commit_msg>Implemented fmt::Display for DeviceToken<commit_after>pub struct DeviceToken {
    pub token: String,
}

impl DeviceToken {
    pub fn new<S>(token: S) -> DeviceToken where S: Into<String> {
        DeviceToken {token: token.into()}
    }
}

impl fmt::Display for DeviceToken {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.token)
    }
}
<|endoftext|>


<commit_before>use std::num::Wrapping as W;

use digest;
use utils::buffer::{FixedBuffer64, FixedBuffer, StandardPadding};

use byteorder::{ByteOrder, BigEndian};

// sboxes.c: Tiger S boxeszz
const SBOXES: [[u64; 256]; 4] = include!("tiger.sboxes");
const ROUNDS: usize = 3;

#[derive(Debug, Clone, Copy)]
struct State {
    a: W<u64>,
    b: W<u64>,
    c: W<u64>,
}

macro_rules! round {
    ($a:expr, $b:expr, $c:expr, $x:expr, $mul:expr) => {
        $c = $c ^ $x;
        $a = $a - W(
            SBOXES[0][($c.0 >> (0*8)) as usize & 0xff] ^
            SBOXES[1][($c.0 >> (2*8)) as usize & 0xff] ^
            SBOXES[2][($c.0 >> (4*8)) as usize & 0xff] ^
            SBOXES[3][($c.0 >> (6*8)) as usize & 0xff]);
        $b = $b + W(
            SBOXES[3][($c.0 >> (1*8)) as usize & 0xff] ^
            SBOXES[2][($c.0 >> (3*8)) as usize & 0xff] ^
            SBOXES[1][($c.0 >> (5*8)) as usize & 0xff] ^
            SBOXES[0][($c.0 >> (7*8)) as usize & 0xff]);
        $b = $b * W($mul);
    };
}

impl State {
    fn new() -> Self {
        State {
            a: W(0x0123456789abcdef),
            b: W(0xfedcba9876543210),
            c: W(0xf096a5b4c3b2e187),
        }
    }

    fn pass(&mut self, block: &[W<u64>], mul: u64) {
        round!(self.a, self.b, self.c, block[0], mul);
        round!(self.b, self.c, self.a, block[1], mul);
        round!(self.c, self.a, self.b, block[2], mul);
        round!(self.a, self.b, self.c, block[3], mul);
        round!(self.b, self.c, self.a, block[4], mul);
        round!(self.c, self.a, self.b, block[5], mul);
        round!(self.a, self.b, self.c, block[6], mul);
        round!(self.b, self.c, self.a, block[7], mul);
    }

    fn key_schedule(x: &mut [W<u64>]) {
        x[0] = x[0] - (x[7] ^ W(0xa5a5a5a5a5a5a5a5));
        x[1] = x[1] ^ x[0];
        x[2] = x[2] + x[1];
        x[3] = x[3] - (x[2] ^ (!x[1] << 19));
        x[4] = x[4] ^ x[3];
        x[5] = x[5] + x[4];
        x[6] = x[6] - (x[5] ^ (!x[4] >> 23));
        x[7] = x[7] ^ x[6];

        x[0] = x[0] + x[7];
        x[1] = x[1] - (x[0] ^ (!x[7] << 19));
        x[2] = x[2] ^ x[1];
        x[3] = x[3] + x[2];
        x[4] = x[4] - (x[3] ^ (!x[2] >> 23));
        x[5] = x[5] ^ x[4];
        x[6] = x[6] + x[5];
        x[7] = x[7] - (x[6] ^ W(0x0123456789abcdef));
    }

    fn rotate(&mut self) {
        let tmp = self.a;
        self.a = self.c;
        self.c = self.b;
        self.b = tmp;
    }

    fn compress(&mut self, block: &[u8]) {
        assert_eq!(block.len(), 64);
        let mut wblock = [W(0); 8];

        for (v, c) in wblock.iter_mut().zip(block.chunks(8)) {
            *v = W(BigEndian::read_u64(c));
        }

        let tmp = *self; // save abc
        for i in 0..ROUNDS {
            if i != 0 {
                Self::key_schedule(&mut wblock);
            }
            let mul = match i {
                0 => 5,
                1 => 7,
                _ => 9,
            };
            self.pass(&mut wblock, mul);
            self.rotate();
        }

        // feedforward
        self.a = self.a ^ tmp.a;
        self.b = self.b - tmp.b;
        self.c = self.c + tmp.c;
    }
}

#[derive(Clone)]
pub struct Tiger {
    state: State,
    buffer: FixedBuffer64,
    length: u64,
}

impl Default for Tiger {
    fn default() -> Self {
        Tiger {
            state: State::new(),
            buffer: FixedBuffer64::new(),
            length: 0,
        }
    }
}

impl digest::Digest for Tiger {
    fn update<T>(&mut self, update: T)
        where T: AsRef<[u8]>
    {
        let update = update.as_ref();
        self.length += update.len() as u64;

        let state = &mut self.state;
        self.buffer.input(update, |d| state.compress(d));
    }

    fn output_bits() -> usize {
        192
    }
    fn block_size() -> usize {
        64
    }

    fn result<T>(mut self, mut out: T)
        where T: AsMut<[u8]>
    {
        let state = &mut self.state;

        self.buffer.pad(0x01, 8, |d| state.compress(d));
        BigEndian::write_u64(self.buffer.next(8), self.length << 3);
        state.compress(self.buffer.full_buffer());

        let mut out = out.as_mut();
        assert!(out.len() >= Self::output_bytes());
        BigEndian::write_u64(&mut out[0..8], state.a.0);
        BigEndian::write_u64(&mut out[8..16], state.b.0);
        BigEndian::write_u64(&mut out[16..24], state.c.0);
    }
}

#[cfg(test)]
mod tests {
    use digest::test::Test;
    use super::Tiger;

    const TESTS: &'static [Test<'static>] = &[
        Test { input: b"", output: &[0x60, 0xef, 0x6c, 0x0d, 0xbc, 0x07, 0x7b, 0x9c, 0x17, 0x5f, 0xfb, 0x77, 0x71, 0x00, 0x8c, 0x25, 0x3b, 0xac, 0xea, 0x02, 0x4c, 0x9d, 0x01, 0xab] },
        Test { input: b"abc", output: &[0xc7, 0x9e, 0x79, 0x9e, 0x14, 0xb5, 0x3e, 0x7d, 0xf9, 0x35, 0xd8, 0x34, 0x77, 0xfa, 0x4d, 0xf9, 0x39, 0xd1, 0x8c, 0x44, 0xf7, 0x6b, 0x73, 0xcd] },
        Test { input: b"Tiger", output: &[0xa2, 0x4e, 0xe9, 0x54, 0x0c, 0x41, 0xd7, 0x1b, 0x6a, 0x62, 0x6f, 0x9d, 0xdf, 0x41, 0xd1, 0x2e, 0x30, 0x31, 0x27, 0x2b, 0x6a, 0xab, 0xbd, 0x9a] },
        Test { input: b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", output: &[0xaf, 0x58, 0xf9, 0xc0, 0x5b, 0x88, 0x60, 0x48, 0xc1, 0x6f, 0x48, 0xbc, 0x90, 0x4b, 0xef, 0xfd, 0xa8, 0x38, 0xf0, 0x05, 0xff, 0x74, 0x03, 0x5e] },
        Test { input: b"ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789", output: &[0x76, 0xaa, 0x09, 0x2e, 0x58, 0x9b, 0x0f, 0x0b, 0x8b, 0x78, 0x09, 0x44, 0xad, 0x1f, 0x0c, 0x41, 0xc9, 0xa5, 0xce, 0xb3, 0x07, 0xd2, 0xfd, 0xe0] },
        Test { input: b"Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham", output: &[0x82, 0x81, 0x5d, 0x89, 0x24, 0xe2, 0xf1, 0x1a, 0x88, 0xc0, 0xf2, 0x92, 0x91, 0x4c, 0x6c, 0xfd, 0xbf, 0xd8, 0xe7, 0x8e, 0x2c, 0xf2, 0x9a, 0xd0] },
        Test { input: b"Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.", output: &[0x48, 0x1f, 0x6d, 0xd0, 0xdf, 0x57, 0xe1, 0x03, 0xd7, 0xde, 0x0b, 0x66, 0x3a, 0xdb, 0x05, 0xf5, 0x03, 0xb8, 0x77, 0xf2, 0x76, 0xad, 0xb2, 0x86] },
        Test { input: b"Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.", output: &[0x69, 0x6d, 0x99, 0x60, 0x61, 0x88, 0x47, 0x25, 0x9f, 0x2f, 0xa5, 0x80, 0xdb, 0x2f, 0x95, 0x55, 0x96, 0xd7, 0xbe, 0xa2, 0x04, 0x6f, 0x46, 0xd7] },
        Test { input: b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", output: &[0x27, 0x20, 0xa3, 0x8d, 0x7f, 0x08, 0x75, 0x54, 0x5f, 0xd9, 0x61, 0x4f, 0x48, 0xf7, 0xe6, 0x7a, 0x92, 0xd3, 0x74, 0x69, 0xda, 0x2e, 0xf3, 0x78] },
    ];

    #[test]
    fn example_implementation_vectors() {
        for test in TESTS {
            test.test(Tiger::default());
        }
    }

    #[test]
    fn hash_of_64k_bytes_string() {
        use digest::Digest;

        let mut hash = Tiger::default();

        for i in 0..65536 {
            hash.update(&[(i & 0xff) as u8]);
        }
        let mut result = [0; 24];
        hash.result(&mut result[..]);

        assert_eq!(&result[..],
                   &[0xcd, 0x7e, 0xb9, 0x64, 0x5f, 0xb4, 0x05, 0xc6, 0x48, 0x5d, 0xd1, 0xaa, 0x14,
                     0x59, 0x6a, 0x63, 0xe5, 0x70, 0x4c, 0xc2, 0xff, 0x28, 0xf2, 0x4a])
    }
}
<commit_msg>feat(digest::tiger::Tiger2): Add implementation<commit_after>use std::num::Wrapping as W;

use digest;
use utils::buffer::{FixedBuffer64, FixedBuffer, StandardPadding};

use byteorder::{ByteOrder, BigEndian};

// sboxes.c: Tiger S boxeszz
const SBOXES: [[u64; 256]; 4] = include!("tiger.sboxes");
const ROUNDS: usize = 3;

#[derive(Debug, Clone, Copy)]
struct State {
    a: W<u64>,
    b: W<u64>,
    c: W<u64>,
}

macro_rules! round {
    ($a:expr, $b:expr, $c:expr, $x:expr, $mul:expr) => {
        $c = $c ^ $x;
        $a = $a - W(
            SBOXES[0][($c.0 >> (0*8)) as usize & 0xff] ^
            SBOXES[1][($c.0 >> (2*8)) as usize & 0xff] ^
            SBOXES[2][($c.0 >> (4*8)) as usize & 0xff] ^
            SBOXES[3][($c.0 >> (6*8)) as usize & 0xff]);
        $b = $b + W(
            SBOXES[3][($c.0 >> (1*8)) as usize & 0xff] ^
            SBOXES[2][($c.0 >> (3*8)) as usize & 0xff] ^
            SBOXES[1][($c.0 >> (5*8)) as usize & 0xff] ^
            SBOXES[0][($c.0 >> (7*8)) as usize & 0xff]);
        $b = $b * W($mul);
    };
}

impl State {
    fn new() -> Self {
        State {
            a: W(0x0123456789abcdef),
            b: W(0xfedcba9876543210),
            c: W(0xf096a5b4c3b2e187),
        }
    }

    fn pass(&mut self, block: &[W<u64>], mul: u64) {
        round!(self.a, self.b, self.c, block[0], mul);
        round!(self.b, self.c, self.a, block[1], mul);
        round!(self.c, self.a, self.b, block[2], mul);
        round!(self.a, self.b, self.c, block[3], mul);
        round!(self.b, self.c, self.a, block[4], mul);
        round!(self.c, self.a, self.b, block[5], mul);
        round!(self.a, self.b, self.c, block[6], mul);
        round!(self.b, self.c, self.a, block[7], mul);
    }

    fn key_schedule(x: &mut [W<u64>]) {
        x[0] = x[0] - (x[7] ^ W(0xa5a5a5a5a5a5a5a5));
        x[1] = x[1] ^ x[0];
        x[2] = x[2] + x[1];
        x[3] = x[3] - (x[2] ^ (!x[1] << 19));
        x[4] = x[4] ^ x[3];
        x[5] = x[5] + x[4];
        x[6] = x[6] - (x[5] ^ (!x[4] >> 23));
        x[7] = x[7] ^ x[6];

        x[0] = x[0] + x[7];
        x[1] = x[1] - (x[0] ^ (!x[7] << 19));
        x[2] = x[2] ^ x[1];
        x[3] = x[3] + x[2];
        x[4] = x[4] - (x[3] ^ (!x[2] >> 23));
        x[5] = x[5] ^ x[4];
        x[6] = x[6] + x[5];
        x[7] = x[7] - (x[6] ^ W(0x0123456789abcdef));
    }

    fn rotate(&mut self) {
        let tmp = self.a;
        self.a = self.c;
        self.c = self.b;
        self.b = tmp;
    }

    fn compress(&mut self, block: &[u8]) {
        assert_eq!(block.len(), 64);
        let mut wblock = [W(0); 8];

        for (v, c) in wblock.iter_mut().zip(block.chunks(8)) {
            *v = W(BigEndian::read_u64(c));
        }

        let tmp = *self; // save abc
        for i in 0..ROUNDS {
            if i != 0 {
                Self::key_schedule(&mut wblock);
            }
            let mul = match i {
                0 => 5,
                1 => 7,
                _ => 9,
            };
            self.pass(&mut wblock, mul);
            self.rotate();
        }

        // feedforward
        self.a = self.a ^ tmp.a;
        self.b = self.b - tmp.b;
        self.c = self.c + tmp.c;
    }
}

macro_rules! tiger_impl {
    ($name:ident, $padding:expr) => {
        #[derive(Clone)]
        pub struct $name {
            state: State,
            buffer: FixedBuffer64,
            length: u64,
        }

        impl Default for $name {
            fn default() -> Self {
                $name {
                    state: State::new(),
                    buffer: FixedBuffer64::new(),
                    length: 0,
                }
            }
        }

        impl digest::Digest for $name {
            fn update<T>(&mut self, update: T)
                where T: AsRef<[u8]>
                {
                    let update = update.as_ref();
                    self.length += update.len() as u64;

                    let state = &mut self.state;
                    self.buffer.input(update, |d| state.compress(d));
                }

            fn output_bits() -> usize {
                192
            }
            fn block_size() -> usize {
                64
            }

            fn result<T>(mut self, mut out: T)
                where T: AsMut<[u8]>
                {
                    let state = &mut self.state;

                    self.buffer.pad($padding, 8, |d| state.compress(d));
                    BigEndian::write_u64(self.buffer.next(8), self.length << 3);
                    state.compress(self.buffer.full_buffer());

                    let mut out = out.as_mut();
                    assert!(out.len() >= Self::output_bytes());
                    BigEndian::write_u64(&mut out[0..8], state.a.0);
                    BigEndian::write_u64(&mut out[8..16], state.b.0);
                    BigEndian::write_u64(&mut out[16..24], state.c.0);
                }
        }
    };
}

tiger_impl!(Tiger,  0x01);
tiger_impl!(Tiger2, 0x80);

#[cfg(test)]
mod tests {
    use digest::test::Test;
    use super::Tiger;

    const TESTS: &'static [Test<'static>] = &[
        Test { input: b"", output: &[0x60, 0xef, 0x6c, 0x0d, 0xbc, 0x07, 0x7b, 0x9c, 0x17, 0x5f, 0xfb, 0x77, 0x71, 0x00, 0x8c, 0x25, 0x3b, 0xac, 0xea, 0x02, 0x4c, 0x9d, 0x01, 0xab] },
        Test { input: b"abc", output: &[0xc7, 0x9e, 0x79, 0x9e, 0x14, 0xb5, 0x3e, 0x7d, 0xf9, 0x35, 0xd8, 0x34, 0x77, 0xfa, 0x4d, 0xf9, 0x39, 0xd1, 0x8c, 0x44, 0xf7, 0x6b, 0x73, 0xcd] },
        Test { input: b"Tiger", output: &[0xa2, 0x4e, 0xe9, 0x54, 0x0c, 0x41, 0xd7, 0x1b, 0x6a, 0x62, 0x6f, 0x9d, 0xdf, 0x41, 0xd1, 0x2e, 0x30, 0x31, 0x27, 0x2b, 0x6a, 0xab, 0xbd, 0x9a] },
        Test { input: b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", output: &[0xaf, 0x58, 0xf9, 0xc0, 0x5b, 0x88, 0x60, 0x48, 0xc1, 0x6f, 0x48, 0xbc, 0x90, 0x4b, 0xef, 0xfd, 0xa8, 0x38, 0xf0, 0x05, 0xff, 0x74, 0x03, 0x5e] },
        Test { input: b"ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789", output: &[0x76, 0xaa, 0x09, 0x2e, 0x58, 0x9b, 0x0f, 0x0b, 0x8b, 0x78, 0x09, 0x44, 0xad, 0x1f, 0x0c, 0x41, 0xc9, 0xa5, 0xce, 0xb3, 0x07, 0xd2, 0xfd, 0xe0] },
        Test { input: b"Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham", output: &[0x82, 0x81, 0x5d, 0x89, 0x24, 0xe2, 0xf1, 0x1a, 0x88, 0xc0, 0xf2, 0x92, 0x91, 0x4c, 0x6c, 0xfd, 0xbf, 0xd8, 0xe7, 0x8e, 0x2c, 0xf2, 0x9a, 0xd0] },
        Test { input: b"Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.", output: &[0x48, 0x1f, 0x6d, 0xd0, 0xdf, 0x57, 0xe1, 0x03, 0xd7, 0xde, 0x0b, 0x66, 0x3a, 0xdb, 0x05, 0xf5, 0x03, 0xb8, 0x77, 0xf2, 0x76, 0xad, 0xb2, 0x86] },
        Test { input: b"Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.", output: &[0x69, 0x6d, 0x99, 0x60, 0x61, 0x88, 0x47, 0x25, 0x9f, 0x2f, 0xa5, 0x80, 0xdb, 0x2f, 0x95, 0x55, 0x96, 0xd7, 0xbe, 0xa2, 0x04, 0x6f, 0x46, 0xd7] },
        Test { input: b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", output: &[0x27, 0x20, 0xa3, 0x8d, 0x7f, 0x08, 0x75, 0x54, 0x5f, 0xd9, 0x61, 0x4f, 0x48, 0xf7, 0xe6, 0x7a, 0x92, 0xd3, 0x74, 0x69, 0xda, 0x2e, 0xf3, 0x78] },
    ];

    #[test]
    fn example_implementation_vectors() {
        for test in TESTS {
            test.test(Tiger::default());
        }
    }

    #[test]
    fn hash_of_64k_bytes_string() {
        use digest::Digest;

        let mut hash = Tiger::default();

        for i in 0..65536 {
            hash.update(&[(i & 0xff) as u8]);
        }
        let mut result = [0; 24];
        hash.result(&mut result[..]);

        assert_eq!(&result[..],
                   &[0xcd, 0x7e, 0xb9, 0x64, 0x5f, 0xb4, 0x05, 0xc6, 0x48, 0x5d, 0xd1, 0xaa, 0x14,
                   0x59, 0x6a, 0x63, 0xe5, 0x70, 0x4c, 0xc2, 0xff, 0x28, 0xf2, 0x4a])
    }
}
<|endoftext|>