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

simplify http response construction; deprecate httpcodes

This commit is contained in:
Nikolay Kim
2018-03-30 23:07:33 -07:00
parent 8d8f6bedad
commit 44e3df82f6
58 changed files with 561 additions and 539 deletions

View File

@ -23,7 +23,7 @@ Here is an example of a simple middleware that adds request and response headers
# extern crate http;
# extern crate actix_web;
use http::{header, HttpTryFrom};
use actix_web::{Application, HttpRequest, HttpResponse, Result, httpcodes};
use actix_web::{Application, HttpRequest, HttpResponse, Result};
use actix_web::middleware::{Middleware, Started, Response};
struct Headers; // <- Our middleware
@ -53,7 +53,7 @@ impl<S> Middleware<S> for Headers {
fn main() {
Application::new()
.middleware(Headers) // <- Register middleware, this method can be called multiple times
.resource("/", |r| r.h(httpcodes::HttpOk));
.resource("/", |r| r.f(|_| HttpResponse::Ok()));
}
```
@ -135,7 +135,7 @@ the specified header.
```rust
# extern crate actix_web;
use actix_web::{Application, http, httpcodes, middleware};
use actix_web::{http, middleware, Application, HttpResponse};
fn main() {
let app = Application::new()
@ -144,8 +144,8 @@ fn main() {
.header("X-Version", "0.2")
.finish())
.resource("/test", |r| {
r.method(http::Method::GET).f(|req| httpcodes::HttpOk);
r.method(http::Method::HEAD).f(|req| httpcodes::HttpMethodNotAllowed);
r.method(http::Method::GET).f(|req| HttpResponse::Ok());
r.method(http::Method::HEAD).f(|req| HttpResponse::MethodNotAllowed());
})
.finish();
}

View File

@ -112,8 +112,8 @@ fn index(req: HttpRequest<State>) -> Box<Future<Item=HttpResponse, Error=Error>>
.from_err()
.and_then(|res| {
match res {
Ok(user) => Ok(httpcodes::HttpOk.build().json(user)?),
Err(_) => Ok(httpcodes::HttpInternalServerError.into())
Ok(user) => Ok(HttpResponse::Ok().json(user)),
Err(_) => Ok(HttpResponse::InternalServerError().into())
}
})
.responder()

View File

@ -72,7 +72,7 @@ Here is full source of main.rs file:
```rust
# use std::thread;
extern crate actix_web;
use actix_web::*;
use actix_web::{Application, HttpRequest, HttpResponse, HttpServer};
fn index(req: HttpRequest) -> &'static str {
"Hello world!"

View File

@ -19,7 +19,7 @@ but path `/application` would not match.
```rust,ignore
# extern crate actix_web;
# extern crate tokio_core;
# use actix_web::*;
# use actix_web::{*, http::Method};
# fn index(req: HttpRequest) -> &'static str {
# "Hello world!"
# }
@ -43,18 +43,18 @@ Multiple applications can be served with one server:
# extern crate tokio_core;
# use tokio_core::net::TcpStream;
# use std::net::SocketAddr;
use actix_web::*;
use actix_web::{Application, HttpResponse, HttpServer};
fn main() {
HttpServer::new(|| vec![
Application::new()
.prefix("/app1")
.resource("/", |r| r.f(|r| httpcodes::HttpOk)),
.resource("/", |r| r.f(|r| HttpResponse::Ok())),
Application::new()
.prefix("/app2")
.resource("/", |r| r.f(|r| httpcodes::HttpOk)),
.resource("/", |r| r.f(|r| HttpResponse::Ok())),
Application::new()
.resource("/", |r| r.f(|r| httpcodes::HttpOk)),
.resource("/", |r| r.f(|r| HttpResponse::Ok())),
]);
}
```

View File

@ -13,14 +13,14 @@ within a properly configured actix system:
# extern crate actix;
# extern crate actix_web;
use actix::*;
use actix_web::*;
use actix_web::{server, Application, HttpResponse};
fn main() {
let sys = actix::System::new("guide");
HttpServer::new(
server::new(
|| Application::new()
.resource("/", |r| r.h(httpcodes::HttpOk)))
.resource("/", |r| r.f(|_| HttpResponse::Ok())))
.bind("127.0.0.1:59080").unwrap()
.start();
@ -46,18 +46,19 @@ address of the started http server. Actix http server accepts several messages:
# extern crate actix;
# extern crate actix_web;
# use futures::Future;
use actix_web::*;
use std::thread;
use std::sync::mpsc;
use actix::*;
use actix_web::{server, Application, HttpResponse, HttpServer};
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let sys = actix::System::new("http-server");
let addr = HttpServer::new(
let addr = server::new(
|| Application::new()
.resource("/", |r| r.h(httpcodes::HttpOk)))
.resource("/", |r| r.f(|_| HttpResponse::Ok())))
.bind("127.0.0.1:0").expect("Can not bind to 127.0.0.1:0")
.shutdown_timeout(60) // <- Set shutdown timeout to 60 seconds
.start();
@ -80,12 +81,12 @@ can be overridden with the `HttpServer::threads()` method.
```rust
# extern crate actix_web;
# extern crate tokio_core;
use actix_web::*;
use actix_web::{Application, HttpServer, HttpResponse};
fn main() {
HttpServer::new(
|| Application::new()
.resource("/", |r| r.h(httpcodes::HttpOk)))
.resource("/", |r| r.f(|_| HttpResponse::Ok())))
.threads(4); // <- Start 4 workers
}
```
@ -109,16 +110,16 @@ use std::fs::File;
use actix_web::*;
fn main() {
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();
HttpServer::new(
|| Application::new()
.resource("/index.html", |r| r.f(index)))
.bind("127.0.0.1:8080").unwrap()
.serve_ssl(pkcs12).unwrap();
.serve_ssl(builder).unwrap();
}
```
@ -142,22 +143,22 @@ connection behavior is defined by server settings.
```rust
# extern crate actix_web;
# extern crate tokio_core;
use actix_web::*;
use actix_web::{server, Application, HttpResponse};
fn main() {
HttpServer::new(||
server::new(||
Application::new()
.resource("/", |r| r.h(httpcodes::HttpOk)))
.resource("/", |r| r.f(|_| HttpResponse::Ok())))
.keep_alive(75); // <- Set keep-alive to 75 seconds
HttpServer::new(||
server::new(||
Application::new()
.resource("/", |r| r.h(httpcodes::HttpOk)))
.resource("/", |r| r.f(|_| HttpResponse::Ok())))
.keep_alive(server::KeepAlive::Tcp(75)); // <- Use `SO_KEEPALIVE` socket option.
HttpServer::new(||
server::new(||
Application::new()
.resource("/", |r| r.h(httpcodes::HttpOk)))
.resource("/", |r| r.f(|_| HttpResponse::Ok())))
.keep_alive(None); // <- Disable keep-alive
}
```
@ -172,13 +173,13 @@ and is on for *HTTP/1.1* and *HTTP/2.0*.
```rust
# extern crate actix_web;
use actix_web::{HttpRequest, HttpResponse, http, httpcodes::HttpOk};
use actix_web::{HttpRequest, HttpResponse, http};
fn index(req: HttpRequest) -> HttpResponse {
HttpOk.build()
HttpResponse::Ok()
.connection_type(http::ConnectionType::Close) // <- Close connection
.force_close() // <- Alternative method
.finish().unwrap()
.force_close() // <- Alternative method
.finish()
}
# fn main() {}
```

