Re: (tomcat) branch main updated: Fix matching of the pattern documented in the javadoc

Konstantin Kolinko <[email protected]> Fri, 31 Jul 2026 15:48:43 +0300
Newsgroups gmane.comp.jakarta.tomcat.devel
Message-ID <CABzHfV=tNariBby=UiSa=wYCiy4MCzDiAb4bCKG5TBOpvq1nzA@mail.gmail.com>
=D0=BF=D1=82, 31 =D0=B8=D1=8E=D0=BB. 2026=E2=80=AF=D0=B3. =D0=B2 12:36, <re=
[email protected]>:
>
> This is an automated email from the ASF dual-hosted git repository.
>
> rmaucher pushed a commit to branch main
> in repository https://gitbox.apache.org/repos/asf/tomcat.git
>
>
> The following commit(s) were added to refs/heads/main by this push:
>      new 1f29baf341 Fix matching of the pattern documented in the javadoc
> 1f29baf341 is described below
>
> commit 1f29baf341220048c66e30aedf43c5b7d0266060
> Author: remm <[email protected]>
> AuthorDate: Fri Jul 31 11:35:54 2026 +0200
>
>     Fix matching of the pattern documented in the javadoc

1. The online documentation was correct (before your change), saying "match=
ing",
and it was not updated by this commit.

https://tomcat.apache.org/tomcat-11.0-doc/config/http.html
see "noCompressionUserAgents"

2. The code using "matches()" is there at least from the first
revision of CompressionConfig.java (year 2017)
when it was moved there out of org/apache/coyote/http11/Http11Processor.jav=
a


I know that HTTPD uses find rather than matching the whole string, but
our code is 9+ old,
so I think that it would be better to just align the documentation
with the behaviour.

https://httpd.apache.org/docs/current/mod/mod_setenvif.html
see BrowserMatch, BrowserMatchNoCase

Best regards,
Konstantin Kolinko

>     Also add a test case for the noCompressionUserAgents feature, coautho=
red
>     with OpenCode.
> ---
>  java/org/apache/coyote/CompressionConfig.java      |  2 +-
>  .../coyote/TestCompressionConfigUserAgents.java    | 67 ++++++++++++++++=
++++++
>  webapps/docs/changelog.xml                         |  6 ++
>  3 files changed, 74 insertions(+), 1 deletion(-)
>
> diff --git a/java/org/apache/coyote/CompressionConfig.java b/java/org/apa=
che/coyote/CompressionConfig.java
> index 7c5efcfec9..b07b8c10b5 100644
> --- a/java/org/apache/coyote/CompressionConfig.java
> +++ b/java/org/apache/coyote/CompressionConfig.java
> @@ -375,7 +375,7 @@ public class CompressionConfig {
>                  MessageBytes userAgentValueMB =3D request.getMimeHeaders=
().getValue("user-agent");
>                  if (userAgentValueMB !=3D null) {
>                      String userAgentValue =3D userAgentValueMB.toString(=
);
> -                    if (noCompressionUserAgents.matcher(userAgentValue).=
matches()) {
> +                    if (noCompressionUserAgents.matcher(userAgentValue).=
find()) {
>                          return false;
>                      }
>                  }
> diff --git a/test/org/apache/coyote/TestCompressionConfigUserAgents.java =
b/test/org/apache/coyote/TestCompressionConfigUserAgents.java
> new file mode 100644
> index 0000000000..43f988533f
> --- /dev/null
> +++ b/test/org/apache/coyote/TestCompressionConfigUserAgents.java
> @@ -0,0 +1,67 @@
> +/*
> + *  Licensed to the Apache Software Foundation (ASF) under one or more
> + *  contributor license agreements.  See the NOTICE file distributed wit=
h
> + *  this work for additional information regarding copyright ownership.
> + *  The ASF licenses this file to You under the Apache License, Version =
2.0
> + *  (the "License"); you may not use this file except in compliance with
> + *  the License.  You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + *  Unless required by applicable law or agreed to in writing, software
> + *  distributed under the License is distributed on an "AS IS" BASIS,
> + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impl=
ied.
> + *  See the License for the specific language governing permissions and
> + *  limitations under the License.
> + */
> +package org.apache.coyote;
> +
> +import org.junit.Assert;
> +import org.junit.Test;
> +
> +public class TestCompressionConfigUserAgents {
> +
> +    @Test
> +    public void testNoCompressionUserAgents() {
> +        CompressionConfig config =3D new CompressionConfig();
> +        config.setNoCompressionUserAgents("gorilla|MSIE|tigrus");
> +
> +        Request request =3D new Request();
> +        request.getMimeHeaders().addValue("accept-encoding").setString("=
gzip");
> +        Response response;
> +
> +        // Force mode (compressionLevel =3D=3D 2) skips the user-agent c=
heck,
> +        // so use "on" mode where the check applies
> +        config.setCompression("on");
> +
> +        // User-agent matching the pattern should not be compressed
> +        response =3D createResponse();
> +        request.getMimeHeaders().addValue("user-agent").setString("Mozil=
la/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
> +        Assert.assertFalse(config.useCompression(request, response));
> +
> +        // No user-agent header should be compressed
> +        response =3D createResponse();
> +        request.getMimeHeaders().removeHeader("user-agent");
> +        Assert.assertTrue(config.useCompression(request, response));
> +
> +        // User-agent not matching the pattern should be compressed
> +        response =3D createResponse();
> +        request.getMimeHeaders().removeHeader("user-agent");
> +        request.getMimeHeaders().addValue("user-agent").setString("Mozil=
la/5.0 (X11; Linux x86_64)");
> +        Assert.assertTrue(config.useCompression(request, response));
> +
> +        // Force mode skips the user-agent check
> +        response =3D createResponse();
> +        config.setCompression("force");
> +        request.getMimeHeaders().removeHeader("user-agent");
> +        request.getMimeHeaders().addValue("user-agent").setString("Mozil=
la/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
> +        Assert.assertTrue(config.useCompression(request, response));
> +    }
> +
> +    private Response createResponse() {
> +        Response response =3D new Response();
> +        response.setContentLength(4096);
> +        response.setContentType("text/html");
> +        return response;
> +    }
> +}
> diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
> index 173f38f99e..f550280459 100644
> --- a/webapps/docs/changelog.xml
> +++ b/webapps/docs/changelog.xml
> @@ -339,6 +339,12 @@
>          of how early in the HEADERS frame processing an error is detecte=
d.
>          (markt)
>        </fix>
> +      <fix>
> +        Fix matching the compression config
> +        <code>noCompressionUserAgents</code> with patterns of the style
> +        of the example <code>gorilla|desesplorer|tigrus</code> pattern
> +        documented in the javadoc. (remm)
> +      </fix>
>      </changelog>
>    </subsection>
>    <subsection name=3D"Jasper">
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>