Skip to content

Commit

Permalink
Issue #5171 Simplify GzipHandler user-agent handling
Browse files Browse the repository at this point in the history
+ Remove User-Agent handling from GzipHandler
+ Allow Vary header to be set
+ Create rewrite MsieRule to remove Accept-Encoding from IE<=6

Signed-off-by: Greg Wilkins <[email protected]>
  • Loading branch information
gregw committed Aug 24, 2020
1 parent d2e23a3 commit 8c6ee05
Show file tree
Hide file tree
Showing 14 changed files with 498 additions and 127 deletions.
32 changes: 32 additions & 0 deletions jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,38 @@ public Mutable clear()
return this;
}

/** Ensure that a multivalue CSV field contains the value
* @param header The header to check
* @param value The value that it must contain.
*/
public void ensure(HttpHeader header, String value)
{
computeField(header, (h,l) ->
{
if (l == null || l.isEmpty())
return new HttpField(h, value);

if (l.size() == 1)
{
HttpField f = l.get(0);
return f.contains(value) ? f : new HttpField(h, f.getValue() + ", " + value);
}
StringBuilder v = new StringBuilder();
boolean hasIt = false;
for (HttpField f : l)
{
if (v.length() > 0)
v.append(", ");
v.append(f.getValue());
if (f.contains(value))
hasIt = true;
}
if (!hasIt)
v.append(", ").append(value);
return new HttpField(h, v.toString());
});
}

@Override
public boolean equals(Object o)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -922,4 +922,25 @@ public void testComputeField()
fields.computeField("TEST", (n, f) -> null);
assertThat(fields.stream().map(HttpField::toString).collect(Collectors.toList()), contains("Before: value", "After: value"));
}
}

@Test
public void testEnsureValue()
{
HttpFields.Mutable fields = HttpFields.build();
assertThat(fields.size(), is(0));

fields.ensure(HttpHeader.ETAG, "one");
assertThat(fields.stream().map(HttpField::toString).collect(Collectors.toList()), contains("ETag: one"));

fields.ensure(HttpHeader.ETAG, "one");
assertThat(fields.stream().map(HttpField::toString).collect(Collectors.toList()), contains("ETag: one"));

fields.add(new HttpField(HttpHeader.ETAG, "two"));
fields.ensure(HttpHeader.ETAG, "one");
assertThat(fields.stream().map(HttpField::toString).collect(Collectors.toList()), contains("ETag: one, two"));

fields.add(new HttpField(HttpHeader.ETAG, "three"));
fields.ensure(HttpHeader.ETAG, "four");
assertThat(fields.stream().map(HttpField::toString).collect(Collectors.toList()), contains("ETag: one, two, three, four"));
}
}
13 changes: 13 additions & 0 deletions jetty-rewrite/src/main/config/modules/msie.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html

[description]
Enables the MSIE rewrite rule for MSIE 5 and 6 known bugs.

[depend]
rewrite

[files]
basehome:modules/rewrite/rewrite-msie.xml|etc/rewrite-msie.xml

[xml]
etc/rewrite-msie.xml
10 changes: 10 additions & 0 deletions jetty-rewrite/src/main/config/modules/rewrite/rewrite-msie.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RuleContainer">
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.MsieRule"/>
</Arg>
</Call>
</Configure>

16 changes: 8 additions & 8 deletions jetty-rewrite/src/main/config/modules/rewrite/rewrite-rules.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RuleContainer">

<!-- Add rule to protect against IE ssl bug
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.MsieSslRule"/>
</Arg>
</Call>
-->

<!-- protect favicon handling
<Call name="addRule">
<Arg>
Expand Down Expand Up @@ -102,5 +94,13 @@
</Call>
-->

<!-- Add rule to protect against IE ssl bug (see msie module and rewrite-msie.xml)
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.MsieRule"/>
</Arg>
</Call>
-->

</Configure>

Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.rewrite.handler;

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.ArrayTernaryTrie;
import org.eclipse.jetty.util.Trie;

/**
* Special handling for MSIE (Microsoft Internet Explorer).
* <ul>
* <li>Disable keep alive for SSL from IE5 or IE6 on Windows 2000</li>
* <li>Disable encodings for IE<=6</li>
* </ul>
*/
public class MsieRule extends MsieSslRule
{
private static final int IEv5 = '5';
private static final int IEv6 = '6';
private static Trie<Boolean> __IE6_BadOS = new ArrayTernaryTrie<>();
private static HttpField CONNECTION_CLOSE = new HttpField(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE);

{
__IE6_BadOS.put("NT 5.01", Boolean.TRUE);
__IE6_BadOS.put("NT 5.0", Boolean.TRUE);
__IE6_BadOS.put("NT 4.0", Boolean.TRUE);
__IE6_BadOS.put("98", Boolean.TRUE);
__IE6_BadOS.put("98; Win 9x 4.90", Boolean.TRUE);
__IE6_BadOS.put("95", Boolean.TRUE);
__IE6_BadOS.put("CE", Boolean.TRUE);
}

public MsieRule()
{
_handling = false;
_terminating = false;
}

@Override
public String matchAndApply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
{
Request baseRequest = Request.getBaseRequest(request);
if (baseRequest == null)
return null;
String userAgent = baseRequest.getHttpFields().get(HttpHeader.USER_AGENT);

int msie = userAgent.indexOf("MSIE");
if (msie >= 0)
{
int version = (userAgent.length() - msie > 5) ? userAgent.charAt(msie + 5) : IEv5;

if (version <= IEv6)
{
HttpFields.Mutable fields = HttpFields.build(baseRequest.getHttpFields());

// Don't gzip responses for IE<=6
fields.remove(HttpHeader.ACCEPT_ENCODING);

// IE<=6 can't do persistent SSL
if (request.isSecure())
{
boolean badOs = false;
if (version == IEv6)
{
int windows = userAgent.indexOf("Windows", msie + 5);
if (windows > 0)
{
int end = userAgent.indexOf(')', windows + 8);
badOs = (end < 0 || __IE6_BadOS.get(userAgent, windows + 8, end - windows - 8) != null);
}
}

if (version <= IEv5 || badOs)
{
fields.remove(HttpHeader.KEEP_ALIVE);
fields.ensure(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString());
response.setHeader(HttpHeader.CONNECTION.asString(), HttpHeaderValue.CLOSE.asString());
}
}
baseRequest.setHttpFields(fields);
return target;
}
}
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
/**
* MSIE (Microsoft Internet Explorer) SSL Rule.
* Disable keep alive for SSL from IE5 or IE6 on Windows 2000.
* @deprecated use MsieRule
*/
@Deprecated
public class MsieSslRule extends Rule
{
private static final int IEv5 = '5';
Expand Down
Loading

0 comments on commit 8c6ee05

Please sign in to comment.