Update the pastebin tutorial for 0.3.

This commit is contained in:
Sergio Benitez 2017-07-04 19:36:16 -07:00
parent b2ab3861b4
commit ef2739ee50
1 changed files with 13 additions and 11 deletions

View File

@ -108,7 +108,7 @@ to them. To mount the `index` route, modify the main function so that it reads:
```rust ```rust
fn main() { fn main() {
rocket::ignite().mount("/", routes![index]).launch() rocket::ignite().mount("/", routes![index]).launch();
} }
``` ```
@ -256,7 +256,7 @@ Make sure that the route is mounted at the root path:
```rust ```rust
fn main() { fn main() {
rocket::ignite().mount("/", routes![index, upload]).launch() rocket::ignite().mount("/", routes![index, upload]).launch();
} }
``` ```
@ -296,6 +296,7 @@ paste doesn't exist.
```rust ```rust
use std::fs::File; use std::fs::File;
use rocket::http::RawStr;
#[get("/<id>")] #[get("/<id>")]
fn retrieve(id: &RawStr) -> Option<File> { fn retrieve(id: &RawStr) -> Option<File> {
@ -304,7 +305,9 @@ fn retrieve(id: &RawStr) -> Option<File> {
} }
``` ```
Unfortunately, there's a problem with this code. Can you spot the issue? Unfortunately, there's a problem with this code. Can you spot the issue? The
[`RawStr`](https://api.rocket.rs/rocket/http/struct.RawStr.html) type should tip
you off!
The issue is that the _user_ controls the value of `id`, and as a result, can The issue is that the _user_ controls the value of `id`, and as a result, can
coerce the service into opening files inside `upload/` that aren't meant to be coerce the service into opening files inside `upload/` that aren't meant to be
@ -327,7 +330,7 @@ using it. We do this by implementing `FromParam` for `PasteID` in
use rocket::request::FromParam; use rocket::request::FromParam;
/// Returns `true` if `id` is a valid paste ID and `false` otherwise. /// Returns `true` if `id` is a valid paste ID and `false` otherwise.
fn valid_id(id: &RawStr) -> bool { fn valid_id(id: &str) -> bool {
id.chars().all(|c| { id.chars().all(|c| {
(c >= 'a' && c <= 'z') (c >= 'a' && c <= 'z')
|| (c >= 'A' && c <= 'Z') || (c >= 'A' && c <= 'Z')
@ -338,9 +341,9 @@ fn valid_id(id: &RawStr) -> bool {
/// Returns an instance of `PasteID` if the path segment is a valid ID. /// Returns an instance of `PasteID` if the path segment is a valid ID.
/// Otherwise returns the invalid ID as the `Err` value. /// Otherwise returns the invalid ID as the `Err` value.
impl<'a> FromParam<'a> for PasteID<'a> { impl<'a> FromParam<'a> for PasteID<'a> {
type Error = &'a str; type Error = &'a RawStr;
fn from_param(param: &'a str) -> Result<PasteID<'a>, &'a str> { fn from_param(param: &'a RawStr) -> Result<PasteID<'a>, &'a RawStr> {
match valid_id(param) { match valid_id(param) {
true => Ok(PasteID(Cow::Borrowed(param))), true => Ok(PasteID(Cow::Borrowed(param))),
false => Err(param) false => Err(param)
@ -361,7 +364,7 @@ fn retrieve(id: PasteID) -> Option<File> {
} }
``` ```
Note that our `valid_id` function is simple and could be improved by, for Note that our `valid_id` function is simplistic and could be improved by, for
example, checking that the length of the `id` is within some known bound or example, checking that the length of the `id` is within some known bound or
potentially blacklisting sensitive files as needed. potentially blacklisting sensitive files as needed.
@ -396,11 +399,10 @@ through some of them to get a better feel for Rocket. Here are some ideas:
* Add a new route, `GET /<id>/<lang>` that syntax highlights the paste with ID * Add a new route, `GET /<id>/<lang>` that syntax highlights the paste with ID
`<id>` for language `<lang>`. If `<lang>` is not a known language, do no `<id>` for language `<lang>`. If `<lang>` is not a known language, do no
highlighting. Possibly validate `<lang>` with `FromParam`. highlighting. Possibly validate `<lang>` with `FromParam`.
* Use the [testing module](https://api.rocket.rs/rocket/testing/) to write * Use the [`local` module](https://api.rocket.rs/rocket/local/) to write
unit tests for your pastebin. unit tests for your pastebin.
* Dispatch a thread before `launch`ing Rocket in `main` that periodically * Dispatch a thread before `launch`ing Rocket in `main` that periodically
cleans up idling old pastes in `upload/`. cleans up idling old pastes in `upload/`.
You can find the full source code for the completed pastebin tutorial in the You can find the full source code for the [completed pastebin tutorial on
[Rocket Github GitHub](https://github.com/SergioBenitez/Rocket/tree/v0.2.8/examples/pastebin).
Repo](https://github.com/SergioBenitez/Rocket/tree/v0.2.8/examples/pastebin).