View File

@ -52,10 +52,8 @@ of application state objects and handler objects.
Here is an example of a handler that stores the number of processed requests:
```rust
# extern crate actix;
# extern crate actix_web;
use actix_web::*;
use actix_web::dev::Handler;
use actix_web::{Application, HttpRequest, HttpResponse, dev::Handler};
struct MyHandler(usize);
@ -65,7 +63,7 @@ impl<S> Handler<S> for MyHandler {
/// Handle request
fn handle(&mut self, req: HttpRequest<S>) -> Self::Result {
self.0 += 1;
httpcodes::HttpOk.into()
HttpResponse::Ok().into()
}
}
# fn main() {}
@ -77,8 +75,7 @@ number of requests processed per thread. A proper implementation would use `Arc`
```rust
# extern crate actix;
# extern crate actix_web;
use actix_web::*;
use actix_web::dev::Handler;
use actix_web::{server, Application, HttpRequest, HttpResponse, dev::Handler};
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
@ -90,7 +87,7 @@ impl<S> Handler<S> for MyHandler {
/// Handle request
fn handle(&mut self, req: HttpRequest<S>) -> Self::Result {
self.0.fetch_add(1, Ordering::Relaxed);
httpcodes::HttpOk.into()
HttpResponse::Ok().into()
}
}
@ -99,7 +96,7 @@ fn main() {
let inc = Arc::new(AtomicUsize::new(0));
HttpServer::new(
server::new(
move || {
let cloned = inc.clone();
Application::new()
@ -148,7 +145,7 @@ impl Responder for MyObj {
// Create response and set content type
Ok(HttpResponse::Ok()
.content_type("application/json")
.body(body)?)
.body(body))
}
}
@ -189,10 +186,9 @@ that implements the [*Responder*](../actix_web/trait.Responder.html) trait. In t
# use futures::future::{Future, result};
fn index(req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
result(HttpResponse::Ok()
.content_type("text/html")
.body(format!("Hello!"))
.map_err(|e| e.into()))
result(Ok(HttpResponse::Ok()
.content_type("text/html")
.body(format!("Hello!"))))
.responder()
}
@ -224,7 +220,7 @@ fn index(req: HttpRequest) -> HttpResponse {
HttpResponse::Ok()
.content_type("application/json")
.body(Body::Streaming(Box::new(body))).unwrap()
.body(Body::Streaming(Box::new(body)))
}
fn main() {
@ -253,9 +249,9 @@ fn index(req: HttpRequest) -> Result<Box<Future<Item=HttpResponse, Error=Error>>
Err(error::ErrorBadRequest("bad request"))
} else {
Ok(Box::new(
result(HttpResponse::Ok()
result(Ok(HttpResponse::Ok()
.content_type("text/html")
.body(format!("Hello!")))))
.body(format!("Hello!"))))))
}
}
#
@ -281,20 +277,19 @@ For this case the [*Either*](../actix_web/enum.Either.html) type can be used.
# use actix_web::*;
# use futures::future::Future;
use futures::future::result;
use actix_web::{Either, Error, HttpResponse, httpcodes};
use actix_web::{Either, Error, HttpResponse};
type RegisterResult = Either<HttpResponse, Box<Future<Item=HttpResponse, Error=Error>>>;
fn index(req: HttpRequest) -> RegisterResult {
if is_a_variant() { // <- choose variant A
Either::A(
httpcodes::HttpBadRequest.with_body("Bad data"))
HttpResponse::BadRequest().body("Bad data"))
} else {
Either::B( // <- variant B
result(HttpResponse::Ok()
result(Ok(HttpResponse::Ok()
.content_type("text/html")
.body(format!("Hello!"))
.map_err(|e| e.into())).responder())
.body(format!("Hello!")))).responder())
}
}
# fn is_a_variant() -> bool { true }

