Skip to content

Check for reserved DOS names#663

Merged
Darksonn merged 2 commits into
tower-rs:mainfrom
Darksonn:tower-http-windows
May 1, 2026
Merged

Check for reserved DOS names#663
Darksonn merged 2 commits into
tower-rs:mainfrom
Darksonn:tower-http-windows

Conversation

@Darksonn

Copy link
Copy Markdown
Member

I'm not sure if there is a good implementation of reserved DOS file names that we could reuse from anywhere ...

Fixes: #662

@seanmonstar

Copy link
Copy Markdown
Collaborator

Could this be done without allocating? Both the wide collect, and the normalized case collect? Copilot suggests an alternative of putting just 7 or 8 characters into a stack array from the iterator.

@Darksonn

Copy link
Copy Markdown
Member Author

Done

@Darksonn Darksonn merged commit 91bdd3b into tower-rs:main May 1, 2026
11 checks passed
@Darksonn Darksonn deleted the tower-http-windows branch May 1, 2026 11:25
eleboucher pushed a commit to eleboucher/towonel that referenced this pull request May 5, 2026
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [tower-http](https://github.com/tower-rs/tower-http) | workspace.dependencies | patch | `0.6.8` → `0.6.9` |

---

### Release Notes

<details>
<summary>tower-rs/tower-http (tower-http)</summary>

### [`v0.6.9`](https://github.com/tower-rs/tower-http/releases/tag/tower-http-0.6.9)

[Compare Source](tower-rs/tower-http@tower-http-0.6.8...tower-http-0.6.9)

#### Added:

- `on-early-drop`: middleware that detects when a response future or response
  body is dropped before completion ([#&#8203;636])

  Two events get hooks: the response future being dropped before
  the inner service produces a response, and the response body being
  dropped before reaching end-of-stream.

  Install custom callbacks with `OnEarlyDropLayer::builder()`:

  ```rust
  use http::Request;
  use tower_http::on_early_drop::{OnBodyDropFn, OnEarlyDropLayer};

  let layer = OnEarlyDropLayer::builder()
      .on_future_drop(|req: &Request<()>| {
          let uri = req.uri().clone();
          move || eprintln!("future dropped for {}", uri)
      })
      .on_body_drop(OnBodyDropFn::new(|req: &Request<()>| {
          let uri = req.uri().clone();
          move |parts: &http::response::Parts| {
              let status = parts.status;
              move || eprintln!("body dropped for {} status {}", uri, status)
          }
      }));
  ```

  Or route both events through a `trace::OnFailure` hook with
  `EarlyDropsAsFailures`. Place this layer inside a `TraceLayer` so the
  emitted events inherit the request span:

  ```rust
  use tower::ServiceBuilder;
  use tower_http::on_early_drop::{OnEarlyDropLayer, EarlyDropsAsFailures};
  use tower_http::trace::{DefaultOnFailure, TraceLayer};

  let stack = ServiceBuilder::new()
      .layer(TraceLayer::new_for_http())
      .layer(OnEarlyDropLayer::new(
          EarlyDropsAsFailures::new(DefaultOnFailure::default()),
      ));
  ```
- `fs`: make `AsyncReadBody::with_capacity` public ([#&#8203;415])

#### Changed:

- The implicit `async-compression` feature is removed ([#&#8203;642])
- The implicit `tokio` feature is removed ([#&#8203;628])
- `fs`: no longer auto-enables the `tracing` crate feature; enable `tracing`
  explicitly to restore error logging on `ServeDir` IO failures ([#&#8203;614])

#### Fixed

- `trace`: restore failure classification at end-of-stream ([#&#8203;483])
- `follow-redirect`: support unicode URLs (swaps `iri-string` dep for
  `url`) ([#&#8203;646])
- `fs`: reject reserved Windows DOS device names (`CON`, `COM1`, etc.) in
  `ServeDir` ([#&#8203;663])

[#&#8203;415]: tower-rs/tower-http#415

[#&#8203;483]: tower-rs/tower-http#483

[#&#8203;614]: tower-rs/tower-http#614

[#&#8203;628]: tower-rs/tower-http#628

[#&#8203;636]: tower-rs/tower-http#636

[#&#8203;642]: tower-rs/tower-http#642

[#&#8203;646]: tower-rs/tower-http#646

[#&#8203;663]: tower-rs/tower-http#663

#### All the PRs

- ci: update deny action to v2 by [@&#8203;seanmonstar](https://github.com/seanmonstar) in [#&#8203;627](tower-rs/tower-http#627)
- chore: improve code comments clarity by [@&#8203;xibeiyoumian](https://github.com/xibeiyoumian) in [#&#8203;626](tower-rs/tower-http#626)
- ci: Update to actions/checkout v6 by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;629](tower-rs/tower-http#629)
- ci: msrv resolver by [@&#8203;seanmonstar](https://github.com/seanmonstar) in [#&#8203;635](tower-rs/tower-http#635)
- chore: Remove resolved cargo-deny config by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;631](tower-rs/tower-http#631)
- ci: Update to cargo-check-external-types 0.4.0 by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;633](tower-rs/tower-http#633)
- examples: Use typed default value clap config by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;634](tower-rs/tower-http#634)
- examples: Disable unused reqwest feature by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;632](tower-rs/tower-http#632)
- examples: Update to reqwest 0.13 by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;640](tower-rs/tower-http#640)
- Fix clippy warnings in warp-key-value-store example by [@&#8203;jplatte](https://github.com/jplatte) in [#&#8203;637](tower-rs/tower-http#637)
- ci: Use Swatinem/rust-cache\@&#8203;v2 to cache by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;644](tower-rs/tower-http#644)
- ci: Remove unused working-directory config by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;645](tower-rs/tower-http#645)
- Use cargo-deny graph config by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;639](tower-rs/tower-http#639)
- Fix: follow redirect unicode in [#&#8203;646](tower-rs/tower-http#646)
- doc: remove mention of deprecated bearer method in lib.rs comment by [@&#8203;VojtaStanek](https://github.com/VojtaStanek) in [#&#8203;641](tower-rs/tower-http#641)
- Allow Unicode-3.0 license by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;648](tower-rs/tower-http#648)
- fix(docs): typo by [@&#8203;carlocorradini](https://github.com/carlocorradini) in [#&#8203;649](tower-rs/tower-http#649)
- fix: remove unused GzEncoder import in decompression in [#&#8203;647](tower-rs/tower-http#647)
- docs: update Example server in [#&#8203;652](tower-rs/tower-http#652)
- Don't automatically enable tracing for fs feature by [@&#8203;ginnyTheCat](https://github.com/ginnyTheCat) in [#&#8203;614](tower-rs/tower-http#614)
- examples: Remove unnecessary trait bound by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;651](tower-rs/tower-http#651)
- Remove implicit async-compression feature by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;642](tower-rs/tower-http#642)
- fix clippy warnings by [@&#8203;alexanderkjall](https://github.com/alexanderkjall) in [#&#8203;659](tower-rs/tower-http#659)
- Check for reserved DOS names by [@&#8203;Darksonn](https://github.com/Darksonn) in [#&#8203;663](tower-rs/tower-http#663)
- enable clippy for tower-http and fix current issues by [@&#8203;GlenDC](https://github.com/GlenDC) in [#&#8203;407](tower-rs/tower-http#407)
- chore: remove implicit tokio feature by [@&#8203;WaterWhisperer](https://github.com/WaterWhisperer) in [#&#8203;628](tower-rs/tower-http#628)
- trace: adds back call to classify\_eos on trailers by [@&#8203;markdingram](https://github.com/markdingram) in [#&#8203;483](tower-rs/tower-http#483)
- Make AsyncReadBody::with\_capacity public by [@&#8203;bouk](https://github.com/bouk) in [#&#8203;415](tower-rs/tower-http#415)
- examples: Use axum::body::to\_bytes by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;650](tower-rs/tower-http#650)
- ci: Remove unnecessary protoc setup by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;665](tower-rs/tower-http#665)
- feat(on-early-drop): Add middleware for client early drop detection by [@&#8203;fbergero](https://github.com/fbergero) in [#&#8203;636](tower-rs/tower-http#636)
- chore: release tower-http 0.6.9 by [@&#8203;jlizen](https://github.com/jlizen) in [#&#8203;666](tower-rs/tower-http#666)

#### New Contributors

- [@&#8203;xibeiyoumian](https://github.com/xibeiyoumian) made their first contribution in [#&#8203;626](tower-rs/tower-http#626)
- [@&#8203;VojtaStanek](https://github.com/VojtaStanek) made their first contribution in [#&#8203;641](tower-rs/tower-http#641)
- [@&#8203;carlocorradini](https://github.com/carlocorradini) made their first contribution in [#&#8203;649](tower-rs/tower-http#649)
- [@&#8203;ginnyTheCat](https://github.com/ginnyTheCat) made their first contribution in [#&#8203;614](tower-rs/tower-http#614)
- [@&#8203;alexanderkjall](https://github.com/alexanderkjall) made their first contribution in [#&#8203;659](tower-rs/tower-http#659)
- [@&#8203;Darksonn](https://github.com/Darksonn) made their first contribution in [#&#8203;663](tower-rs/tower-http#663)
- [@&#8203;WaterWhisperer](https://github.com/WaterWhisperer) made their first contribution in [#&#8203;628](tower-rs/tower-http#628)
- [@&#8203;bouk](https://github.com/bouk) made their first contribution in [#&#8203;415](tower-rs/tower-http#415)
- [@&#8203;fbergero](https://github.com/fbergero) made their first contribution in [#&#8203;636](tower-rs/tower-http#636)
- [@&#8203;jlizen](https://github.com/jlizen) made their first contribution in [#&#8203;666](tower-rs/tower-http#666)

**Full Changelog**: <tower-rs/tower-http@tower-http-0.6.8...tower-http-0.6.9>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJ0eXBlL3BhdGNoIl19-->

Reviewed-on: https://git.erwanleboucher.dev/eleboucher/towonel/pulls/33
/// iterates the characters twice. The closure must return the same iterator each time it is
/// called.
#[cfg(any(windows, test))]
#[cfg(any(windows, test))]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw this was slipped through, but you have a double cfg statement here

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @GlenDC , would you want to cut a PR? I can if not, np

eleboucher pushed a commit to eleboucher/towonel that referenced this pull request May 20, 2026
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [tower-http](https://github.com/tower-rs/tower-http) | workspace.dependencies | patch | `0.6.8` → `0.6.9` |

---

### Release Notes

<details>
<summary>tower-rs/tower-http (tower-http)</summary>

### [`v0.6.9`](https://github.com/tower-rs/tower-http/releases/tag/tower-http-0.6.9)

[Compare Source](tower-rs/tower-http@tower-http-0.6.8...tower-http-0.6.9)

#### Added:

- `on-early-drop`: middleware that detects when a response future or response
  body is dropped before completion ([#&#8203;636])

  Two events get hooks: the response future being dropped before
  the inner service produces a response, and the response body being
  dropped before reaching end-of-stream.

  Install custom callbacks with `OnEarlyDropLayer::builder()`:

  ```rust
  use http::Request;
  use tower_http::on_early_drop::{OnBodyDropFn, OnEarlyDropLayer};

  let layer = OnEarlyDropLayer::builder()
      .on_future_drop(|req: &Request<()>| {
          let uri = req.uri().clone();
          move || eprintln!("future dropped for {}", uri)
      })
      .on_body_drop(OnBodyDropFn::new(|req: &Request<()>| {
          let uri = req.uri().clone();
          move |parts: &http::response::Parts| {
              let status = parts.status;
              move || eprintln!("body dropped for {} status {}", uri, status)
          }
      }));
  ```

  Or route both events through a `trace::OnFailure` hook with
  `EarlyDropsAsFailures`. Place this layer inside a `TraceLayer` so the
  emitted events inherit the request span:

  ```rust
  use tower::ServiceBuilder;
  use tower_http::on_early_drop::{OnEarlyDropLayer, EarlyDropsAsFailures};
  use tower_http::trace::{DefaultOnFailure, TraceLayer};

  let stack = ServiceBuilder::new()
      .layer(TraceLayer::new_for_http())
      .layer(OnEarlyDropLayer::new(
          EarlyDropsAsFailures::new(DefaultOnFailure::default()),
      ));
  ```
- `fs`: make `AsyncReadBody::with_capacity` public ([#&#8203;415])

#### Changed:

- The implicit `async-compression` feature is removed ([#&#8203;642])
- The implicit `tokio` feature is removed ([#&#8203;628])
- `fs`: no longer auto-enables the `tracing` crate feature; enable `tracing`
  explicitly to restore error logging on `ServeDir` IO failures ([#&#8203;614])

#### Fixed

- `trace`: restore failure classification at end-of-stream ([#&#8203;483])
- `follow-redirect`: support unicode URLs (swaps `iri-string` dep for
  `url`) ([#&#8203;646])
- `fs`: reject reserved Windows DOS device names (`CON`, `COM1`, etc.) in
  `ServeDir` ([#&#8203;663])

[#&#8203;415]: tower-rs/tower-http#415

[#&#8203;483]: tower-rs/tower-http#483

[#&#8203;614]: tower-rs/tower-http#614

[#&#8203;628]: tower-rs/tower-http#628

[#&#8203;636]: tower-rs/tower-http#636

[#&#8203;642]: tower-rs/tower-http#642

[#&#8203;646]: tower-rs/tower-http#646

[#&#8203;663]: tower-rs/tower-http#663

#### All the PRs

- ci: update deny action to v2 by [@&#8203;seanmonstar](https://github.com/seanmonstar) in [#&#8203;627](tower-rs/tower-http#627)
- chore: improve code comments clarity by [@&#8203;xibeiyoumian](https://github.com/xibeiyoumian) in [#&#8203;626](tower-rs/tower-http#626)
- ci: Update to actions/checkout v6 by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;629](tower-rs/tower-http#629)
- ci: msrv resolver by [@&#8203;seanmonstar](https://github.com/seanmonstar) in [#&#8203;635](tower-rs/tower-http#635)
- chore: Remove resolved cargo-deny config by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;631](tower-rs/tower-http#631)
- ci: Update to cargo-check-external-types 0.4.0 by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;633](tower-rs/tower-http#633)
- examples: Use typed default value clap config by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;634](tower-rs/tower-http#634)
- examples: Disable unused reqwest feature by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;632](tower-rs/tower-http#632)
- examples: Update to reqwest 0.13 by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;640](tower-rs/tower-http#640)
- Fix clippy warnings in warp-key-value-store example by [@&#8203;jplatte](https://github.com/jplatte) in [#&#8203;637](tower-rs/tower-http#637)
- ci: Use Swatinem/rust-cache\@&#8203;v2 to cache by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;644](tower-rs/tower-http#644)
- ci: Remove unused working-directory config by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;645](tower-rs/tower-http#645)
- Use cargo-deny graph config by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;639](tower-rs/tower-http#639)
- Fix: follow redirect unicode in [#&#8203;646](tower-rs/tower-http#646)
- doc: remove mention of deprecated bearer method in lib.rs comment by [@&#8203;VojtaStanek](https://github.com/VojtaStanek) in [#&#8203;641](tower-rs/tower-http#641)
- Allow Unicode-3.0 license by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;648](tower-rs/tower-http#648)
- fix(docs): typo by [@&#8203;carlocorradini](https://github.com/carlocorradini) in [#&#8203;649](tower-rs/tower-http#649)
- fix: remove unused GzEncoder import in decompression in [#&#8203;647](tower-rs/tower-http#647)
- docs: update Example server in [#&#8203;652](tower-rs/tower-http#652)
- Don't automatically enable tracing for fs feature by [@&#8203;ginnyTheCat](https://github.com/ginnyTheCat) in [#&#8203;614](tower-rs/tower-http#614)
- examples: Remove unnecessary trait bound by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;651](tower-rs/tower-http#651)
- Remove implicit async-compression feature by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;642](tower-rs/tower-http#642)
- fix clippy warnings by [@&#8203;alexanderkjall](https://github.com/alexanderkjall) in [#&#8203;659](tower-rs/tower-http#659)
- Check for reserved DOS names by [@&#8203;Darksonn](https://github.com/Darksonn) in [#&#8203;663](tower-rs/tower-http#663)
- enable clippy for tower-http and fix current issues by [@&#8203;GlenDC](https://github.com/GlenDC) in [#&#8203;407](tower-rs/tower-http#407)
- chore: remove implicit tokio feature by [@&#8203;WaterWhisperer](https://github.com/WaterWhisperer) in [#&#8203;628](tower-rs/tower-http#628)
- trace: adds back call to classify\_eos on trailers by [@&#8203;markdingram](https://github.com/markdingram) in [#&#8203;483](tower-rs/tower-http#483)
- Make AsyncReadBody::with\_capacity public by [@&#8203;bouk](https://github.com/bouk) in [#&#8203;415](tower-rs/tower-http#415)
- examples: Use axum::body::to\_bytes by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;650](tower-rs/tower-http#650)
- ci: Remove unnecessary protoc setup by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;665](tower-rs/tower-http#665)
- feat(on-early-drop): Add middleware for client early drop detection by [@&#8203;fbergero](https://github.com/fbergero) in [#&#8203;636](tower-rs/tower-http#636)
- chore: release tower-http 0.6.9 by [@&#8203;jlizen](https://github.com/jlizen) in [#&#8203;666](tower-rs/tower-http#666)

#### New Contributors

- [@&#8203;xibeiyoumian](https://github.com/xibeiyoumian) made their first contribution in [#&#8203;626](tower-rs/tower-http#626)
- [@&#8203;VojtaStanek](https://github.com/VojtaStanek) made their first contribution in [#&#8203;641](tower-rs/tower-http#641)
- [@&#8203;carlocorradini](https://github.com/carlocorradini) made their first contribution in [#&#8203;649](tower-rs/tower-http#649)
- [@&#8203;ginnyTheCat](https://github.com/ginnyTheCat) made their first contribution in [#&#8203;614](tower-rs/tower-http#614)
- [@&#8203;alexanderkjall](https://github.com/alexanderkjall) made their first contribution in [#&#8203;659](tower-rs/tower-http#659)
- [@&#8203;Darksonn](https://github.com/Darksonn) made their first contribution in [#&#8203;663](tower-rs/tower-http#663)
- [@&#8203;WaterWhisperer](https://github.com/WaterWhisperer) made their first contribution in [#&#8203;628](tower-rs/tower-http#628)
- [@&#8203;bouk](https://github.com/bouk) made their first contribution in [#&#8203;415](tower-rs/tower-http#415)
- [@&#8203;fbergero](https://github.com/fbergero) made their first contribution in [#&#8203;636](tower-rs/tower-http#636)
- [@&#8203;jlizen](https://github.com/jlizen) made their first contribution in [#&#8203;666](tower-rs/tower-http#666)

**Full Changelog**: <tower-rs/tower-http@tower-http-0.6.8...tower-http-0.6.9>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJ0eXBlL3BhdGNoIl19-->

Reviewed-on: https://git.erwanleboucher.dev/eleboucher/towonel/pulls/33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Potential Windows Reserved Device Name Handling Issue in the Common axum Static File Stack via tower-http::ServeDir

4 participants