rocket_post_as_delete/lib.rs
1//! `rocket-post-as-delete` is a Fairing for [Rocket](https://rocket.rs) rewriting
2//! requests such as `POST foo/bar/delete` into `DELETE foo/bar`.
3//!
4//! This is useful when you have web forms (which, unless you use javascript, only
5//! support POST and GET) for deleting stuff, and want to write those routes with
6//! (the more correct) `DELETE` verb.
7//!
8//! # Example
9//!
10//! ```rust
11//! use rocket::{launch, delete, routes};
12//! use rocket_post_as_delete::PostAsDelete;
13//!
14//! #[launch]
15//! fn rocket() -> _ {
16//! rocket::build()
17//! .attach(PostAsDelete)
18//! .mount("/", routes![delete_foo_bar])
19//! }
20//!
21//! #[delete("/foo/bar")]
22//! async fn delete_foo_bar() -> String {
23//! "Poof!".into()
24//! }
25//!
26//! # use rocket::local::blocking::Client;
27//! # use rocket::http::Status;
28//! # let client = Client::tracked(rocket()).expect("valid rocket instance");
29//! # let response = client.post("/foo/bar/delete").dispatch();
30//! # assert_eq!(response.status(), Status::Ok);
31//! # assert_eq!(response.into_string().unwrap(), "Poof!");
32//! ```
33//!
34//! Now forms such as this (`POST` verb, and submit URL suffixed by `/delete`):
35//! ```html
36//! <form method="post" action="/foo/bar/delete">
37//! <button>Delete me!</button>
38//! </form>
39//! ```
40//!
41//! Will run the `delete_foo_bar` route as expected.
42
43use rocket::{
44 fairing::{Fairing, Info, Kind},
45 http::Method,
46 Data, Request,
47};
48
49pub struct PostAsDelete;
50
51#[rocket::async_trait]
52impl Fairing for PostAsDelete {
53 fn info(&self) -> Info {
54 let kind = Kind::Request;
55 Info {
56 kind,
57 name: "POST as DELETE",
58 }
59 }
60
61 async fn on_request(&self, request: &mut Request<'_>, _: &mut Data<'_>) {
62 let last = request.uri().path().segments().last();
63 if request.method() == Method::Post && last == Some("delete") {
64 request.set_method(Method::Delete);
65 request.set_uri(
66 request
67 .uri()
68 .map_path(|p| p.strip_suffix("/delete").unwrap_or(p))
69 .unwrap(),
70 );
71 }
72 }
73}