View File

@ -70,7 +70,7 @@ to return different responses for different types of errors.
```rust
# extern crate actix_web;
#[macro_use] extern crate failure;
use actix_web::{Application, Body, HttpRequest, HttpResponse, http, error};
use actix_web::{Application, HttpRequest, HttpResponse, http, error};
#[derive(Fail, Debug)]
enum MyError {
@ -86,11 +86,11 @@ impl error::ResponseError for MyError {
fn error_response(&self) -> HttpResponse {
match *self {
MyError::InternalError => HttpResponse::new(
http::StatusCode::INTERNAL_SERVER_ERROR, Body::Empty),
http::StatusCode::INTERNAL_SERVER_ERROR),
MyError::BadClientData => HttpResponse::new(
http::StatusCode::BAD_REQUEST, Body::Empty),
http::StatusCode::BAD_REQUEST),
MyError::Timeout => HttpResponse::new(
http::StatusCode::GATEWAY_TIMEOUT, Body::Empty),
http::StatusCode::GATEWAY_TIMEOUT),
}
}
}

View File

@ -22,7 +22,6 @@ and a resource configuration function.
```rust
# extern crate actix_web;
# use actix_web::{Application, HttpRequest, HttpResponse, http::Method};
# use actix_web::httpcodes::HttpOk;
#
# fn index(req: HttpRequest) -> HttpResponse {
# unimplemented!()
@ -32,7 +31,7 @@ fn main() {
Application::new()
.resource("/prefix", |r| r.f(index))
.resource("/user/{name}",
|r| r.method(Method::GET).f(|req| HttpOk))
|r| r.method(Method::GET).f(|req| HttpResponse::Ok()))
.finish();
}
```
@ -62,7 +61,6 @@ any number of *predicates* but only one handler.
```rust
# extern crate actix_web;
# use actix_web::*;
# use actix_web::httpcodes::*;
fn main() {
Application::new()
@ -70,13 +68,13 @@ fn main() {
resource.route()
.filter(pred::Get())
.filter(pred::Header("content-type", "text/plain"))
.f(|req| HttpOk)
.f(|req| HttpResponse::Ok())
)
.finish();
}
```
In this example `HttpOk` is returned for *GET* requests,
In this example `HttpResponse::Ok()` is returned for *GET* requests,
if request contains `Content-Type` header and value of this header is *text/plain*
and path equals to `/path`. Resource calls handle of the first matching route.
If a resource can not match any route a "NOT FOUND" response is returned.
@ -367,18 +365,17 @@ resource with the name "foo" and the pattern "{a}/{b}/{c}", you might do this:
```rust
# extern crate actix_web;
# use actix_web::{Application, HttpRequest, HttpResponse, http::Method};
# use actix_web::httpcodes::HttpOk;
#
fn index(req: HttpRequest) -> HttpResponse {
let url = req.url_for("foo", &["1", "2", "3"]); // <- generate url for "foo" resource
HttpOk.into()
HttpResponse::Ok().into()
}
fn main() {
let app = Application::new()
.resource("/test/{a}/{b}/{c}", |r| {
r.name("foo"); // <- set resource name, then it could be used in `url_for`
r.method(Method::GET).f(|_| HttpOk);
r.method(Method::GET).f(|_| HttpResponse::Ok());
})
.finish();
}
@ -397,12 +394,12 @@ for URL generation purposes only and are never considered for matching at reques
```rust
# extern crate actix_web;
use actix_web::*;
use actix_web::{Application, HttpRequest, HttpResponse, Error};
fn index(mut req: HttpRequest) -> Result<HttpResponse> {
fn index(mut req: HttpRequest) -> Result<HttpResponse, Error> {
let url = req.url_for("youtube", &["oHg5SJYRHA0"])?;
assert_eq!(url.as_str(), "https://youtube.com/watch/oHg5SJYRHA0");
Ok(httpcodes::HttpOk.into())
Ok(HttpResponse::Ok().into())
}
fn main() {
@ -439,8 +436,8 @@ This handler designed to be use as a handler for application's *default resource
# use actix_web::*;
use actix_web::http::NormalizePath;
#
# fn index(req: HttpRequest) -> httpcodes::StaticResponse {
# httpcodes::HttpOk
# fn index(req: HttpRequest) -> HttpResponse {
# HttpResponse::Ok().into()
# }
fn main() {
let app = Application::new()
@ -462,10 +459,10 @@ It is possible to register path normalization only for *GET* requests only:
```rust
# extern crate actix_web;
# #[macro_use] extern crate serde_derive;
use actix_web::{Application, HttpRequest, http::Method, http::NormalizePath, httpcodes};
use actix_web::{Application, HttpRequest, http::Method, http::NormalizePath};
#
# fn index(req: HttpRequest) -> httpcodes::StaticResponse {
# httpcodes::HttpOk
# fn index(req: HttpRequest) -> &'static str {
# "test"
# }
fn main() {
let app = Application::new()
@ -519,18 +516,15 @@ Here is a simple predicate that check that a request contains a specific *header
```rust
# extern crate actix_web;
# extern crate http;
# use actix_web::*;
# use actix_web::httpcodes::*;
use http::header::CONTENT_TYPE;
use actix_web::pred::Predicate;
use actix_web::{http, pred::Predicate, Application, HttpRequest};
struct ContentTypeHeader;
impl<S: 'static> Predicate<S> for ContentTypeHeader {
fn check(&self, req: &mut HttpRequest<S>) -> bool {
req.headers().contains_key(CONTENT_TYPE)
req.headers().contains_key(http::header::CONTENT_TYPE)
}
}
@ -539,7 +533,7 @@ fn main() {
.resource("/index.html", |r|
r.route()
.filter(ContentTypeHeader)
.h(HttpOk));
.f(|_| HttpResponse::Ok()));
}
```
@ -559,15 +553,14 @@ except "GET":
# extern crate actix_web;
# extern crate http;
# use actix_web::*;
# use actix_web::httpcodes::*;
use actix_web::pred;
use actix_web::{pred, Application, HttpResponse};
fn main() {
Application::new()
.resource("/index.html", |r|
r.route()
.filter(pred::Not(pred::Get()))
.f(|req| HttpMethodNotAllowed))
.f(|req| HttpResponse::MethodNotAllowed()))
.finish();
}
```
@ -596,14 +589,14 @@ with `Application::resource()` method.
```rust
# extern crate actix_web;
use actix_web::{Application, http::Method, pred};
use actix_web::httpcodes::{HttpNotFound, HttpMethodNotAllowed};
use actix_web::{Application, HttpResponse, http::Method, pred};
fn main() {
Application::new()
.default_resource(|r| {
r.method(Method::GET).f(|req| HttpNotFound);
r.route().filter(pred::Not(pred::Get())).f(|req| HttpMethodNotAllowed);
r.method(Method::GET).f(|req| HttpResponse::NotFound());
r.route().filter(pred::Not(pred::Get()))
.f(|req| HttpResponse::MethodNotAllowed());
})
# .finish();
}

