Croway commented on PR #26334:
URL: https://github.com/apache/camel/pull/26334#issuecomment-5635485555

   Thanks for digging into this! I ran a reproducer against the PR and found a 
regression on the default path.
   
   **Problem:** `!BROTLI4J_AVAILABLE` is also true when brotli4j is not on the 
classpath at all (plain Camel / Spring Boot), so the custom decoder map is 
always installed. `buildDecodersWithoutBrotli()` drops the `x-gzip` alias that 
HttpClient's default `ContentCompressionExec` registers: `Accept-Encoding` 
becomes `gzip, deflate` and a `Content-Encoding: x-gzip` response fails with 
`ClientProtocolException: Unsupported Content-Encoding: x-gzip`.
   
   camel-http test with gzip / x-gzip / br / negotiated responses, across 
classpaths:
   
   | | brotli4j absent | brotli4j without native | brotli4j + native |
   |---|---|---|---|
   | main | ✅ | ❌ `UnsatisfiedLinkError` | ✅ |
   | this PR | ❌ x-gzip | ❌ x-gzip | ✅ |
   | suggested approach below | ✅ | ✅ | ✅ |
   
   The new tests don't catch it: the test-scoped `brotli4j` pulls the native 
jar on CI (Maven activates its OS profiles, also for transitive dependencies), 
so the "unavailable" branch never runs.
   
   For reference, HttpClient fixed this itself in 
apache/httpcomponents-client@be07c77297576b08bc01bb93789eca6f5f9bf850 (not 
released yet): `Brotli4jRuntime.available()` now loads `Brotli4jLoader` and 
returns `isAvailable()` instead of only checking the class is present. The 
Camel check can mirror that, and becomes redundant once we upgrade.
   
   **Suggested approach: a narrow, self-disabling workaround in camel-http.** 
Only replace the decoders when HttpClient registered brotli4j but its native 
library can't load, keep `x-gzip`, and evaluate lazily (not in 
`HttpComponent`'s static init). Once HttpClient ships the fix, 
`Brotli4jRuntime.available()` returns false and this becomes a no-op.
   
   ```java
   // HttpComponent#createHttpClientBuilder
   } else if (BrotliContentDecoders.isBrotliDecoderUnusable()) { // lazy holder:
       // Brotli4jRuntime.available() && !Brotli4jLoader.isAvailable() 
(reflective)
       
clientBuilder.setContentDecoderRegistry(BrotliContentDecoders.decodersWithoutBrotli());
   }
   
   static LinkedHashMap<String, InputStreamFactory> decodersWithoutBrotli() {
       LinkedHashMap<String, InputStreamFactory> decoders = new 
LinkedHashMap<>();
       for (ContentCoding coding : ContentCoding.values()) {
           if (coding != ContentCoding.BROTLI && 
ContentCodecRegistry.decoder(coding) != null) {
               decoders.put(coding.token(), decoder(coding));
           }
       }
       // HttpClient's default content compression also accepts x-gzip as an 
alias of gzip
       if (decoders.containsKey(ContentCoding.GZIP.token())) {
           decoders.put(ContentCoding.X_GZIP.token(), 
decoder(ContentCoding.GZIP));
       }
       return decoders;
   }
   ```
   
   quarkusio/quarkus#56547 is still worth pursuing for the dev-mode case.
   
   **Tests**, independent of the build machine:
   - test-scoped `brotli4j` with a `*` exclusion plus an explicit `service` 
dependency, so every CI platform runs with "classes but no native library" and 
exercises the workaround;
   - an HTTP test asserting `gzip`, `x-gzip` and a server-negotiated `br` 
response all decode, and that `Accept-Encoding` equals HttpClient's default 
minus `br`;
   - the reflective availability check against an isolated `URLClassLoader` 
holding only the brotli4j and service jars.
   
   Minor: the JIRA says Maven doesn't activate brotli4j's profiles for 
transitive dependencies, but `mvn dependency:tree` on `quarkus-vertx-http` does 
pull `native-<os>`, and packaged Quarkus apps ship it. The missing native 
library is specific to dev mode / `camel run --runtime=quarkus` (and to images 
built on a different OS/arch), so it may be worth correcting the description.
   
   _Claude Code on behalf of Croway_
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to