1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-28 01:32:57 +01:00

move protobuf support to the example

This commit is contained in:
Nikolay Kim 2018-03-09 05:29:06 -08:00
parent 2068eee669
commit 49e007ff2a
6 changed files with 38 additions and 44 deletions

View File

@ -78,7 +78,7 @@ script:
after_success: after_success:
- | - |
if [[ "$TRAVIS_OS_NAME" == "linux" && "$TRAVIS_PULL_REQUEST" = "false" && "$TRAVIS_BRANCH" == "master" && "$TRAVIS_RUST_VERSION" == "nightly" ]]; then if [[ "$TRAVIS_OS_NAME" == "linux" && "$TRAVIS_PULL_REQUEST" = "false" && "$TRAVIS_BRANCH" == "master" && "$TRAVIS_RUST_VERSION" == "nightly" ]]; then
cargo doc --features "alpn, tls, protobuf" --no-deps && cargo doc --features "alpn, tls" --no-deps &&
echo "<meta http-equiv=refresh content=0;url=os_balloon/index.html>" > target/doc/index.html && echo "<meta http-equiv=refresh content=0;url=os_balloon/index.html>" > target/doc/index.html &&
cargo install mdbook && cargo install mdbook &&
cd guide && mdbook build -d ../target/doc/guide && cd .. && cd guide && mdbook build -d ../target/doc/guide && cd .. &&

View File

@ -38,9 +38,6 @@ alpn = ["openssl", "openssl/v102", "openssl/v110", "tokio-openssl"]
# sessions # sessions
session = ["cookie/secure"] session = ["cookie/secure"]
# protobuf
protobuf = ["prost"]
[dependencies] [dependencies]
actix = "^0.5.2" actix = "^0.5.2"
@ -90,9 +87,6 @@ tokio-tls = { version="0.1", optional = true }
openssl = { version="0.10", optional = true } openssl = { version="0.10", optional = true }
tokio-openssl = { version="0.2", optional = true } tokio-openssl = { version="0.2", optional = true }
# protobuf
prost = { version="^0.2", optional = true }
[dev-dependencies] [dev-dependencies]
env_logger = "0.5" env_logger = "0.5"
skeptic = "0.13" skeptic = "0.13"

View File

@ -6,10 +6,11 @@ authors = ["kingxsp <jin_hb_zh@126.com>"]
[dependencies] [dependencies]
bytes = "0.4" bytes = "0.4"
futures = "0.1" futures = "0.1"
failure = "0.1"
env_logger = "*" env_logger = "*"
prost = "0.2.0" prost = "0.2.0"
prost-derive = "0.2.0" prost-derive = "0.2.0"
actix = "0.5" actix = "0.5"
actix-web = { path="../../", features=["protobuf"] } actix-web = { path="../../" }

View File

