483039 - HTTP2 Upgrade case sensitivity on Connection header

This commit is contained in:
Greg Wilkins 2015-11-26 07:06:38 +11:00
parent d2e4eff686
commit a2c057892e
4 changed files with 27 additions and 10 deletions

View File

@ -21,6 +21,8 @@ package org.eclipse.jetty.http;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Objects; import java.util.Objects;
import org.eclipse.jetty.util.StringUtil;
/** A HTTP Field /** A HTTP Field
*/ */
public class HttpField public class HttpField
@ -191,7 +193,7 @@ public class HttpField
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Look for a value in a possible multi valued field /** Look for a value in a possible multi valued field
* @param search Values to search for * @param search Values to search for (case insensitive)
* @return True iff the value is contained in the field value entirely or * @return True iff the value is contained in the field value entirely or
* as an element of a quoted comma separated list. List element parameters (eg qualities) are ignored, * as an element of a quoted comma separated list. List element parameters (eg qualities) are ignored,
* except if they are q=0, in which case the item itself is ignored. * except if they are q=0, in which case the item itself is ignored.
@ -205,6 +207,8 @@ public class HttpField
if (_value==null) if (_value==null)
return false; return false;
search = StringUtil.asciiToLowerCase(search);
int state=0; int state=0;
int match=0; int match=0;
int param=0; int param=0;
@ -236,7 +240,7 @@ public class HttpField
break; break;
default: // character default: // character
match = c==search.charAt(0)?1:-1; match = Character.toLowerCase(c)==search.charAt(0)?1:-1;
state=1; state=1;
break; break;
} }
@ -261,7 +265,7 @@ public class HttpField
if (match>0) if (match>0)
{ {
if (match<search.length()) if (match<search.length())
match=c==search.charAt(match)?(match+1):-1; match=Character.toLowerCase(c)==search.charAt(match)?(match+1):-1;
else if (c!=' ' && c!= '\t') else if (c!=' ' && c!= '\t')
match=-1; match=-1;
} }
@ -285,7 +289,7 @@ public class HttpField
if (match>=0) if (match>=0)
{ {
if (match<search.length()) if (match<search.length())
match=c==search.charAt(match)?(match+1):-1; match=Character.toLowerCase(c)==search.charAt(match)?(match+1):-1;
else else
match=-1; match=-1;
} }
@ -296,7 +300,7 @@ public class HttpField
if (match>=0) if (match>=0)
{ {
if (match<search.length()) if (match<search.length())
match=c==search.charAt(match)?(match+1):-1; match=Character.toLowerCase(c)==search.charAt(match)?(match+1):-1;
else else
match=-1; match=-1;
} }
@ -346,7 +350,7 @@ public class HttpField
if (param>=0) if (param>=0)
{ {
if (param<__zeroquality.length()) if (param<__zeroquality.length())
param=c==__zeroquality.charAt(param)?(param+1):-1; param=Character.toLowerCase(c)==__zeroquality.charAt(param)?(param+1):-1;
else if (c!='0'&&c!='.') else if (c!='0'&&c!='.')
param=-1; param=-1;
} }

View File

@ -35,10 +35,13 @@ public class HttpFieldTest
@Test @Test
public void testContainsSimple() throws Exception public void testContainsSimple() throws Exception
{ {
HttpField field = new HttpField("name","somevalue"); HttpField field = new HttpField("name","SomeValue");
assertTrue(field.contains("somevalue")); assertTrue(field.contains("somevalue"));
assertTrue(field.contains("sOmEvAlUe"));
assertTrue(field.contains("SomeValue"));
assertFalse(field.contains("other")); assertFalse(field.contains("other"));
assertFalse(field.contains("some")); assertFalse(field.contains("some"));
assertFalse(field.contains("Some"));
assertFalse(field.contains("value")); assertFalse(field.contains("value"));
assertFalse(field.contains("v")); assertFalse(field.contains("v"));
assertFalse(field.contains("")); assertFalse(field.contains(""));
@ -66,10 +69,16 @@ public class HttpFieldTest
@Test @Test
public void testContainsList() throws Exception public void testContainsList() throws Exception
{ {
HttpField field = new HttpField("name",",aaa,bbb,ccc, ddd , e e, \"\\\"f,f\\\"\", "); HttpField field = new HttpField("name",",aaa,Bbb,CCC, ddd , e e, \"\\\"f,f\\\"\", ");
assertTrue(field.contains("aaa")); assertTrue(field.contains("aaa"));
assertTrue(field.contains("bbb")); assertTrue(field.contains("bbb"));
assertTrue(field.contains("ccc")); assertTrue(field.contains("ccc"));
assertTrue(field.contains("Aaa"));
assertTrue(field.contains("Bbb"));
assertTrue(field.contains("Ccc"));
assertTrue(field.contains("AAA"));
assertTrue(field.contains("BBB"));
assertTrue(field.contains("CCC"));
assertTrue(field.contains("ddd")); assertTrue(field.contains("ddd"));
assertTrue(field.contains("e e")); assertTrue(field.contains("e e"));
assertTrue(field.contains("\"f,f\"")); assertTrue(field.contains("\"f,f\""));
@ -126,6 +135,10 @@ public class HttpFieldTest
assertTrue(field.contains("yes")); assertTrue(field.contains("yes"));
assertFalse(field.contains("no")); assertFalse(field.contains("no"));
field = new HttpField("name","no;q=0.0000,Yes;Q=0.0001,no; Q = 0.00000");
assertTrue(field.contains("yes"));
assertFalse(field.contains("no"));
} }
@Test @Test

View File

@ -115,7 +115,7 @@ public class HTTP2CServerTest extends AbstractServerTest
output.write(("" + output.write(("" +
"GET /one HTTP/1.1\r\n" + "GET /one HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Connection: Upgrade, HTTP2-Settings\r\n" + "Connection: something, else, upgrade, HTTP2-Settings\r\n" +
"Upgrade: h2c\r\n" + "Upgrade: h2c\r\n" +
"HTTP2-Settings: \r\n" + "HTTP2-Settings: \r\n" +
"\r\n").getBytes(StandardCharsets.ISO_8859_1)); "\r\n").getBytes(StandardCharsets.ISO_8859_1));

View File

@ -370,7 +370,7 @@ class HttpChannelOverHttp extends HttpChannel implements HttpParser.RequestHandl
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("upgrade {} {}",this,_upgrade); LOG.debug("upgrade {} {}",this,_upgrade);
if (_upgrade!=PREAMBLE_UPGRADE_H2C && (_connection==null || !_connection.getValue().contains("Upgrade"))) if (_upgrade!=PREAMBLE_UPGRADE_H2C && (_connection==null || !_connection.contains("upgrade")))
throw new BadMessageException(HttpStatus.BAD_REQUEST_400); throw new BadMessageException(HttpStatus.BAD_REQUEST_400);
// Find the upgrade factory // Find the upgrade factory