Skip to content

feat: introduce http_extensions crate#326

Open
martintmk wants to merge 58 commits intomainfrom
http_extensions
Open

feat: introduce http_extensions crate#326
martintmk wants to merge 58 commits intomainfrom
http_extensions

Conversation

@martintmk
Copy link
Member

@martintmk martintmk commented Mar 17, 2026

Introduce http_extensions crate

Shared HTTP types and extension traits for clients and servers, built on the http / http-body ecosystem.

  • Core types: HttpRequest, HttpResponse, fluent builders for both, HttpBody with memory-pooled allocation via bytesbuf, and HttpError with automatic backtraces and retry/recovery classification
  • Extension traits: convenience methods on status codes, requests, responses, and headers (e.g. ensure_success(), Retry-After parsing, header extraction)
  • Middleware: RequestHandler trait for composable HTTP pipelines (via layered)
  • Testing: FakeHandler for mocking HTTP responses without network calls (test-util feature)
  • Optional: JSON support via serde (json feature)

Includes benchmarks, examples, and documentation with recipes.

@github-actions
Copy link

github-actions bot commented Mar 17, 2026

⚠️ Breaking Changes Detected

error: failed to retrieve local crate data from git revision

Caused by:
    0: failed to retrieve manifest file from git revision source
    1: possibly due to errors: [
         failed when reading /home/runner/work/oxidizer/oxidizer/target/semver-checks/git-origin_main/23fdd2c66f47b23760325f115991d841bbac1677/scripts/crate-template/Cargo.toml: TOML parse error at line 9, column 26
         |
       9 | keywords = ["oxidizer", {{CRATE_KEYWORDS}}]
         |                          ^
       missing key for inline table element, expected key
       : TOML parse error at line 9, column 26
         |
       9 | keywords = ["oxidizer", {{CRATE_KEYWORDS}}]
         |                          ^
       missing key for inline table element, expected key
       ,
         failed to parse /home/runner/work/oxidizer/oxidizer/target/semver-checks/git-origin_main/23fdd2c66f47b23760325f115991d841bbac1677/Cargo.toml: no `package` table,
       ]
    2: package `http_extensions` not found in /home/runner/work/oxidizer/oxidizer/target/semver-checks/git-origin_main/23fdd2c66f47b23760325f115991d841bbac1677

Stack backtrace:
   0: anyhow::error::<impl anyhow::Error>::msg
   1: cargo_semver_checks::rustdoc_gen::RustdocFromProjectRoot::get_crate_source
   2: cargo_semver_checks::rustdoc_gen::StatefulRustdocGenerator<cargo_semver_checks::rustdoc_gen::CoupledState>::prepare_generator
   3: cargo_semver_checks::Check::check_release::{{closure}}
   4: cargo_semver_checks::Check::check_release
   5: cargo_semver_checks::exit_on_error
   6: cargo_semver_checks::main
   7: std::sys::backtrace::__rust_begin_short_backtrace
   8: main
   9: <unknown>
  10: __libc_start_main
  11: _start

If the breaking changes are intentional then everything is fine - this message is merely informative.

Remember to apply a version number bump with the correct severity when publishing a version with breaking changes (1.x.x -> 2.x.x or 0.1.x -> 0.2.x).

@codecov
Copy link

codecov bot commented Mar 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.0%. Comparing base (1cf8d12) to head (a7bfd8d).

Additional details and impacted files
@@           Coverage Diff            @@
##             main     #326    +/-   ##
========================================
  Coverage   100.0%   100.0%            
========================================
  Files         168      186    +18     
  Lines       11902    12648   +746     
========================================
+ Hits        11902    12648   +746     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@martintmk martintmk marked this pull request as ready for review March 18, 2026 11:08
Copilot AI review requested due to automatic review settings March 18, 2026 11:08
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a new http_extensions crate to the workspace, providing shared HTTP request/response types, body handling, extension traits, and testing utilities built around the http ecosystem.

Changes:

  • Added the new crates/http_extensions crate (builders, body abstraction, extension traits, fake handler, docs, examples).
  • Wired the crate into the workspace (Cargo.toml, Cargo.lock) and listed it in root README.md / CHANGELOG.md.
  • Removed the workspace rust-toolchain.toml and updated the spelling wordlist.

Reviewed changes