@ -2,15 +2,19 @@ extern crate actix;
extern crate actix_web; extern crate actix_web;
extern crate bytes; extern crate bytes;
extern crate futures; extern crate futures;
#[macro_use]
extern crate failure;
extern crate env_logger; extern crate env_logger;
extern crate prost; extern crate prost;
#[macro_use] #[macro_use]
extern crate prost_derive; extern crate prost_derive;
use actix_web::*; use actix_web::*;
use actix_web::ProtoBufBody;
use futures::Future; use futures::Future;
mod protobuf;
use protobuf::ProtoBufResponseBuilder;
#[derive(Clone, Debug, PartialEq, Message)] #[derive(Clone, Debug, PartialEq, Message)]
pub struct MyObj { pub struct MyObj {
@ -21,9 +25,9 @@ pub struct MyObj {
} }
/// This handler uses `HttpRequest::json()` for loading serde json object. /// This handler uses `ProtoBufMessage` for loading protobuf object.
fn index(req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> { fn index(req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
ProtoBufBody::new(req) protobuf::ProtoBufMessage::new(req)
.from_err() // convert all errors into `Error` .from_err() // convert all errors into `Error`
.and_then(|val: MyObj| { .and_then(|val: MyObj| {
println!("model: {:?}", val); println!("model: {:?}", val);

View File

@ -1,18 +1,17 @@
use bytes::{Bytes, BytesMut}; use bytes::{Bytes, BytesMut};
use futures::{Poll, Future, Stream}; use futures::{Poll, Future, Stream};
use http::header::{CONTENT_TYPE, CONTENT_LENGTH};
use bytes::IntoBuf; use bytes::IntoBuf;
use prost::Message; use prost::Message;
use prost::EncodeError as ProtoBufEncodeError;
use prost::DecodeError as ProtoBufDecodeError; use prost::DecodeError as ProtoBufDecodeError;
use prost::EncodeError as ProtoBufEncodeError;
use actix_web::header::http::{CONTENT_TYPE, CONTENT_LENGTH};
use actix_web::{Responder, HttpMessage, HttpRequest, HttpResponse};
use actix_web::dev::HttpResponseBuilder;
use actix_web::error::{Error, PayloadError, ResponseError};
use actix_web::httpcodes::{HttpBadRequest, HttpPayloadTooLarge};
use error::{Error, PayloadError, ResponseError};
use handler::Responder;
use httpmessage::HttpMessage;
use httprequest::HttpRequest;
use httpresponse::{HttpResponse, HttpResponseBuilder};
use httpcodes::{HttpBadRequest, HttpPayloadTooLarge};
#[derive(Fail, Debug)] #[derive(Fail, Debug)]
pub enum ProtoBufPayloadError { pub enum ProtoBufPayloadError {
@ -22,8 +21,11 @@ pub enum ProtoBufPayloadError {
/// Content type error /// Content type error
#[fail(display="Content type error")] #[fail(display="Content type error")]
ContentType, ContentType,
/// Serialize error
#[fail(display="ProtoBud serialize error: {}", _0)]
Serialize(#[cause] ProtoBufEncodeError),
/// Deserialize error /// Deserialize error
#[fail(display="Json deserialize error: {}", _0)] #[fail(display="ProtoBud deserialize error: {}", _0)]
Deserialize(#[cause] ProtoBufDecodeError), Deserialize(#[cause] ProtoBufDecodeError),
/// Payload error /// Payload error
#[fail(display="Error that occur during reading payload: {}", _0)] #[fail(display="Error that occur during reading payload: {}", _0)]
@ -52,10 +54,6 @@ impl From<ProtoBufDecodeError> for ProtoBufPayloadError {
} }
} }
/// `InternalServerError` for `ProtoBufEncodeError` `ProtoBufDecodeError`
impl ResponseError for ProtoBufEncodeError {}
impl ResponseError for ProtoBufDecodeError {}
#[derive(Debug)] #[derive(Debug)]
pub struct ProtoBuf<T: Message>(pub T); pub struct ProtoBuf<T: Message>(pub T);
@ -66,28 +64,28 @@ impl<T: Message> Responder for ProtoBuf<T> {
fn respond_to(self, _: HttpRequest) -> Result<HttpResponse, Error> { fn respond_to(self, _: HttpRequest) -> Result<HttpResponse, Error> {
let mut buf = Vec::new(); let mut buf = Vec::new();
self.0.encode(&mut buf) self.0.encode(&mut buf)
.map_err(Error::from) .map_err(|e| Error::from(ProtoBufPayloadError::Serialize(e)))
.and_then(|()| { .and_then(|()| {
Ok(HttpResponse::Ok() Ok(HttpResponse::Ok()
.content_type("application/protobuf") .content_type("application/protobuf")
.body(buf) .body(buf)
.into()) .into())
}) })
} }
} }
pub struct ProtoBufBody<T, U: Message + Default>{ pub struct ProtoBufMessage<T, U: Message + Default>{
limit: usize, limit: usize,
ct: &'static str, ct: &'static str,
req: Option<T>, req: Option<T>,
fut: Option<Box<Future<Item=U, Error=ProtoBufPayloadError>>>, fut: Option<Box<Future<Item=U, Error=ProtoBufPayloadError>>>,
} }
impl<T, U: Message + Default> ProtoBufBody<T, U> { impl<T, U: Message + Default> ProtoBufMessage<T, U> {
/// Create `ProtoBufBody` for request. /// Create `ProtoBufMessage` for request.
pub fn new(req: T) -> Self { pub fn new(req: T) -> Self {
ProtoBufBody{ ProtoBufMessage{
limit: 262_144, limit: 262_144,
req: Some(req), req: Some(req),
fut: None, fut: None,
@ -111,7 +109,7 @@ impl<T, U: Message + Default> ProtoBufBody<T, U> {
} }
} }
impl<T, U: Message + Default + 'static> Future for ProtoBufBody<T, U> impl<T, U: Message + Default + 'static> Future for ProtoBufMessage<T, U>
where T: HttpMessage + Stream<Item=Bytes, Error=PayloadError> + 'static where T: HttpMessage + Stream<Item=Bytes, Error=PayloadError> + 'static
{ {
type Item = U; type Item = U;
@ -154,13 +152,18 @@ impl<T, U: Message + Default + 'static> Future for ProtoBufBody<T, U>
} }
impl HttpResponseBuilder { pub trait ProtoBufResponseBuilder {
pub fn protobuf<T: Message>(&mut self, value: T) -> Result<HttpResponse, Error> { fn protobuf<T: Message>(&mut self, value: T) -> Result<HttpResponse, Error>;
}
impl ProtoBufResponseBuilder for HttpResponseBuilder {
fn protobuf<T: Message>(&mut self, value: T) -> Result<HttpResponse, Error> {
self.header(CONTENT_TYPE, "application/protobuf"); self.header(CONTENT_TYPE, "application/protobuf");
let mut body = Vec::new(); let mut body = Vec::new();
value.encode(&mut body)?; value.encode(&mut body).map_err(|e| ProtoBufPayloadError::Serialize(e))?;
Ok(self.body(body)?) Ok(self.body(body)?)
} }
} }

View File

@ -88,9 +88,6 @@ extern crate h2 as http2;
extern crate trust_dns_resolver; extern crate trust_dns_resolver;
#[macro_use] extern crate actix; #[macro_use] extern crate actix;
#[cfg(feature="protobuf")]
extern crate prost;
#[cfg(test)] #[cfg(test)]
#[macro_use] extern crate serde_derive; #[macro_use] extern crate serde_derive;
@ -121,11 +118,6 @@ mod param;
mod payload; mod payload;
mod pipeline; mod pipeline;
#[cfg(feature="protobuf")]
mod protobuf;
#[cfg(feature="protobuf")]
pub use protobuf::{ProtoBuf, ProtoBufBody};
pub mod client; pub mod client;
pub mod fs; pub mod fs;
pub mod ws; pub mod ws;