View File

@ -19,7 +19,7 @@ fn index(req: HttpRequest) -> HttpResponse {
.content_encoding(ContentEncoding::Br)
.content_type("plain/text")
.header("X-Hdr", "sample")
.body("data").unwrap()
.body("data")
}
# fn main() {}
```
@ -50,7 +50,7 @@ use actix_web::{HttpRequest, HttpResponse, http::ContentEncoding};
fn index(req: HttpRequest) -> HttpResponse {
HttpResponse::Ok()
.content_encoding(ContentEncoding::Br)
.body("data").unwrap()
.body("data")
}
# fn main() {}
```
@ -82,7 +82,7 @@ fn index(mut req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
req.json().from_err()
.and_then(|val: MyObj| {
println!("model: {:?}", val);
Ok(httpcodes::HttpOk.build().json(val)?) // <- send response
Ok(HttpResponse::Ok().json(val)) // <- send response
})
.responder()
}
@ -115,7 +115,7 @@ fn index(req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
// synchronous workflow
.and_then(|body| { // <- body is loaded, now we can deserialize json
let obj = serde_json::from_slice::<MyObj>(&body)?;
Ok(httpcodes::HttpOk.build().json(obj)?) // <- send response
Ok(HttpResponse::Ok().json(obj)) // <- send response
})
.responder()
}
@ -178,7 +178,7 @@ use futures::stream::once;
fn index(req: HttpRequest) -> HttpResponse {
HttpResponse::Ok()
.chunked()
.body(Body::Streaming(Box::new(once(Ok(Bytes::from_static(b"data")))))).unwrap()
.body(Body::Streaming(Box::new(once(Ok(Bytes::from_static(b"data"))))))
}
# fn main() {}
```
@ -249,7 +249,7 @@ fn index(mut req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
.from_err()
.and_then(|params| { // <- url encoded parameters
println!("==== BODY ==== {:?}", params);
ok(httpcodes::HttpOk.into())
ok(HttpResponse::Ok().into())
})
.responder()
}
@ -278,7 +278,7 @@ fn index(mut req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
println!("Chunk: {:?}", chunk);
result::<_, error::PayloadError>(Ok(()))
})
.map(|_| HttpResponse::Ok().finish().unwrap())
.map(|_| HttpResponse::Ok().finish())
.responder()
}
# fn main() {}

View File

@ -11,31 +11,28 @@ You can generate a `HttpRequest` instance with `finish()` or you can
run your handler with `run()` or `run_async()`.
```rust
# extern crate http;
# extern crate actix_web;
use http::{header, StatusCode};
use actix_web::*;
use actix_web::test::TestRequest;
use actix_web::{http, test, HttpRequest, HttpResponse, HttpMessage};
fn index(req: HttpRequest) -> HttpResponse {
if let Some(hdr) = req.headers().get(header::CONTENT_TYPE) {
if let Some(hdr) = req.headers().get(http::header::CONTENT_TYPE) {
if let Ok(s) = hdr.to_str() {
return httpcodes::HttpOk.into()
return HttpResponse::Ok().into()
}
}
httpcodes::HttpBadRequest.into()
HttpResponse::BadRequest().into()
}
fn main() {
let resp = TestRequest::with_header("content-type", "text/plain")
let resp = test::TestRequest::with_header("content-type", "text/plain")
.run(index)
.unwrap();
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.status(), http::StatusCode::OK);
let resp = TestRequest::default()
let resp = test::TestRequest::default()
.run(index)
.unwrap();
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
assert_eq!(resp.status(), http::StatusCode::BAD_REQUEST);
}
```
@ -55,11 +52,11 @@ for more information.
```rust
# extern crate actix_web;
use actix_web::*;
use actix_web::{HttpRequest, HttpResponse, HttpMessage};
use actix_web::test::TestServer;
fn index(req: HttpRequest) -> HttpResponse {
httpcodes::HttpOk.into()
HttpResponse::Ok().into()
}
fn main() {
@ -77,14 +74,11 @@ The other option is to use an application factory. In this case you need to pass
function same way as you would for real http server configuration.
```rust
# extern crate http;
# extern crate actix_web;
use http::Method;
use actix_web::*;
use actix_web::test::TestServer;
use actix_web::{http, test, Application, HttpRequest, HttpResponse};
fn index(req: HttpRequest) -> HttpResponse {
httpcodes::HttpOk.into()
HttpResponse::Ok().into()
}
/// This function get called by http server.
@ -94,12 +88,13 @@ fn create_app() -> Application {
}
fn main() {
let mut srv = TestServer::with_factory(create_app); // <- Start new test server
let mut srv = test::TestServer::with_factory(create_app); // <- Start new test server
let request = srv.client(Method::GET, "/test").finish().unwrap(); // <- create client request
let response = srv.execute(request.send()).unwrap(); // <- send request to the server
let request = srv.client(
http::Method::GET, "/test").finish().unwrap(); // <- create client request
let response = srv.execute(request.send()).unwrap(); // <- send request to the server
assert!(response.status().is_success()); // <- check response
assert!(response.status().is_success()); // <- check response
}
```