Skip to content

Conversation

@bplatz
Copy link
Contributor

@bplatz bplatz commented Oct 9, 2025

Summary

Fixes CORS preflight failures that can occur when browsers send requests with custom headers or non-standard content types. This ensures Fluree Server works correctly with modern web applications making cross-origin requests.

Problem

The current CORS implementation uses :any for allowed headers, which:

  1. Causes runtime errors with the ring-cors library (not a valid value)
  2. Fails browser preflight checks - browsers will block requests before they reach the server if the preflight response doesn't explicitly list allowed headers
  3. Missing OPTIONS handlers - some routes return 404 on preflight OPTIONS requests

When a browser sends a request with custom headers (like Fluree-Identity) or non-simple content types (like application/sparql-query), it first sends a preflight OPTIONS request. If the server doesn't respond correctly, the browser blocks the actual request entirely - the server never even sees it.

Changes

1. Centralized Header Management

  • Created standard-request-headers constant for common HTTP headers
  • Existing fluree-request-header-keys now serves as single source of truth
  • Created fluree-response-header-keys for headers browsers can read
  • CORS configuration now composes these constants automatically

2. Enhanced CORS Middleware

  • Replaced :any with explicit header list from constants
  • Added Access-Control-Expose-Headers so browsers can read Fluree response headers
  • Added Access-Control-Max-Age (24 hours) to cache preflight responses and reduce network overhead
  • Maintained backward-compatible defaults (wildcard origins)

3. OPTIONS Route Handlers

Added explicit OPTIONS handlers returning 204 status to all endpoints:

  • /fluree/create, /drop, /transact, /update, /insert, /upsert
  • /fluree/query, /history, /subscribe
  • All /fluree/remote/* endpoints

4. Documentation

  • Added corsOrigins to README Configuration Options
  • Included examples for development (wildcard) and production (restricted origins)
  • Documented regex pattern support

Testing

  • All existing tests pass
  • Enhanced handler_cors_test.clj to verify header constants and middleware composition
  • Manually verified preflight requests work correctly

Security Considerations

  • No security changes - maintains existing wildcard origin default
  • Users can still restrict origins via config (e.g., ["https://app.example.com"])
  • Production deployments should restrict origins; this is now documented

Backward Compatibility

✅ Fully backward compatible:

  • Same default behavior (accept all origins)
  • No configuration changes required
  • Existing corsOrigins config continues to work
  • No API changes

- Introduced `corsOrigins` configuration in README for CORS settings.
- Implemented standard request and Fluree-specific header constants in handler.
- Updated `wrap-cors` function to utilize new header constants.
- Added CORS preflight options to various routes.
- Enhanced tests to verify header constants and CORS functionality.
@bplatz bplatz requested a review from a team October 9, 2025 17:44
Copy link
Contributor

@zonotope zonotope left a comment

Choose a reason for hiding this comment

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

⌨️

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