Skip to content

Releases: http-rs/tide

v0.8.1

07 May 17:17
Compare
Choose a tag to compare

docs.rs

This patch contains several bug fixes and doc tweaks.

Added

  • Route::serve_dir now applies some degree of mime guessing #461
  • Added the "Tide Channels" post to the README #464
  • Added documentation on Tide's default backend #467

Changed

  • Updated the crate version in the README #475

Fixed

  • Check directory traversal attack without file system visit #473
  • Correctly parse multiple values from the Cookie header #484

v0.8.0

24 Apr 14:24
Compare
Choose a tag to compare

API Documentation

This patch introduces the use of the ? operator in Endpoints, initial support for Server-Sent Events, static file serving, and a new submodule hierarchy. This continues the integration of http-types we started in v0.7.0

Fallible endpoints

Tide now allows the use of ? in endpoints. Errors are automatically converted to tide::Error and have a status code of 500 assigned to them. Overriding status codes can be done through the use of the tide::Status trait which is included in the prelude.

use async_std::{fs, io};
use tide::{Response, StatusCode};

#[async_std::main]
async fn main() -> io::Result<()> {
    let mut app = tide::new();

    app.at("/").get(|_| async move {
        let mut res = Response::new(StatusCode::Ok);
        res.set_body(fs::read("my_file").await?);
        Ok(res)
    });

    app.listen("localhost:8080").await?;
    Ok(())
}

Server-Sent Events

This release makes the first steps towards integrating channels in Tide. In this release we're introducing support for Server-Sent Events, unidirectional event streams that operate over HTTP. This can be used for implementing features such as live-reloading, or sending notifications.

use tide::sse;

#[async_std::main]
async fn main() -> Result<(), std::io::Error> {
    let mut app = tide::new();
    app.at("/sse").get(sse::endpoint(|_req, sender| async move {
        sender.send("fruit", "banana", None).await;
        sender.send("fruit", "apple", None).await;
        Ok(())
    }));
    app.listen("localhost:8080").await?;
    Ok(())
}

Connecting to the stream can be done using async-sse or from the browser:

var sse = new EventSource('/sse');
sse.on("message", (ev) => console.log(ev));

In the future we may expand on these APIs to allow other endpoints to send messages on established channels, but in order to do so we need to implement session management first.

Static file serving

Tide is now able to serve static directories through the Route::serve_dir method. This allows mapping URLs to directories on disk:

#[async_std::main]
async fn main() -> Result<(), std::io::Error> {
    let mut app = tide::new();
    app.at("/public/images").serve_dir("images/")?;
    app.listen("127.0.0.1:8080").await?;
    Ok(())
}

Revamped Hierarchy

Tide has been changing a lot recently, and we've made changes to our submodules so we can keep up. We no longer have a singular middleware submodule and instead split them up by topic. This will allow us to continue to expand on Tide's capabilities, while keeping things easy to find.

Screenshot_2020-04-24 tide - Rust

Future Directions

The next step for us is to continue to integrate http-types into Tide, focusing on the Request, Response, and Body types. This will likely coincide with a http-types@2.0.0 release. After that our goal is to expand our capabilities around file serving and testing. And finally adding support for WebSockets, sessions, and TLS.

We're excited for the future of Tide, and we're glad you're here with us!

Added

  • Enabled the use of ? in Endpoint #438
  • HttpService is now directly implemented on Server #442
  • Added Route::serve_dir which can serve full directories #415
  • Added a "getting started" section to the README #445
  • Added Response::redirect_permanent #435
  • Added Response::redirect_temporary #435
  • Added the redirect submodule #450
  • Added redirect::permanent #435
  • Added the log submodule providing structured logging #451
  • Added a test for chunked encoding #437
  • Added a logo and favicon for rustdoc #459
  • Added the sse submodule providing initial Server-Sent Events support #456
  • Added tide::{Body, StatusCode}, re-exported from http-types #455
  • Added instructions to the README how to run examples #460
  • Added an example for a nesting tide server #429

Changed

  • All Endpoints now return Result<Into<Response>> #438
  • Renamed tide::redirect to tide::redirect::temporary #450
  • Logging middleware is now enabled by default #451
  • Moved CORS middleware to the security submodule #453
  • Allow tide::Result<Response> to be abbreviated as tide::Result #457
  • Replaced the use of IntoResponse with Into<Response> #463

