Skip to content

Conversation

@marevol
Copy link
Contributor

@marevol marevol commented Nov 16, 2025

This commit improves the CORS (Cross-Origin Resource Sharing) implementation in the org.codelibs.fess.cors package with the following enhancements:

  1. Bug Fixes:

    • Fixed typo in CorsHandlerFactory: renamed 'handerMap' to 'handlerMap'
    • Changed OPTIONS preflight response from SC_ACCEPTED (202) to SC_OK (200) for better compliance with CORS standard
  2. Thread Safety:

    • Replaced HashMap with ConcurrentHashMap in CorsHandlerFactory
    • Added thread-safety documentation
  3. New Features:

    • Added Access-Control-Expose-Headers support to expose custom headers
    • Added Vary: Origin header for proper caching behavior
    • Added Access-Control-Allow-Private-Network support for private network access requests (Chrome feature)
  4. Configuration:

    • Added new config property: api.cors.expose.headers
    • Added corresponding method in FessConfig interface
    • Updated default values and documentation
  5. Code Quality:

    • Added inline comments for better code readability
    • Added new header constants in CorsHandler base class
    • Improved JavaDoc documentation
  6. Tests:

    • Updated CorsHandlerFactoryTest to use correct field name
    • Updated CorsFilterTest to expect SC_OK instead of SC_ACCEPTED

These improvements enhance security, performance, and standards compliance of the CORS implementation while maintaining backward compatibility.

@marevol marevol requested a review from Copilot November 16, 2025 11:23
@marevol marevol self-assigned this Nov 16, 2025
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 enhances the CORS implementation by fixing bugs, improving thread safety, and adding new CORS features. The changes include correcting a typo from 'handerMap' to 'handlerMap', updating the OPTIONS response status from 202 to 200 for CORS standard compliance, and implementing support for Access-Control-Expose-Headers, Vary: Origin header, and private network access.

Key changes:

  • Fixed typo and changed HashMap to ConcurrentHashMap for thread safety in CorsHandlerFactory
  • Updated OPTIONS preflight response status from SC_ACCEPTED (202) to SC_OK (200)
  • Added new CORS headers support including expose headers, vary header, and private network access

Reviewed Changes

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

Show a summary per file
File Description
src/test/java/org/codelibs/fess/filter/CorsFilterTest.java Updated test to expect SC_OK instead of SC_ACCEPTED for OPTIONS responses
src/test/java/org/codelibs/fess/cors/CorsHandlerFactoryTest.java Updated test to reference corrected field name 'handlerMap'
src/main/resources/fess_config.properties Added new configuration property for CORS expose headers
src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java Added API_CORS_EXPOSE_HEADERS configuration key, getter method, and default value
src/main/java/org/codelibs/fess/filter/CorsFilter.java Changed OPTIONS response status from SC_ACCEPTED to SC_OK
src/main/java/org/codelibs/fess/cors/DefaultCorsHandler.java Implemented expose headers, Vary header, and private network access support
src/main/java/org/codelibs/fess/cors/CorsHandlerFactory.java Fixed typo from 'handerMap' to 'handlerMap' and replaced HashMap with ConcurrentHashMap
src/main/java/org/codelibs/fess/cors/CorsHandler.java Added new header constant definitions for CORS functionality

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

httpResponse.addHeader(ACCESS_CONTROL_ALLOW_METHODS, fessConfig.getApiCorsAllowMethods());
httpResponse.addHeader(ACCESS_CONTROL_ALLOW_HEADERS, fessConfig.getApiCorsAllowHeaders());
httpResponse.addHeader(ACCESS_CONTROL_MAX_AGE, fessConfig.getApiCorsMaxAge());
httpResponse.addHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS, fessConfig.getApiCorsAllowCredentials());
Copy link

Copilot AI Nov 16, 2025

Choose a reason for hiding this comment

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

The Access-Control-Allow-Credentials header expects a boolean value ('true' or 'false'), but getApiCorsAllowCredentials() returns a String. This may work in practice, but the value should be validated or converted to ensure it's either 'true' or 'false' string literal for CORS compliance.

Suggested change
httpResponse.addHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS, fessConfig.getApiCorsAllowCredentials());
final String allowCredentials = fessConfig.getApiCorsAllowCredentials();
httpResponse.addHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS,
"true".equalsIgnoreCase(allowCredentials) ? "true" : "false");