Copilot reviewed 34 out of 35 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
rust-toolchain.toml Removes pinned toolchain file from repo root.
crates/http_extensions/src/url_template_label.rs Adds request extension label type for URL templates.
crates/http_extensions/src/testing.rs Adds hyper Incoming test body generator and MockIo.
crates/http_extensions/src/resilience.rs Adds IO error recoverability classification helper.
crates/http_extensions/src/request_handler.rs Introduces RequestHandler abstraction and extension trait.
crates/http_extensions/src/lib.rs New crate root: public exports, features, crate-level docs.
crates/http_extensions/src/json.rs Adds lazy JSON parsing wrapper and JSON error type.
crates/http_extensions/src/http_utils.rs Adds internal header helpers + SyncHolder.
crates/http_extensions/src/http_response_builder.rs Adds fluent HTTP response builder + tests.
crates/http_extensions/src/http_request_builder.rs Adds fluent HTTP request builder + fetch helpers + tests.
crates/http_extensions/src/fake_handler.rs Adds mock request handler for tests.
crates/http_extensions/src/extensions/status_ext.rs Adds status validation + recovery classification.
crates/http_extensions/src/extensions/response_ext.rs Adds Retry-After aware recovery classification.
crates/http_extensions/src/extensions/request_ext.rs Adds request extensions (path/query + template label).
crates/http_extensions/src/extensions/mod.rs Exposes extension trait modules.
crates/http_extensions/src/extensions/http_request_ext.rs Adds request cloning extension (when body is cloneable).
crates/http_extensions/src/extensions/header_value_ext.rs Adds HeaderValue creation from shared Bytes.
crates/http_extensions/src/extensions/header_map_ext.rs Adds typed header extraction helpers.
crates/http_extensions/src/error.rs Adds unified HttpError type with recovery metadata.
crates/http_extensions/src/constants.rs Adds internal constants (buffer limits, etc.).
crates/http_extensions/src/body.rs Adds HttpBody and HttpBodyBuilder implementation + tests.
crates/http_extensions/src/_documentation/recipes.rs Adds long-form “recipes” documentation module.
crates/http_extensions/src/_documentation/mod.rs Adds documentation module entry point.
crates/http_extensions/logo.png Adds crate logo (LFS pointer).
crates/http_extensions/favicon.ico Adds crate favicon (LFS pointer).
crates/http_extensions/examples/custom_server.rs Adds example server using hyper + layered.
crates/http_extensions/examples/custom_client.rs Adds example client implementing the service abstraction.
crates/http_extensions/README.md Adds crate README (doc2readme output).
crates/http_extensions/Cargo.toml New crate manifest and feature flags.
crates/http_extensions/CHANGELOG.md Adds initial changelog file placeholder.
README.md Lists new crate in workspace overview.
Cargo.toml Adds new workspace member dependency entry and HTTP ecosystem deps.
Cargo.lock Adds transitive deps for hyper/http-body stack and new crate.
CHANGELOG.md Lists new crate changelog link in workspace changelog index.
.spelling Adds new words related to HTTP + JSON + cloning.
Comments suppressed due to low confidence (1)

rust-toolchain.toml:1

  • This change removes the workspace rust-toolchain.toml, but there are existing repo references that assume it exists (e.g. README.md mentions scripts/update_rust_toolchain.ps1 updating it, constants.env says RUST_LATEST must match it, and .delta.toml lists it as a trip-wire). If the file is being retired, those references/scripts need to be updated in the same PR; otherwise keep a minimal toolchain file in place.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Copilot AI review requested due to automatic review settings March 19, 2026 09:59
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Introduces a new http_extensions crate to the workspace, providing shared HTTP request/response types, fluent builders, extension traits, error handling, and test utilities to support both client and server HTTP workloads across the codebase.

Changes:

  • Added the new crates/http_extensions crate (core types, builders, extension traits, errors, docs, tests).
  • Added examples/benches and crate-level documentation assets (logo/favicon/README).
  • Integrated the crate into the workspace (root Cargo.toml, root README/changelogs, Cargo.lock, .spelling).

Reviewed changes

Copilot reviewed 37 out of 38 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
crates/http_extensions/src/url_template_label.rs Adds UrlTemplateLabel request extension for URL template telemetry.
crates/http_extensions/src/testing.rs Adds test-only helpers for constructing hyper::Incoming without network IO.
crates/http_extensions/src/resilience.rs Adds IO error-kind → recoverability classifier.
crates/http_extensions/src/request_handler_ext.rs Adds type-erasure helper to convert a RequestHandler into a DynamicService.
crates/http_extensions/src/request_handler.rs Introduces the sealed RequestHandler trait for middleware pipelines.
crates/http_extensions/src/lib.rs New crate root: exports types, modules, features, and top-level docs.
crates/http_extensions/src/json.rs Adds lazy JSON wrapper + JsonError integration with HttpError.
crates/http_extensions/src/http_utils.rs Adds header builder utilities + SyncHolder helper.
crates/http_extensions/src/http_response_builder.rs Adds fluent HttpResponseBuilder with tests.
crates/http_extensions/src/http_request_builder_ext.rs Adds request_builder() extension for handlers with a body builder.
crates/http_extensions/src/http_request_builder.rs Adds fluent HttpRequestBuilder with fetch helpers and extensive tests.
crates/http_extensions/src/fake_handler.rs Adds FakeHandler test utility implementing Service/RequestHandler.
crates/http_extensions/src/extensions/status_ext.rs Adds StatusExt for status validation and recovery classification.
crates/http_extensions/src/extensions/response_ext.rs Adds ResponseExt recovery classification with Retry-After support.
crates/http_extensions/src/extensions/request_ext.rs Adds RequestExt for path_and_query + template label extraction.
crates/http_extensions/src/extensions/mod.rs Wires up and re-exports extension traits.
crates/http_extensions/src/extensions/http_request_ext.rs Adds HttpRequestExt::try_clone() for replayable request bodies.
crates/http_extensions/src/extensions/header_value_ext.rs Adds HeaderValueExt::from_shared(Bytes) helper.
crates/http_extensions/src/extensions/header_map_ext.rs Adds HeaderMapExt helpers for string/typed value extraction.
crates/http_extensions/src/error.rs Adds unified HttpError and Result alias with conversions/recovery.
crates/http_extensions/src/constants.rs Adds constants (e.g., default response buffer limit).
crates/http_extensions/src/_documentation/recipes.rs Adds cookbook-style documentation for recommended usage patterns.
crates/http_extensions/src/_documentation/mod.rs Documentation module entrypoint.
crates/http_extensions/logo.png Adds crate documentation logo (LFS).
crates/http_extensions/favicon.ico Adds crate documentation favicon (LFS).
crates/http_extensions/examples/custom_server.rs Example: basic hyper server integrating http_extensions + layered.
crates/http_extensions/examples/custom_client.rs Example: custom client implementing Service<HttpRequest>.
crates/http_extensions/benches/http_response_builder.rs Benchmarks for response builder body construction.
crates/http_extensions/benches/http_request_builder.rs Benchmarks for request builder URIs/bodies/headers.
crates/http_extensions/README.md Crate README (doc2readme output).
crates/http_extensions/Cargo.toml New crate manifest, features, deps, examples/benches configuration.
crates/http_extensions/CHANGELOG.md New crate changelog entry.
README.md Adds http_extensions to workspace crate list.
Cargo.toml Adds workspace dependency entry + shared deps for http/hyper ecosystem.
Cargo.lock Locks newly introduced dependencies.
CHANGELOG.md Adds http_extensions crate changelog link.
.spelling Updates spelling dictionary for newly introduced terminology.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Copilot AI review requested due to automatic review settings March 19, 2026 14:00
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

martintmk and others added 2 commits March 19, 2026 15:43
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 19, 2026 14:44
martintmk and others added 3 commits March 19, 2026 15:45
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 37 out of 38 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (6)

crates/http_extensions/src/request_handler.rs:1

  • Future is used in trait/impl return types but isn't in scope in this file, which will not compile. Import std::future::Future (or fully-qualify the trait in these signatures).
    crates/http_extensions/src/request_handler.rs:1
  • Future is used in trait/impl return types but isn't in scope in this file, which will not compile. Import std::future::Future (or fully-qualify the trait in these signatures).
    crates/http_extensions/src/request_handler_ext.rs:1
  • Future is referenced in the return type but isn't imported in this module, causing a compile error. Add use std::future::Future; (or qualify as std::future::Future).
    crates/http_extensions/src/lib.rs:1
  • These crate-level doc examples pass body_builder directly, but the builder constructors take &HttpBodyBuilder. Since the function parameter is already &HttpBodyBuilder, these calls should pass body_builder only if new accepts &HttpBodyBuilder by value; otherwise adjust to HttpRequestBuilder::new(body_builder) only if the signature matches. Given the current signature new(creator: &HttpBodyBuilder), make sure the example matches it (typically HttpRequestBuilder::new(body_builder) is correct if body_builder is already a reference; the README examples are the ones that likely need &).
    crates/http_extensions/src/lib.rs:1
  • These crate-level doc examples pass body_builder directly, but the builder constructors take &HttpBodyBuilder. Since the function parameter is already &HttpBodyBuilder, these calls should pass body_builder only if new accepts &HttpBodyBuilder by value; otherwise adjust to HttpRequestBuilder::new(body_builder) only if the signature matches. Given the current signature new(creator: &HttpBodyBuilder), make sure the example matches it (typically HttpRequestBuilder::new(body_builder) is correct if body_builder is already a reference; the README examples are the ones that likely need &).
    crates/http_extensions/src/testing.rs:1
  • For the empty case, this allocates a Vec just to create an empty stream. Prefer an allocation-free stream (e.g., an empty iterator/stream) so test helpers don't add avoidable overhead.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 19, 2026 14:55
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 37 out of 38 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

crates/http_extensions/src/request_handler.rs:1

  • Future is referenced but not imported/qualified in this module, which will fail to compile. Add use std::future::Future; (or qualify as std::future::Future) here; the same issue appears in other new modules that use Future (e.g. request_handler_ext.rs, http_request_builder.rs, fake_handler.rs).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Copilot AI review requested due to automatic review settings March 19, 2026 17:09
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 37 out of 38 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

crates/http_extensions/src/http_utils.rs:1

  • HeadersBuilder::headers_mut currently calls self.headers_mut() inside the trait impl, which resolves to the trait method and recurses indefinitely, leading to a stack overflow when invoked. Use fully-qualified syntax to call the inherent builder methods (e.g., http::request::Builder::headers_mut(self) / http::response::Builder::headers_mut(self)), or rename the trait method to avoid the name collision.
    crates/http_extensions/src/testing.rs:1
  • For the empty-body case, stream::iter(Vec::<Result<BytesView>>::new()) allocates an empty Vec just to produce an empty stream. Prefer stream::empty() (or stream::iter(std::iter::empty())) to avoid the allocation and make the intent clearer.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

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.

3 participants