Removed

  • Removed unused server impl code #441
  • Removed the tide::server::Service struct #442
  • Removed the tide::server submodule #442
  • Removed the tide::middleware submodule #453
  • Removed the IntoResponse trait #463

Fixed

  • Fixed CORS behavior if there is no origin header #439
  • Fixed documentation formatting in lib.rs #454
  • Fixed a stability issue in our tests regarding by opening random ports #446

v0.7.0

17 Apr 17:36
Compare
Choose a tag to compare

This patch switches Tide to use http-types for its interface, and async-h1 as its default engine. Additionally we now allow middleware to be defined on a per-route basic. Put together this is effectively an overhaul of Tide's internals, and constitutes a fairly large change.

If you're using Tide in production please be advised this release may have a different stability profile than what you've become used to in the past, and we advice upgrading with appropriate caution. If you find any critical bugs, filing a bug report on one of the issue trackers and reaching out directly over Discord is the quickest way to reach the team.

The reason we're making these changes is that it will allow us to finally polish our error handling story, severely simplify internal logic, and enable many many other features we've been wanting to implement for years now. This is a big step for the project, and we're excited to be taking it together.

Added

  • Enables per-route middleware #399
  • Added an example for chunked encoding #430

Changed

  • Made Endpoint::call generic over the lifetime #397
  • Removed Result from Request::cookie #413
  • Use async-h1 as the default engine #414
  • Use http-types as the interface types #414

Fixed

  • Fixed a path on the changelog.md #395
  • Removed unnecessary internal pin-project call #410

v0.6.0

30 Jan 16:51
d17bc0b
Compare
Choose a tag to compare

API Documentation

This patch introduces a new cookies API, based on the excellent
cookie crate. Working with cookies is a staple for
any web server, and Tide's new API now makes this entirely declarative.

Additionally we've added back CORS support. This makes it possible for
possible to configure the single-origin policy of browsers, which is an
incredibly valuable resource.

And finally nesting services with Tide has become even easier. Building on
the APIs in 0.5.0, the manual song-and-dance required to nest APIs is no
longer required, and services can now be nested as-is through the
Route::nest API.

Examples

Cookies

use cookie::Cookie;
use tide::Response;

let mut app = tide::new();

app.at("/").get(|req| async move {
    println!("cat snack: {:?}", req.cookie("snack"));
    Response::new(200)
});
app.at("/set").get(|req| async move {
    let mut res = Response::new(200);
    res.set_cookie(Cookie::new("snack", "tuna"));
    res
});
app.listen("127.0.0.1:8080").await?;

CORS

Make GET, POST, and OPTIONS endpoints on this server accessible from any web
page.

use http::header::HeaderValue;
use tide::middleware::{Cors, Origin};

let rules = Cors::new()
    .allow_methods(HeaderValue::from_static("GET, POST, OPTIONS"))
    .allow_origin(Origin::from("*"))
    .allow_credentials(false);

let mut app = tide::new();
app.middleware(rules);
app.at("/").post(|_| async { Response::new(200) });
app.listen("localhost:8080").await?;

Nesting

Nest the inner serve inside the outer service, exposing GET /cat/nori.

let mut inner = tide::new();
inner.at("/nori").get(|_| async { Response::new(200) });

let mut outer = tide::new();
outer.at("/cat").nest(inner);

outer.listen("localhost:8080").await?;

