Skip to content

Conversation

@guyernest
Copy link
Collaborator

Summary

Implements middleware quick wins for enhanced client-side middleware capabilities:

  1. ClientBuilder::with_middleware() - Fluent API for adding protocol middleware
  2. HttpMiddleware trait - HTTP transport-level middleware for header/payload transforms
  3. OAuthClientMiddleware - Concrete OAuth bearer token middleware implementation
  4. Comprehensive example - End-to-end demonstration with StreamableHttpTransport patterns

Changes

Client Middleware Integration

  • Modified src/client/mod.rs:
    • Added middleware_chain field to Client<T>
    • Added ClientBuilder::with_middleware() for fluent middleware configuration
    • Wired middleware processing into send_request() method
    • Context propagation via MiddlewareContext

HTTP Middleware Layer

  • Created src/client/http_middleware.rs:
    • HttpMiddleware trait for transport-level operations
    • HttpMiddlewareContext for request correlation and metadata
    • HttpRequest and HttpResponse structs for middleware operations
    • HttpMiddlewareChain for composing HTTP middleware
    • Priority-based execution ordering

OAuth Client Middleware

  • Created src/client/oauth_middleware.rs:
    • BearerToken struct with expiry tracking
    • OAuthClientMiddleware implementing HttpMiddleware
    • Automatic token injection into Authorization header
    • 401/403 detection for authentication failures
    • 7 comprehensive unit tests (100% passing)

End-to-End Example

  • Created examples/40_middleware_demo.rs:
    • Custom RequestIdMiddleware (Protocol-level)
    • Custom CorrelationHeaderMiddleware (HTTP-level)
    • Complete integration demonstration
    • Documentation of middleware flow and priorities

Test Results

✓ All 720 existing tests pass
✓ 7 new OAuth middleware tests pass
✓ Example compiles and runs successfully
✓ Doctests pass
✓ Zero clippy warnings

Documentation

  • Comprehensive rustdoc comments with examples
  • Working example in examples/40_middleware_demo.rs
  • Doctest examples in all public APIs

Related Issues

