Skip to content

Commit

Permalink
Merge branch 'tokio-rs:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
bengsparks authored Oct 19, 2024
2 parents 6ecdc05 + 89fec69 commit 6cbf725
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 20 deletions.
41 changes: 26 additions & 15 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:

jobs:
check:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: taiki-e/install-action@protoc
Expand All @@ -22,41 +22,44 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
prefix-key: "v0-rust-ubuntu-24.04"
- name: Check
run: cargo clippy --workspace --all-targets --all-features -- -D warnings
- name: rustfmt
run: cargo fmt --all --check

check-docs:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
prefix-key: "v0-rust-ubuntu-24.04"
- name: cargo doc
env:
RUSTDOCFLAGS: "-D rustdoc::all -A rustdoc::private-doc-tests"
run: cargo doc --all-features --no-deps

cargo-hack:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: taiki-e/install-action@protoc
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
prefix-key: "v0-rust-ubuntu-24.04"
- name: Install cargo-hack
run: |
curl -LsSf https://github.com/taiki-e/cargo-hack/releases/latest/download/cargo-hack-x86_64-unknown-linux-gnu.tar.gz | tar xzf - -C ~/.cargo/bin
- name: cargo hack check
run: cargo hack check --each-feature --no-dev-deps --all

cargo-public-api-crates:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
strategy:
matrix:
crate: [axum, axum-core, axum-extra, axum-macros]
Expand All @@ -69,6 +72,7 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
prefix-key: "v0-rust-ubuntu-24.04"
- name: Install cargo-public-api-crates
run: |
cargo install --git https://github.com/davidpdrsn/cargo-public-api-crates
Expand All @@ -80,7 +84,7 @@ jobs:

test-versions:
needs: check
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
strategy:
matrix:
rust: [stable, beta]
Expand All @@ -93,13 +97,14 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
prefix-key: "v0-rust-ubuntu-24.04"
- name: Run tests
run: cargo test --workspace --all-features --all-targets

# some examples doesn't support our MSRV so we only test axum itself on our MSRV
# some examples don't support our MSRV so we only test axum itself on our MSRV
test-nightly:
needs: check
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Get rust-toolchain version
Expand All @@ -111,15 +116,16 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
prefix-key: "v0-rust-ubuntu-24.04"
- name: Run nightly tests
working-directory: axum-macros
run: cargo test

# some examples doesn't support our MSRV (such as async-graphql)
# some examples don't support our MSRV (such as async-graphql)
# so we only test axum itself on our MSRV
test-msrv:
needs: check
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
Expand All @@ -130,6 +136,7 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
prefix-key: "v0-rust-ubuntu-24.04"
- name: Select minimal version
run: cargo +nightly update -Z minimal-versions
- name: Fix up Cargo.lock
Expand Down Expand Up @@ -157,19 +164,20 @@ jobs:
test-docs:
needs: check
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
prefix-key: "v0-rust-ubuntu-24.04"
- name: Run doc tests
run: cargo test --all-features --doc

deny-check:
name: cargo-deny check
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
continue-on-error: ${{ matrix.checks == 'advisories' }}
strategy:
matrix:
Expand All @@ -185,7 +193,7 @@ jobs:

armv5te-unknown-linux-musleabi:
needs: check
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
Expand All @@ -194,6 +202,7 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
prefix-key: "v0-rust-ubuntu-24.04"
- name: Check
env:
# Clang has native cross-compilation support
Expand All @@ -211,7 +220,7 @@ jobs:
wasm32-unknown-unknown:
needs: check
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
Expand All @@ -220,6 +229,7 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
prefix-key: "v0-rust-ubuntu-24.04"
- name: Check
run: >
cargo
Expand All @@ -228,13 +238,14 @@ jobs:
--target wasm32-unknown-unknown
dependencies-are-sorted:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@beta
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
prefix-key: "v0-rust-ubuntu-24.04"
- name: Install cargo-sort
run: |
cargo install cargo-sort
Expand All @@ -247,7 +258,7 @@ jobs:
typos:
name: Spell Check with Typos
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
if: github.event_name == 'push' || !github.event.pull_request.draft

steps:
Expand Down
2 changes: 1 addition & 1 deletion axum-extra/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ typed-header = ["dep:headers"]
typed-routing = ["dep:axum-macros", "dep:percent-encoding", "dep:serde_html_form", "dep:form_urlencoded"]

[dependencies]
axum = { path = "../axum", version = "0.8.0-alpha.1", default-features = false }
axum = { path = "../axum", version = "0.8.0-alpha.1", default-features = false, features = ["original-uri"] }
axum-core = { path = "../axum-core", version = "0.5.0-alpha.1" }
bytes = "1.1.0"
futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
Expand Down
20 changes: 18 additions & 2 deletions axum-extra/src/routing/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Additional types for defining routes.
use axum::{
extract::Request,
extract::{OriginalUri, Request},
response::{IntoResponse, Redirect, Response},
routing::{any, MethodRouter},
Router,
Expand Down Expand Up @@ -313,7 +313,7 @@ fn add_tsr_redirect_route<S>(router: Router<S>, path: &str) -> Router<S>
where
S: Clone + Send + Sync + 'static,
{
async fn redirect_handler(uri: Uri) -> Response {
async fn redirect_handler(OriginalUri(uri): OriginalUri) -> Response {
let new_uri = map_path(uri, |path| {
path.strip_suffix('/')
.map(Cow::Borrowed)
Expand Down Expand Up @@ -432,6 +432,22 @@ mod tests {
assert_eq!(res.headers()["location"], "/foo?a=a");
}

#[tokio::test]
async fn tsr_works_in_nested_router() {
let app = Router::new().nest(
"/neko",
Router::new().route_with_tsr("/nyan/", get(|| async {})),
);

let client = TestClient::new(app);
let res = client.get("/neko/nyan/").await;
assert_eq!(res.status(), StatusCode::OK);

let res = client.get("/neko/nyan").await;
assert_eq!(res.status(), StatusCode::PERMANENT_REDIRECT);
assert_eq!(res.headers()["location"], "/neko/nyan/");
}

#[test]
#[should_panic = "Cannot add a trailing slash redirect route for `/`"]
fn tsr_at_root() {
Expand Down
2 changes: 2 additions & 0 deletions axum/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

# Unreleased

- **fixed:** Skip SSE incompatible chars of `serde_json::RawValue` in `Event::json_data` ([#2992])
- **breaking:** Move `Host` extractor to `axum-extra` ([#2956])
- **added:** Add `method_not_allowed_fallback` to set a fallback when a path matches but there is no handler for the given HTTP method ([#2903])
- **added:** Add `NoContent` as a self-described shortcut for `StatusCode::NO_CONTENT` ([#2978])
Expand All @@ -26,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#2961]: https://github.com/tokio-rs/axum/pull/2961
[#2974]: https://github.com/tokio-rs/axum/pull/2974
[#2978]: https://github.com/tokio-rs/axum/pull/2978
[#2992]: https://github.com/tokio-rs/axum/pull/2992

# 0.8.0

Expand Down
2 changes: 1 addition & 1 deletion axum/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ quickcheck = "1.0"
quickcheck_macros = "1.0"
reqwest = { version = "0.12", default-features = false, features = ["json", "stream", "multipart"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_json = { version = "1.0", features = ["raw_value"] }
time = { version = "0.3", features = ["serde-human-readable"] }
tokio = { package = "tokio", version = "1.25.0", features = ["macros", "rt", "rt-multi-thread", "net", "test-util"] }
tokio-stream = "0.1"
Expand Down
32 changes: 31 additions & 1 deletion axum/src/response/sse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,12 +208,29 @@ impl Event {
where
T: serde::Serialize,
{
struct IgnoreNewLines<'a>(bytes::buf::Writer<&'a mut BytesMut>);
impl std::io::Write for IgnoreNewLines<'_> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
let mut last_split = 0;
for delimiter in memchr::memchr2_iter(b'\n', b'\r', buf) {
self.0.write_all(&buf[last_split..delimiter])?;
last_split = delimiter + 1;
}
self.0.write_all(&buf[last_split..])?;
Ok(buf.len())
}

fn flush(&mut self) -> std::io::Result<()> {
self.0.flush()
}
}
if self.flags.contains(EventFlags::HAS_DATA) {
panic!("Called `EventBuilder::json_data` multiple times");
}

self.buffer.extend_from_slice(b"data: ");
serde_json::to_writer((&mut self.buffer).writer(), &data).map_err(axum_core::Error::new)?;
serde_json::to_writer(IgnoreNewLines((&mut self.buffer).writer()), &data)
.map_err(axum_core::Error::new)?;
self.buffer.put_u8(b'\n');

self.flags.insert(EventFlags::HAS_DATA);
Expand Down Expand Up @@ -515,6 +532,7 @@ mod tests {
use super::*;
use crate::{routing::get, test_helpers::*, Router};
use futures_util::stream;
use serde_json::value::RawValue;
use std::{collections::HashMap, convert::Infallible};
use tokio_stream::StreamExt as _;

Expand All @@ -527,6 +545,18 @@ mod tests {
assert_eq!(&*leading_space.finalize(), b"data: foobar\n\n");
}

#[test]
fn valid_json_raw_value_chars_stripped() {
let json_string = "{\r\"foo\": \n\r\r \"bar\\n\"\n}";
let json_raw_value_event = Event::default()
.json_data(serde_json::from_str::<&RawValue>(json_string).unwrap())
.unwrap();
assert_eq!(
&*json_raw_value_event.finalize(),
format!("data: {}\n\n", json_string.replace(['\n', '\r'], "")).as_bytes()
);
}

#[crate::test]
async fn basic() {
let app = Router::new().route(
Expand Down

0 comments on commit 6cbf725

Please sign in to comment.