Added

  • Added Route::all to match all HTTP methods on a route (#379)
  • Added Route::nest to nest instances of tide::Server on sub-routes (#379)
  • Added a new cors submodule containing CORS control middleware (#373)
  • Added Request::cookie to get a cookie sent by the client (#380)
  • Added Response::set_cookie to instruct the client to set a cookie (#380)
  • Added Response::remove_cookie to instruct the client to unset a cookie (#380)

Changed

  • Changed the behavior of optional params in Request.query to be more intuitive (384)
  • Improved the debugging experience of query deserialization errors (384)
  • Updated the GraphQL example to use the latest version of Juniper (#372)
  • Tide no longer prints to stdout when started (387)

Fixed

  • Fixed an incorrect MIME type definition on Response::body (378)

0.5.1

20 Dec 22:53
8ccd50b
Compare
Choose a tag to compare

API Documentation

This fixes a rendering issue on docs.rs.

Fixes

  • Fix a rendering issue on docs.rs (#376)

0.5.0

20 Dec 15:29
1a9ae93
Compare
Choose a tag to compare

API Documentation

This release introduces the ability to nest applications, add logging
middleware, and improves our documentation.

Nesting applications is a useful technique that can be used to create several
sub-applications. This allows creating clear points of isolation in applications
that can be used completely independently of the main application. But can be
recombined into a single binary if required.

Being able to nest applications is also a necessary first step to re-introduce
per-route middleware, which we'll do in subsequent patches.

Examples

let mut inner = tide::new();
inner.at("/").get(|_| async { "root" });
inner.at("/foo").get(|_| async { "foo" });
inner.at("/bar").get(|_| async { "bar" });

let mut outer = tide::new();
outer
    .at("/nested")
    .strip_prefix() // catch /nested and /nested/*
    .get(inner.into_http_service()); // the prefix /nested will be stripped here

Added

  • Added Route::strip_prefix (#364)
  • Added the ability Services to be nested (#364)
  • Added middleware::RequestLogger (#367)

Changed

  • Updated and improved the documentation (#363)

0.4.0

27 Nov 21:04
Compare
Choose a tag to compare

This release is a further polishing of Tide's APIs, and works towards
significantly improving Tide's user experience. The biggest question left
unanswered after this patch is how we want to do error handling, but aside from
that the end-user API should be pretty close to where we want it to be.

The biggest changes in this patch is endpoints now take Request instead of
Context. The new Request and Response types are no longer type aliases but
concrete types, making them substantially easier to use. This also means that
we've been able to fold in all the Ext methods we were exposing, enabling
methods such as let values: Schema = req.body_json()?; to deserialize an
incoming JSON body through a Serde schema. This should make it significantly
easier to write APIs with Tide out of the box.

Example

Create a "hello world" app:

#[async_std::main]
async fn main() -> Result<(), std::io::Error> {
    let mut app = tide::new();
    app.at("/").get(|_| async move { "Hello, world!" });
    app.listen("127.0.0.1:8080").await?;
    Ok(())
}

Redirect from /nori to /chashu:

#[async_std::main]
async fn main() -> Result<(), std::io::Error> {
    let mut app = tide::new();
    app.at("/chashu").get(|_| async move { "meow" });
    app.at("/nori").get(tide::redirect("/chashu"));
    app.listen("127.0.0.1:8080").await?;
    Ok(())
}

Added

  • Added logger::RequestLogger based on log (replaces logger:RootLogger).
  • Added Request with inherent methods (replaces Context).
  • Added Server (replaces App).
  • Added Response (replacing a type alias of the same name).
  • Added a prelude submodule, holding all public traits.
  • Added a new free function, a shorthand for Server::new.
  • Added a with_state free function, a shorthand for Server::with_state.
  • Added Result type alias (replaces EndpointResult).
  • Added a redirect free function to redirect from one endpoint to another.

Changed

  • Resolved an #[allow(unused_mut)] workaround.
  • Renamed ExtractForms to ContextExt.
  • Response is now a newly defined type.

Removed

  • Removed logger::RootLogger (replaced by logger:RequestLogger).
  • Removed internal use of the box_async macro.
  • Removed Context (replaced by Request).
  • Removed the Response type alias (replaced by a new Response struct).
  • Removed App (replaced by Server).
  • Temporarily disabled the multipart family of APIs, improving compilation
    speed by ~30%.
  • Removed EndpointResult (replaced by Result).

0.3.0

31 Oct 20:45
8ba713c
Compare
Choose a tag to compare

Documentation link

This is the first release in almost 6 months; introducing a snapshot of where we
were right before splitting up the crate. This release is mostly similar to
0.2.0, but sets us up to start rewinding prior work on top.

Added

  • Added "unstable" feature flag.
  • Added example for serving static files.
  • Added keywords and categories to Cargo.toml.
  • Implemented Default for App.
  • Added App::with_state constructor method.
  • Added Context::state (replacing Context::app_data)

Changed

  • Fixed multipart uploads.
  • Fixed some doc tests.
  • Rename cookies::CookiesExt to cookies::ContextExt.
  • Rename querystring::ExtractQuery to querystring::ContextExt.
  • Switched CI provider from Travis to GitHub actions.
  • Updated README.
  • Updated all dependencies.
  • Replaced AppData with State.

Removed

  • Removed the RFCs subdirectory.
  • Removed an extra incoming license requirement.
  • Removed outdated version logs.
  • Removed rustfmt.toml.
  • Removed Context::app_data (replaced with Context::state).