1
0
mirror of https://github.com/actix/actix-extras.git synced 2025-06-25 18:09:22 +02:00

Merge branch 'master' into master

This commit is contained in:
Nikolay Kim
2018-01-26 19:42:06 -08:00
committed by GitHub
80 changed files with 4067 additions and 1743 deletions

View File

@ -6,6 +6,6 @@ workspace = "../.."
[dependencies]
futures = "*"
env_logger = "0.4"
env_logger = "0.5"
actix = "0.4"
actix-web = { git = "https://github.com/actix/actix-web" }
actix-web = { path="../.." }

View File

@ -16,4 +16,5 @@ cargo run
- [http://localhost:8080/async/bob](http://localhost:8080/async/bob)
- [http://localhost:8080/user/bob/](http://localhost:8080/user/bob/) plain/text download
- [http://localhost:8080/test](http://localhost:8080/test) (return status switch GET or POST or other)
- [http://localhost:8080/static/index.html](http://localhost:8080/static/index.html)
- [http://localhost:8080/static/index.html](http://localhost:8080/static/index.html)
- [http://localhost:8080/static/notexit](http://localhost:8080/static/notexit) display 404 page

View File

@ -7,6 +7,7 @@ extern crate env_logger;
extern crate futures;
use futures::Stream;
use std::{io, env};
use actix_web::*;
use actix_web::middleware::RequestSession;
use futures::future::{FutureResult, result};
@ -56,17 +57,17 @@ fn index(mut req: HttpRequest) -> Result<HttpResponse> {
fn p404(req: HttpRequest) -> Result<HttpResponse> {
// html
let html = format!(r#"<!DOCTYPE html><html><head><title>actix - basics</title><link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" /></head>
let html = r#"<!DOCTYPE html><html><head><title>actix - basics</title><link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" /></head>
<body>
<a href="index.html">back to home</a>
<h1>404</h1>
</body>
</html>"#);
</html>"#;
// response
Ok(HttpResponse::build(StatusCode::NOT_FOUND)
.content_type("text/html; charset=utf-8")
.body(&html).unwrap())
.body(html).unwrap())
}
@ -92,8 +93,9 @@ fn with_param(req: HttpRequest) -> Result<HttpResponse>
}
fn main() {
::std::env::set_var("RUST_LOG", "actix_web=info");
let _ = env_logger::init();
env::set_var("RUST_LOG", "actix_web=debug");
env::set_var("RUST_BACKTRACE", "1");
env_logger::init();
let sys = actix::System::new("basic-example");
let addr = HttpServer::new(
@ -121,6 +123,9 @@ fn main() {
_ => httpcodes::HTTPNotFound,
}
}))
.resource("/error.html", |r| r.f(|req| {
error::ErrorBadRequest(io::Error::new(io::ErrorKind::Other, "test"))
}))
// static files
.handler("/static/", fs::StaticFiles::new("../static/", true))
// redirect

View File

@ -5,9 +5,9 @@ authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
workspace = "../.."
[dependencies]
env_logger = "0.4"
env_logger = "0.5"
actix = "0.4"
actix-web = { git = "https://github.com/actix/actix-web" }
actix-web = { path = "../../" }
futures = "0.1"
uuid = { version = "0.5", features = ["serde", "v4"] }

View File

@ -8,7 +8,7 @@ use diesel::prelude::*;
use models;
use schema;
/// This is db executor actor. We are going to run 3 of them in parallele.
/// This is db executor actor. We are going to run 3 of them in parallel.
pub struct DbExecutor(pub SqliteConnection);
/// This is only message that this actor can handle, but it is easy to extend number of

View File

@ -5,6 +5,6 @@ authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
workspace = "../.."
[dependencies]
env_logger = "0.4"
env_logger = "0.5"
actix = "0.4"
actix-web = { path = "../../" }

View File

@ -15,4 +15,4 @@ serde_derive = "1.0"
json = "*"
actix = "0.4"
actix-web = { git = "https://github.com/actix/actix-web" }
actix-web = { path="../../" }

View File

@ -12,4 +12,4 @@ path = "src/main.rs"
env_logger = "*"
futures = "0.1"
actix = "0.4"
actix-web = { git = "https://github.com/actix/actix-web" }
actix-web = { path="../../" }

View File

@ -6,6 +6,6 @@ workspace = "../.."
[dependencies]
futures = "*"
env_logger = "0.4"
env_logger = "0.5"
actix = "0.4"
actix-web = { git = "https://github.com/actix/actix-web" }
actix-web = { path = "../../" }

View File

@ -1,5 +1,5 @@
#![cfg_attr(feature="cargo-clippy", allow(needless_pass_by_value))]
//! There are two level of statfulness in actix-web. Application has state
//! There are two level of statefulness in actix-web. Application has state
//! that is shared across all handlers within same Application.
//! And individual handler can have state.
@ -33,7 +33,7 @@ struct MyWebSocket {
}
impl Actor for MyWebSocket {
type Context = HttpContext<Self, AppState>;
type Context = ws::WebsocketContext<Self, AppState>;
}
impl Handler<ws::Message> for MyWebSocket {
@ -43,9 +43,9 @@ impl Handler<ws::Message> for MyWebSocket {
self.counter += 1;
println!("WS({}): {:?}", self.counter, msg);
match msg {
ws::Message::Ping(msg) => ws::WsWriter::pong(ctx, &msg),
ws::Message::Text(text) => ws::WsWriter::text(ctx, &text),
ws::Message::Binary(bin) => ws::WsWriter::binary(ctx, bin),
ws::Message::Ping(msg) => ctx.pong(&msg),
ws::Message::Text(text) => ctx.text(&text),
ws::Message::Binary(bin) => ctx.binary(bin),
ws::Message::Closed | ws::Message::Error => {
ctx.stop();
}

View File

@ -5,7 +5,7 @@ authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
workspace = "../.."
[dependencies]
env_logger = "0.4"
env_logger = "0.5"
actix = "0.4"
actix-web = { git = "https://github.com/actix/actix-web" }
actix-web = { path = "../../" }
tera = "*"

View File

@ -9,6 +9,7 @@ name = "server"
path = "src/main.rs"
[dependencies]
env_logger = "0.4"
actix = "0.4"
actix-web = { git = "https://github.com/actix/actix-web", features=["alpn"] }
env_logger = "0.5"
actix = "^0.4.2"
actix-web = { path = "../../", features=["alpn"] }
openssl = { version="0.10", features = ["v110"] }

31
examples/tls/cert.pem Normal file
View File

@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFPjCCAyYCCQDvLYiYD+jqeTANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJV
UzELMAkGA1UECAwCQ0ExCzAJBgNVBAcMAlNGMRAwDgYDVQQKDAdDb21wYW55MQww
CgYDVQQLDANPcmcxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xODAxMjUx
NzQ2MDFaFw0xOTAxMjUxNzQ2MDFaMGExCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJD
QTELMAkGA1UEBwwCU0YxEDAOBgNVBAoMB0NvbXBhbnkxDDAKBgNVBAsMA09yZzEY
MBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
MIICCgKCAgEA2WzIA2IpVR9Tb9EFhITlxuhE5rY2a3S6qzYNzQVgSFggxXEPn8k1
sQEcer5BfAP986Sck3H0FvB4Bt/I8PwOtUCmhwcc8KtB5TcGPR4fjXnrpC+MIK5U
NLkwuyBDKziYzTdBj8kUFX1WxmvEHEgqToPOZfBgsS71cJAR/zOWraDLSRM54jXy
voLZN4Ti9rQagQrvTQ44Vz5ycDQy7UxtbUGh1CVv69vNVr7/SOOh/Nw5FNOZWLWr
odGyoec5wh9iqRZgRqiTUc6Lt7V2RWc2X2gjwST2UfI+U46Ip3oaQ7ZD4eAkoqND
xdniBZAykVG3c/99ux4BAESTF8fsNch6UticBxYMuTu+ouvP0psfI9wwwNliJDmA
CRUTB9AgRynbL1AzhqQoDfsb98IZfjfNOpwnwuLwpMAPhbgd5KNdZaIJ4Hb6/stI
yFElOExxd3TAxF2Gshd/lq1JcNHAZ1DSXV5MvOWT/NWgXwbIzUgQ8eIi+HuDYX2U
UuaB6R8tbd52H7rbUv6HrfinuSlKWqjSYLkiKHkwUpoMw8y9UycRSzs1E9nPwPTO
vRXb0mNCQeBCV9FvStNVXdCUTT8LGPv87xSD2pmt7LijlE6mHLG8McfcWkzA69un
CEHIFAFDimTuN7EBljc119xWFTcHMyoZAfFF+oTqwSbBGImruCxnaJECAwEAATAN
BgkqhkiG9w0BAQsFAAOCAgEApavsgsn7SpPHfhDSN5iZs1ILZQRewJg0Bty0xPfk
3tynSW6bNH3nSaKbpsdmxxomthNSQgD2heOq1By9YzeOoNR+7Pk3s4FkASnf3ToI
JNTUasBFFfaCG96s4Yvs8KiWS/k84yaWuU8c3Wb1jXs5Rv1qE1Uvuwat1DSGXSoD
JNluuIkCsC4kWkyq5pWCGQrabWPRTWsHwC3PTcwSRBaFgYLJaR72SloHB1ot02zL
d2age9dmFRFLLCBzP+D7RojBvL37qS/HR+rQ4SoQwiVc/JzaeqSe7ZbvEH9sZYEu
ALowJzgbwro7oZflwTWunSeSGDSltkqKjvWvZI61pwfHKDahUTmZ5h2y67FuGEaC
CIOUI8dSVSPKITxaq3JL4ze2e9/0Lt7hj19YK2uUmtMAW5Tirz4Yx5lyGH9U8Wur
y/X8VPxTc4A9TMlJgkyz0hqvhbPOT/zSWB10zXh0glKAsSBryAOEDxV1UygmSir7
YV8Qaq+oyKUTMc1MFq5vZ07M51EPaietn85t8V2Y+k/8XYltRp32NxsypxAJuyxh
g/ko6RVTrWa1sMvz/F9LFqAdKiK5eM96lh9IU4xiLg4ob8aS/GRAA8oIFkZFhLrt
tOwjIUPmEPyHWFi8dLpNuQKYalLYhuwZftG/9xV+wqhKGZO9iPrpHSYBRTap8w2y
1QU=
-----END CERTIFICATE-----

Binary file not shown.

51
examples/tls/key.pem Normal file
View File

@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -2,14 +2,13 @@
extern crate actix;
extern crate actix_web;
extern crate env_logger;
use std::fs::File;
use std::io::Read;
extern crate openssl;
use actix_web::*;
use openssl::ssl::{SslMethod, SslAcceptor, SslFiletype};
/// somple handle
/// simple handle
fn index(req: HttpRequest) -> Result<HttpResponse> {
println!("{:?}", req);
Ok(httpcodes::HTTPOk
@ -20,15 +19,15 @@ fn index(req: HttpRequest) -> Result<HttpResponse> {
fn main() {
if ::std::env::var("RUST_LOG").is_err() {
::std::env::set_var("RUST_LOG", "actix_web=trace");
::std::env::set_var("RUST_LOG", "actix_web=info");
}
let _ = env_logger::init();
let sys = actix::System::new("ws-example");
let mut file = File::open("identity.pfx").unwrap();
let mut pkcs12 = vec![];
file.read_to_end(&mut pkcs12).unwrap();
let pkcs12 = Pkcs12::from_der(&pkcs12).unwrap().parse("12345").unwrap();
// load ssl keys
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
builder.set_private_key_file("key.pem", SslFiletype::PEM).unwrap();
builder.set_certificate_chain_file("cert.pem").unwrap();
let addr = HttpServer::new(
|| Application::new()
@ -44,7 +43,7 @@ fn main() {
.body(Body::Empty)
})))
.bind("127.0.0.1:8443").unwrap()
.start_ssl(&pkcs12).unwrap();
.start_ssl(builder).unwrap();
println!("Started http server: 127.0.0.1:8443");
let _ = sys.run();

View File

@ -25,6 +25,5 @@ serde = "1.0"
serde_json = "1.0"
serde_derive = "1.0"
#actix = "0.4"
actix = { git = "https://github.com/actix/actix" }
actix-web = { git = "https://github.com/actix/actix-web" }
actix = "^0.4.2"
actix-web = { path="../../" }

View File

@ -16,8 +16,8 @@ Chat server listens for incoming tcp connections. Server can access several type
* `\list` - list all available rooms
* `\join name` - join room, if room does not exist, create new one
* `\name name` - set session name
* `some message` - just string, send messsage to all peers in same room
* client has to send heartbeat `Ping` messages, if server does not receive a heartbeat message for 10 seconds connection gets droppped
* `some message` - just string, send message to all peers in same room
* client has to send heartbeat `Ping` messages, if server does not receive a heartbeat message for 10 seconds connection gets dropped
To start server use command: `cargo run --bin server`

View File

@ -52,7 +52,7 @@ struct WsChatSession {
}
impl Actor for WsChatSession {
type Context = HttpContext<Self, WsChatSessionState>;
type Context = ws::WebsocketContext<Self, WsChatSessionState>;
/// Method is called on actor start.
/// We register ws session with ChatServer
@ -87,7 +87,7 @@ impl Handler<session::Message> for WsChatSession {
type Result = ();
fn handle(&mut self, msg: session::Message, ctx: &mut Self::Context) {
ws::WsWriter::text(ctx, &msg.0);
ctx.text(&msg.0);
}
}
@ -98,10 +98,8 @@ impl Handler<ws::Message> for WsChatSession {
fn handle(&mut self, msg: ws::Message, ctx: &mut Self::Context) {
println!("WEBSOCKET MESSAGE: {:?}", msg);
match msg {
ws::Message::Ping(msg) =>
ws::WsWriter::pong(ctx, &msg),
ws::Message::Pong(msg) =>
self.hb = Instant::now(),
ws::Message::Ping(msg) => ctx.pong(&msg),
ws::Message::Pong(msg) => self.hb = Instant::now(),
ws::Message::Text(text) => {
let m = text.trim();
// we check for /sss type of messages
@ -115,7 +113,7 @@ impl Handler<ws::Message> for WsChatSession {
match res {
Ok(Ok(rooms)) => {
for room in rooms {
ws::WsWriter::text(ctx, &room);
ctx.text(&room);
}
},
_ => println!("Something is wrong"),
@ -132,20 +130,19 @@ impl Handler<ws::Message> for WsChatSession {
ctx.state().addr.send(
server::Join{id: self.id, name: self.room.clone()});
ws::WsWriter::text(ctx, "joined");
ctx.text("joined");
} else {
ws::WsWriter::text(ctx, "!!! room name is required");
ctx.text("!!! room name is required");
}
},
"/name" => {
if v.len() == 2 {
self.name = Some(v[1].to_owned());
} else {
ws::WsWriter::text(ctx, "!!! name is required");
ctx.text("!!! name is required");
}
},
_ => ws::WsWriter::text(
ctx, &format!("!!! unknown command: {:?}", m)),
_ => ctx.text(&format!("!!! unknown command: {:?}", m)),
}
} else {
let msg = if let Some(ref name) = self.name {

View File

@ -16,7 +16,7 @@ use codec::{ChatRequest, ChatResponse, ChatCodec};
#[derive(Message)]
pub struct Message(pub String);
/// `ChatSession` actor is responsible for tcp peer communitions.
/// `ChatSession` actor is responsible for tcp peer communications.
pub struct ChatSession {
/// unique session id
id: usize,
@ -30,7 +30,7 @@ pub struct ChatSession {
impl Actor for ChatSession {
/// For tcp communication we are going to use `FramedContext`.
/// It is convinient wrapper around `Framed` object from `tokio_io`
/// It is convenient wrapper around `Framed` object from `tokio_io`
type Context = FramedContext<Self>;
fn started(&mut self, ctx: &mut Self::Context) {
@ -149,7 +149,7 @@ impl ChatSession {
}
/// Define tcp server that will accept incomint tcp connection and create
/// Define tcp server that will accept incoming tcp connection and create
/// chat actors.
pub struct TcpServer {
chat: SyncAddress<ChatServer>,

View File

@ -10,6 +10,5 @@ path = "src/main.rs"
[dependencies]
env_logger = "*"
futures = "0.1"
#actix = "0.4"
actix = { git = "https://github.com/actix/actix.git" }
actix = "^0.4.2"
actix-web = { git = "https://github.com/actix/actix-web.git" }

View File

@ -21,20 +21,20 @@ fn ws_index(r: HttpRequest) -> Result<HttpResponse> {
struct MyWebSocket;
impl Actor for MyWebSocket {
type Context = HttpContext<Self>;
type Context = ws::WebsocketContext<Self>;
}
/// Handler for `ws::Message`
impl Handler<ws::Message> for MyWebSocket {
type Result = ();
fn handle(&mut self, msg: ws::Message, ctx: &mut HttpContext<Self>) {
fn handle(&mut self, msg: ws::Message, ctx: &mut Self::Context) {
// process websocket messages
println!("WS: {:?}", msg);
match msg {
ws::Message::Ping(msg) => ws::WsWriter::pong(ctx, &msg),
ws::Message::Text(text) => ws::WsWriter::text(ctx, &text),
ws::Message::Binary(bin) => ws::WsWriter::binary(ctx, bin),
ws::Message::Ping(msg) => ctx.pong(&msg),
ws::Message::Text(text) => ctx.text(&text),
ws::Message::Binary(bin) => ctx.binary(bin),
ws::Message::Closed | ws::Message::Error => {
ctx.stop();
}