Copilot uses AI. Check for mistakes.
*/
@Override
public void process(final String origin, final ServletRequest request, final ServletResponse response) {
final FessConfig fessConfig = ComponentUtil.getFessConfig();
Copy link

Copilot AI Nov 16, 2025

Choose a reason for hiding this comment

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

getFessConfig() is called on every CORS request. Consider caching the FessConfig instance at the handler level if this method involves non-trivial lookups, as CORS processing happens frequently.

Copilot uses AI. Check for mistakes.
Comment on lines +64 to +67
/**
* CORS header for specifying which headers can be exposed to the client.
*/
protected static final String ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers";
Copy link

Copilot AI Nov 16, 2025

Choose a reason for hiding this comment

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

Consider adding a response header constant for Access-Control-Allow-Private-Network to match the pattern of other CORS response headers, since line 88 in DefaultCorsHandler uses the string literal 'Access-Control-Allow-Private-Network'.

Copilot uses AI. Check for mistakes.
@marevol marevol force-pushed the claude/improve-cors-implementation-01N5CKEsJwHtHFepNrDuEZqi branch from d25939b to 76f7f24 Compare November 23, 2025 06:54
This commit improves the CORS (Cross-Origin Resource Sharing) implementation
in the org.codelibs.fess.cors package with the following enhancements:

1. Bug Fixes:
   - Fixed typo in CorsHandlerFactory: renamed 'handerMap' to 'handlerMap'
   - Changed OPTIONS preflight response from SC_ACCEPTED (202) to SC_OK (200)
     for better compliance with CORS standard

2. Thread Safety:
   - Replaced HashMap with ConcurrentHashMap in CorsHandlerFactory
   - Added thread-safety documentation

3. New Features:
   - Added Access-Control-Expose-Headers support to expose custom headers
   - Added Vary: Origin header for proper caching behavior
   - Added Access-Control-Allow-Private-Network support for private network
     access requests (Chrome feature)

4. Configuration:
   - Added new config property: api.cors.expose.headers
   - Added corresponding method in FessConfig interface
   - Updated default values and documentation

5. Code Quality:
   - Added inline comments for better code readability
   - Added new header constants in CorsHandler base class
   - Improved JavaDoc documentation

6. Tests:
   - Updated CorsHandlerFactoryTest to use correct field name
   - Updated CorsFilterTest to expect SC_OK instead of SC_ACCEPTED

These improvements enhance security, performance, and standards compliance
of the CORS implementation while maintaining backward compatibility.
This commit addresses code review feedback to improve the CORS implementation:

1. CORS Spec Compliance:
   - Fixed Access-Control-Allow-Credentials header handling
   - Now only sends "true" when explicitly configured (case-insensitive check)
   - Omits header entirely when not set to true (per CORS specification)

2. Performance Optimization:
   - Cached FessConfig instance in DefaultCorsHandler
   - Eliminates repeated ComponentUtil.getFessConfig() calls on every request
   - FessConfig is initialized once during @PostConstruct and reused

3. Null Safety:
   - Added null checks in CorsHandlerFactory.add() method
   - Added null checks in CorsHandlerFactory.get() method
   - Prevents NullPointerException when using ConcurrentHashMap
   - Fixes test failures: test_add_nullHandler, test_add_nullOrigin, test_get_nullOrigin
   - Null origin falls back to wildcard handler ("*")

These changes improve code quality, performance, and standards compliance
while maintaining backward compatibility.
This commit fixes test failures related to null key handling in CorsHandlerFactory:

1. Null Key Support:
   - Added AtomicReference<CorsHandler> field for null origin handler
   - ConcurrentHashMap does not support null keys, so null origins are stored separately
   - Maintains thread-safety while supporting null keys

2. Null Value Handling:
   - When null handler is added for an origin, remove that entry from the map
   - ConcurrentHashMap does not support null values

3. Test Compatibility:
   - Fixes test_add_nullOrigin: null origin with valid handler can be stored and retrieved
   - Fixes test_add_nullHandler: valid origin with null handler removes the entry
   - Fixes test_get_nullOrigin: null origin falls back to wildcard handler if no null origin handler exists

This implementation maintains the performance benefits of ConcurrentHashMap
while ensuring compatibility with existing test expectations.
This commit adds extensive test coverage for the CORS implementation to
validate all new features and improvements:

1. DefaultCorsHandlerTest (17 test cases):
   - Basic CORS headers validation
   - Access-Control-Allow-Credentials behavior:
     * Case-insensitive "true" detection
     * Header omission when not "true"
     * Null and empty value handling
   - Access-Control-Expose-Headers:
     * Conditional header addition
     * Empty and null value handling
   - Vary: Origin header validation
   - Private network access support:
     * Request header detection
     * Case-insensitive matching
     * Response header generation
   - Multiple origin format testing
   - Complete CORS response validation
   - FessConfig caching verification

2. CorsHandlerFactoryTest (7 additional test cases):
   - Thread-safety testing for ConcurrentHashMap
   - Null origin handler with AtomicReference thread-safety
   - Handler removal by setting null value
   - Null origin with wildcard fallback
   - Null origin precedence over wildcard
   - NullOriginHandler field initialization
   - Concurrent access patterns

3. Test Coverage Summary:
   - Total: 24+ new test cases
   - All new CORS features tested
   - Thread-safety validated
   - Edge cases covered (null, empty, case variations)
   - CORS specification compliance verified

These tests ensure the robustness and correctness of the CORS implementation
while providing regression protection for future changes.
This method returns a String and was required alongside the getPluginVersionFilterAsInteger method.
This method returns a String representing plugin repository URLs
and is required by the FessConfig interface.
Added 36 LDAP attribute getter methods to TestFessConfig class to satisfy
FessConfig interface requirements. All methods return null as test defaults.

Methods added:
- getLdapAttrSurname through getLdapAttrHomeDirectory
- Includes getLdapAttrGidNumber which was causing the compilation error

This ensures TestFessConfig implements all required abstract methods
from the FessConfig interface.
@marevol marevol force-pushed the claude/improve-cors-implementation-01N5CKEsJwHtHFepNrDuEZqi branch from 5b2eb57 to 15b1007 Compare November 23, 2025 11:40
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