Architecture Notes

  • Two-layer middleware system:
    • Protocol-level: AdvancedMiddleware trait (MCP protocol operations)
    • HTTP-level: HttpMiddleware trait (HTTP transport operations)
  • Context propagation: Request IDs and metadata flow through entire chain
  • Priority-based execution: Critical → High → Normal → Low → Lowest
  • Foundation for future enhancements: Full OAuth flow (feat: Add OAuth client-side middleware with token injection and auto-refresh #83), retry logic, circuit breakers

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

guyernest and others added 12 commits October 7, 2025 21:28
Complete rewrite of Chapter 10 transport chapters with SDK-accurate content:

- ch10-01-websocket.md: WebSocket client + optional server transport with
  correct examples using WebSocketTransport, WebSocketConfig, and
  WebSocketServerTransport. Documented feature flag and optional server
  capabilities.

- ch10-02-http.md: HTTP client transport fundamentals with correct examples
  using HttpTransport and HttpConfig. Clarified SSE support and directed
  readers to Streamable HTTP for server deployments.

- ch10-03-streamable-http.md: Streamable HTTP server (Axum-based) and client
  with accurate examples using StreamableHttpServer, StreamableHttpServerConfig,
  StreamableHttpTransport. Documented stateless vs stateful modes, protocol
  headers, and Accept negotiation.

- ch10-transports.md: Updated WebSocket section to reflect client + optional
  server support, corrected feature flags, and added deployment guidance.

All examples verified with: cargo check --examples --features "streamable-http websocket"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Complete Chapter 11 middleware documentation covering:

- Basic Middleware trait for simple request/response interception
- Advanced AdvancedMiddleware with priority ordering, context propagation,
  conditional execution, and lifecycle hooks
- MiddlewareContext for sharing data and metrics across middleware layers
- MiddlewarePriority for controlling execution order (Critical, High, Normal,
  Low, Lowest)
- Built-in middleware implementations:
  * LoggingMiddleware - configurable logging levels
  * AuthMiddleware - authentication support
  * RetryMiddleware - retry logic with exponential backoff
  * RateLimitMiddleware - token bucket rate limiting
  * CircuitBreakerMiddleware - fault tolerance with state management
  * MetricsMiddleware - performance and usage metrics
  * CompressionMiddleware - large message compression
- Custom middleware examples (basic and advanced)
- Middleware ordering best practices and principles
- Performance considerations and optimization techniques
- Examples reference: examples/15_middleware.rs, examples/30_enhanced_middleware.rs,
  and inline doctests in src/shared/middleware.rs

All code examples verified against SDK implementation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Quick wins for middleware enhancement:

1. **ClientBuilder middleware integration**
   - Added `with_middleware()` method to ClientBuilder
   - Added `middleware_chain()` method for bulk configuration
   - Wired middleware to Client send_request/send_response flow
   - Middleware processes requests and responses via MiddlewareContext

2. **HttpMiddleware trait**
   - New HTTP-level middleware trait for transport-specific operations
   - Operates on HTTP requests/responses before MCP protocol processing
   - Supports header injection, status code handling, compression
   - HttpMiddlewareChain for composing HTTP middleware with priority ordering

3. **OAuth client middleware**
   - OAuthClientMiddleware for automatic bearer token injection
   - Token expiry tracking and validation
   - 401/403 detection with metadata for retry logic
   - Foundation for full OAuth flow (Issue paiml#83)

4. **End-to-end demonstration**
   - examples/40_middleware_demo.rs showing complete integration
   - Demonstrates Protocol-level middleware (RequestId, Metrics)
   - Demonstrates HTTP-level middleware (OAuth, Correlation headers)
   - Shows proper priority ordering and context propagation

**Testing:**
- All 720 existing tests pass
- 7 new OAuth middleware tests (all passing)
- Doctests for ClientBuilder::with_middleware() passing
- Example compiles and runs successfully

**Related Issues:**
- Implements quick wins from Issue paiml#80 discussion
- Foundation for Issue paiml#82 (HttpMiddleware)
- Foundation for Issue paiml#83 (OAuth client)
- Referenced by Issue paiml#84 (LoggingMiddleware enhancements - future)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…tegration hooks

Phase 1 (P0) foundation for HTTP middleware integration with transports.

## Changes

### HttpRequest/HttpResponse Enhancements
- Added `method` and `url` fields to `HttpRequest` for full request context
- Added helper methods: `has_header()`, `remove_header()` to `HttpRequest`
- Added `with_headers()` constructor to `HttpResponse`
- Added status helpers: `is_success()`, `is_client_error()`, `is_server_error()`
- Updated OAuth tests to use new `HttpRequest::new(method, url, body)` signature

### HttpMiddleware Trait - Error Handling
- Added `on_error()` hook for cleanup and logging when errors occur
- Documented short-circuit semantics: first error stops chain, calls on_error for all
- Added comprehensive error handling documentation with examples

### HttpMiddlewareChain - Error Propagation
- Updated `process_request()` and `process_response()` with short-circuit on error
- Added `handle_error()` private method to call on_error for all middleware
- Added `handle_transport_error()` public method for transport-level errors
- Errors from on_error hooks are logged but don't propagate (prevent cascades)

### OAuth Precedence Policy
- Implemented **Priority Order**: transport auth_provider > HttpMiddleware OAuth > extra headers
- Skip OAuth injection if `auth_already_set` metadata present in context
- Skip OAuth injection if Authorization header already exists (with warning)
- Added `on_error()` implementation with context-aware logging
- Added retry detection via `oauth.retry_used` metadata
- Added tracing: debug for skips, warn for duplicates, trace for injections, error for failures

### StreamableHttpTransportConfig
- Added `http_middleware_chain: Option<Arc<HttpMiddlewareChain>>` field
- Updated `Debug` impl to include middleware chain presence
- Updated all docstring examples to include `http_middleware_chain: None`

### StreamableHttpTransport Integration Helpers
- Added `apply_request_middleware()` helper for pre-send processing
- Added `apply_response_middleware()` helper for post-receive processing
- Helpers convert between reqwest types and HttpRequest/HttpResponse
- Implements auth precedence policy by checking Authorization header
- Calls `handle_transport_error()` on middleware failures

## Test Results
```
✓ All 421 tests pass (no regressions)
✓ OAuth middleware tests updated and passing (7 tests)
✓ Zero clippy warnings
✓ Compiles cleanly with --features full
```

## Architecture Notes

**OAuth Precedence Policy:**
1. Transport `auth_provider` sets Authorization header (highest priority)
2. If set, context metadata `auth_already_set=true` is added
3. OAuth middleware checks metadata and skips if present
4. OAuth middleware also skips if Authorization header exists (warns about duplication)
5. Extra headers applied last (lowest priority, won't override existing)

**Error Handling Flow:**
1. Middleware returns `Err()` → chain short-circuits immediately
2. `handle_error()` called for ALL middleware (allows cleanup)
3. Original error propagated to caller
4. Errors from `on_error()` itself are logged but don't propagate

**Integration Status:**
- ✅ HttpRequest/HttpResponse conversion layer complete
- ✅ Error handling and precedence policy implemented
- ✅ Helper methods for middleware integration added
- ⚠️  Full POST/SSE integration pending (requires reqwest refactor or alternate approach)
- ⚠️  HttpTransport integration pending

## Related Issues
- Part of paiml#80 - Middleware expansion tracking
- Implements review feedback from PR paiml#89
- Foundation for paiml#82, paiml#84, paiml#85 (Quick wins)

## Next Steps (Phase 1 Completion)
1. Complete POST path integration in `send_with_options()`
2. Complete SSE GET path integration in `start_sse()`
3. Add same integration to HttpTransport (hyper-based)
4. Add integration tests with StreamableHttpServer
5. Add ordering and OAuth flow tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Migrates StreamableHttpTransport from reqwest to hyper with complete middleware support.

## Changes

### Transport Migration (reqwest → hyper)
- **Client**: Changed from `reqwest::Client` to `hyper_util::client::legacy::Client<HttpConnector, Full<Bytes>>`
- **Connection pooling**: 90s idle timeout, max 10 idle per host
- **Removed dependencies**: No longer depends on reqwest types

### HTTP Middleware Integration - POST Path
- `send_with_options()`: Complete rewrite with middleware
  1. Build request via `build_request_with_middleware(Method::POST, url, body)`
  2. Add Content-Type and Accept headers
  3. Send via `client.request()`
  4. Collect response body with `response.collect().await`
  5. Run response middleware with `apply_response_middleware()`
  6. Parse modified body and send to channel

### HTTP Middleware Integration - SSE GET Path
- `start_sse()`: Complete rewrite with middleware
  1. Build request via `build_request_with_middleware(Method::GET, url, vec![])`
  2. Add Accept: text/event-stream header
  3. Add Last-Event-ID for resumability
  4. Send via `client.request()`
  5. Collect response body
  6. Run response middleware
  7. Parse SSE events from modified body
  8. Spawn task for event processing

### HTTP Middleware Integration - DELETE Path
- `close()`: Updated to use hyper
  - Sends DELETE request via `build_request_with_middleware()`
  - Gracefully handles 405 Method Not Allowed

### Middleware Helper Methods

**`build_request_with_middleware()`** - Core integration point:
```rust
async fn build_request_with_middleware(
    &self,
    method: Method,
    url: &str,
    body: Vec<u8>,
) -> Result<Request<Full<Bytes>>>
```
1. Builds hyper::Request with config headers, auth, session, protocol version
2. Creates temporary request to extract headers
3. Runs HTTP middleware on HttpRequest representation
4. Rebuilds final request with modified headers and body
5. Implements OAuth precedence: transport auth > middleware OAuth > extra headers

**`apply_response_middleware()`** - Response processing:
```rust
async fn apply_response_middleware(
    &self,
    method: &str,
    url: &str,
    response: &HyperResponse<impl hyper::body::Body>,
    body: Vec<u8>,
) -> Result<Vec<u8>>
```
1. Converts hyper::Response to HttpResponse
2. Runs middleware chain with `process_response()`
3. Returns modified body for further processing

**`process_response_headers()`** - Updated for hyper:
- Extracts session ID and protocol version from hyper::Response
- Updates transport state

## OAuth Precedence Policy (Enforced)

```
Priority Order:
1. Transport auth_provider (sets Authorization header)
   ↓
2. Set metadata: auth_already_set=true
   ↓
3. HTTP middleware (OAuth skips if metadata set)
   ↓
4. Extra headers (lowest priority)
```

**Implementation:**
- `build_request_with_middleware()` sets `has_auth` flag when auth_provider injects token
- Sets `auth_already_set` metadata in HttpMiddlewareContext
- `OAuthClientMiddleware::on_request()` checks metadata and skips if present
- Warns if Authorization header exists without metadata (duplicate config)

## Middleware Integration Points

### Request Path:
```
Client → build_request_with_middleware()
  → Add config headers
  → Add transport auth (if provider exists)
  → Create HttpRequest from headers
  → Run middleware.process_request()
  → Rebuild hyper::Request with modified headers/body
  → Send via client.request()
```

### Response Path:
```
client.request() → response
  → Collect body bytes
  → apply_response_middleware()
    → Create HttpResponse
    → Run middleware.process_response()
    → Return modified body
  → Parse and handle response
```

## Test Results
```
✓ All 421 tests pass (no regressions)
✓ Compiles cleanly with --features full
✓ Zero clippy warnings
✓ Hyper + middleware integration working end-to-end
```

## Architecture Benefits

1. **Consistency**: Both HttpTransport and StreamableHttpTransport now use hyper
2. **Middleware Control**: Clean interception points for requests and responses
3. **OAuth Precedence**: Enforced policy prevents auth header duplication
4. **Type Safety**: hyper types throughout, no reqwest/hyper mixing
5. **Performance**: Connection pooling, reusable client
6. **Extensibility**: Easy to add compression, retry, rate limiting

## Related Issues
- Completes Phase 1 (P0) of middleware integration
- Part of paiml#80 - Middleware expansion tracking
- Implements review feedback from PR paiml#89
- Foundation for paiml#82, paiml#84, paiml#85 (Quick wins)

## Next Steps (Phase 2)
1. Add integration test: StreamableHttpServer + OAuth middleware
2. Add ordering tests (multiple middleware, priority verification)
3. Add OAuth flow tests (expired token, duplicate header, no provider)
4. Add SSE reconnection tests with middleware
5. Add concurrency tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Implements Phase 2 test coverage for HTTP middleware:

## Tests Added (8 total)

1. **test_middleware_ordering**: Verifies priority-based execution
   - Request order: High(10) → Normal(30) → Low(50)
   - Response order: Reverse (Low → Normal → High)
   - Uses OrderTrackingMiddleware with AtomicUsize

2. **test_oauth_no_provider**: Verifies basic OAuth token injection

3. **test_oauth_expired_token**: Verifies expired tokens return auth error

4. **test_oauth_duplicate_header_detection**: Verifies existing Authorization
   header is preserved (not overwritten)

5. **test_oauth_precedence_policy**: Verifies auth_already_set metadata
   causes OAuth middleware to skip injection

6. **test_oauth_401_detection**: Verifies 401 response triggers error
   with metadata (auth_failure=true, status_code=401)

7. **test_middleware_short_circuit_on_error**: Verifies error in first
   middleware prevents later middleware from running

8. **test_concurrency_no_shared_state_contention**: Verifies 100 parallel
   requests through middleware chain succeed with no contention

## Test Results
- All 8 tests pass
- All 421 existing tests still pass
- Zero clippy warnings
- Clean formatting

## Coverage
- ✅ Ordering and priority verification
- ✅ OAuth flows (no provider, expired, duplicate, precedence)
- ✅ Short-circuit error handling
- ✅ Concurrency (100 parallel requests)

Part of Phase 2 test plan from PR paiml#89 review.
Optimizes response handling by checking for middleware existence before
creating temporary response objects and calling middleware processing.

## Changes

**src/shared/streamable_http.rs**:
- Added fast path check in GET SSE response handling (lines 283-295)
- Added fast path check in POST response handling (lines 586-598)
- Avoids function call overhead when no middleware is configured
- Avoids creating temporary Response objects unnecessarily
- Avoids header HashMap conversion when not needed

## Performance Impact

When no middleware is configured (the common case):
- ✅ Skips apply_response_middleware() function call
- ✅ Skips creating temporary HyperResponse object
- ✅ Skips HashMap allocation and header conversion
- ✅ Skips middleware chain lock acquisition
- ✅ Direct path: body_bytes.to_vec()

When middleware exists:
- Same behavior as before
- Only one lock acquisition instead of two

## Testing
- All 421 existing tests pass
- All 8 middleware integration tests pass
- Zero clippy warnings

Part of Phase 2 performance optimizations from PR paiml#89 review.
Comprehensive documentation updates for HTTP-level middleware system.

## Changes

**pmcp-book/src/ch11-middleware.md**:
- Added new "HTTP-Level Middleware" section (lines 824-1236)
- Architecture diagram showing two-layer middleware system
- HttpMiddleware trait documentation
- HttpRequest/HttpResponse/HttpMiddlewareContext API reference
- OAuthClientMiddleware usage and features
- OAuth precedence policy explanation
- Custom middleware examples (CorrelationHeaderMiddleware)
- ClientBuilder integration patterns
- StreamableHttpTransport integration guide
- Complete OAuth + protocol middleware example
- Middleware execution flow diagram
- Error handling and short-circuit behavior
- Priority reference for both HTTP and protocol middleware

**pmcp-book/src/ch10-03-streamable-http.md**:
- Updated client section with HTTP middleware support
- Basic client example with StreamableHttpConfig
- HTTP middleware chain integration example
- OAuth middleware usage with StreamableHttpTransport
- Features list and precedence notes
- Cross-reference to Chapter 11

## Documentation Coverage

✅ HttpMiddleware trait and chain
✅ OAuthClientMiddleware with token management
✅ OAuth precedence policy (transport > middleware > headers)
✅ ClientBuilder::with_middleware() for protocol middleware
✅ StreamableHttpConfig::with_http_middleware() for HTTP middleware
✅ Complete working examples with both layers
✅ Two-layer architecture explanation
✅ Execution flow diagrams
✅ Error handling patterns
✅ Priority ordering guidelines

Addresses documentation requirements from PR paiml#89 review.
Fixes critical header normalization bug where case-sensitive HashMap
lookups could miss headers due to case variations between hyper's
lowercase output and middleware's capitalized checks.

## Problem

HTTP headers are case-insensitive per RFC 7230, but the implementation
used HashMap<String, String> with case-sensitive lookups:

```rust
// hyper HeaderName::to_string() → "authorization" (lowercase)
// OAuth middleware check → request.has_header("Authorization")
// Result: false negative! ❌
```

This caused OAuth duplicate detection to fail when:
- Transport auth_provider added "authorization" (from hyper)
- Custom middleware added "Authorization"
- OAuth middleware failed to detect the duplicate

## Solution

Implement case-insensitive header handling by normalizing all header
names to lowercase:

**HttpRequest**:
- `add_header()`: Normalize name to lowercase on insert
- `get_header()`: Normalize name to lowercase on lookup
- `has_header()`: Normalize name to lowercase on check
- `remove_header()`: Normalize name to lowercase on removal

**HttpResponse**:
- Same normalization in all methods
- `with_headers()`: Normalizes incoming HashMap keys to lowercase

## Implementation Details

All header operations now use `.to_lowercase()`:
- Insert: `self.headers.insert(name.to_lowercase(), value)`
- Lookup: `self.headers.get(&name.to_lowercase())`
- Check: `self.headers.contains_key(&name.to_lowercase())`

This ensures HTTP header semantics match RFC 7230:
- "Authorization" == "authorization" == "AUTHORIZATION" ✅
- Works with hyper's lowercase HeaderName::to_string()
- Works with middleware using any case variation

## Test Coverage (3 new tests, 188 lines)

**test_header_case_insensitivity**:
- HttpRequest: add/get/has/remove with mixed cases
- HttpResponse: add/get/has with mixed cases
- with_headers() constructor normalization
- All case variations work correctly

**test_oauth_duplicate_detection_case_insensitive**:
- Add "AUTHORIZATION" header (uppercase)
- OAuth middleware detects it regardless of case
- No duplicate headers created
- Original header preserved

**test_middleware_chain_with_mixed_case_headers**:
- OAuth adds "Authorization" (capitalized)
- Next middleware checks with "authorization", "Authorization", "AUTHORIZATION"
- All lookups succeed
- Middleware chain works with any case variation

## Test Results

- ✅ All 11 middleware integration tests pass
- ✅ All 421 library tests pass (no regressions)
- ✅ Zero clippy warnings

## Migration to http::HeaderMap (Phase 3)

This is an interim fix. Phase 3 will migrate to http::HeaderMap which:
- Provides native case-insensitive semantics
- Handles multi-value headers correctly
- Matches HTTP standard header behavior
- Eliminates need for manual normalization

## Impact

**Before**: Header lookups could fail due to case mismatches
**After**: All header operations are case-insensitive per HTTP spec

Fixes header normalization issue identified in PR paiml#89 review.
Comprehensive real-world integration tests with actual HTTP server and
OAuth middleware. Tests full client-server flow with authentication.

## Tests Added (5 tests, 357 lines)

**test_oauth_middleware_injects_token**:
- Creates real server with StreamableHttpServer
- Configures OAuth middleware without auth_provider
- Verifies client can initialize and communicate
- OAuth middleware automatically injects Bearer token
- Server receives authenticated requests

**test_auth_provider_takes_precedence_over_oauth**:
- Configures BOTH auth_provider AND OAuth middleware
- Verifies auth_provider token wins (OAuth skips via auth_already_set)
- Tests precedence policy: transport > HTTP middleware > headers
- Custom TestAuthProvider implementation for testing

**test_oauth_token_expiry_triggers_error**:
- Creates expired token (Duration::from_secs(0))
- Waits to ensure expiration
- Verifies initialization fails with Authentication error
- Tests token expiry checking before requests

**test_multiple_requests_with_oauth**:
- Makes 5 sequential requests through OAuth middleware
- Verifies token injection happens for each request
- Tests middleware statelessness across requests
- Uses list_tools() for real client API testing

**test_oauth_with_case_insensitive_header_check**:
- Pre-configures extra_headers with "AUTHORIZATION" (uppercase)
- OAuth middleware detects it despite case difference
- Verifies case-insensitive duplicate detection works end-to-end
- Integration test for header normalization fix

## Test Coverage

✅ Real server: StreamableHttpServer on random port
✅ Real transport: StreamableHttpTransport with hyper
✅ Real middleware: OAuth token injection via HttpMiddlewareChain
✅ OAuth precedence: auth_provider > HTTP middleware
✅ Token expiry: Authentication error when expired
✅ Multiple requests: Middleware runs for each request
✅ Case insensitivity: Header detection works across case variations

## Test Results

- ✅ All 5 OAuth integration tests pass
- ✅ All 11 HTTP middleware integration tests pass
- ✅ All 421 library tests pass (no regressions)

## Implementation Details

**Server Setup**:
- Random port binding (`127.0.0.1:0`)
- Stateless mode (no session tracking)
- Simple echo tool for request verification
- Cleanup with handle.abort()

**Client Setup**:
- StreamableHttpTransportConfig with all fields
- HttpMiddlewareChain with OAuthClientMiddleware
- ClientBuilder for proper client construction
- Automatic cleanup via drop(client)

**Auth Testing**:
- BearerToken with expiry support
- Custom TestAuthProvider for precedence testing
- No manual transport access (uses Client API only)

Part of Phase 2 complex integration tests from PR paiml#89 plan.
Phase 2 complete with comprehensive integration test coverage:

SSE Middleware Integration (tests/sse_middleware_integration.rs):
- Middleware runs on initial SSE GET request
- Middleware tracks Last-Event-ID headers correctly
- Request/response processing for SSE streams
- HTTP method tracking across GET/POST requests

OAuth Retry Coordination:
- Fixed retry middleware to use on_error hook (not on_response)
- Response chain runs in reverse priority order
- OAuth (priority 10) sets metadata, retry (priority 5) reads it
- Double-retry protection via oauth.retry_used metadata

Header Normalization:
- Fixed case-sensitivity bugs in HttpRequest/HttpResponse
- All header operations now use .to_lowercase() normalization
- Case-insensitive get/has/remove operations work correctly

Config Updates:
- Added http_middleware_chain field to StreamableHttpTransportConfig
- Updated all existing usages across tests and examples
- Maintains backward compatibility with None default

Test Coverage:
- 14 HTTP middleware integration tests
- 4 SSE middleware integration tests
- 5 OAuth integration tests
Total: 23 comprehensive middleware integration tests

All tests passing with zero clippy warnings.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Clippy fixes for zero-warning policy:
- Change add_header to accept &str instead of String (needless_pass_by_value)
- Add backticks to type names in docs (doc_markdown)
- Remove unnecessary .iter() calls (explicit_iter_loop)
- Add allow(future_not_send) for hyper response reference
- Fix needless_collect by using count() directly

Updated files:
- src/client/http_middleware.rs: &str parameters
- src/client/oauth_middleware.rs: &str for add_header call
- src/shared/streamable_http.rs: iterator syntax + allow annotation
- tests/http_middleware_integration.rs: &str in test calls
- tests/sse_middleware_integration.rs: items_after_statements fix
- tests/streamable_http_oauth_integration.rs: doc markdown
- examples/40_middleware_demo.rs: &str for add_header calls

All clippy checks pass with -D warnings.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@guyernest guyernest merged commit 3baa53c into paiml:main Oct 9, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant