Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various cleanups of StringUtil and TypeUtil #10082

Merged
merged 2 commits into from
Jul 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.util.Attributes;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;

/**
* Implementation of the HTTP "Digest" authentication defined in RFC 2617.
Expand Down Expand Up @@ -231,7 +230,7 @@ private String newClientNonce()

private String toHexString(byte[] bytes)
{
return TypeUtil.toHexString(bytes).toLowerCase(Locale.ENGLISH);
return StringUtil.toHexString(bytes).toLowerCase(Locale.ENGLISH);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.charset.UnsupportedCharsetException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
Expand All @@ -40,11 +42,18 @@ public class MimeTypes
{
static final Logger LOG = LoggerFactory.getLogger(MimeTypes.class);
private static final Set<Locale> KNOWN_LOCALES = Set.copyOf(Arrays.asList(Locale.getAvailableLocales()));

public static boolean isKnownLocale(Locale locale)
{
return KNOWN_LOCALES.contains(locale);
}
public static final String ISO_8859_1 = StandardCharsets.ISO_8859_1.name().toLowerCase();
public static final String UTF8 = StandardCharsets.UTF_8.name().toLowerCase();
public static final String UTF16 = StandardCharsets.UTF_16.name().toLowerCase();
private static final Index<String> CHARSETS = new Index.Builder<String>()
.caseSensitive(false)
.with("utf-8", UTF8)
.with("utf8", UTF8)
.with("utf-16", UTF16)
.with("utf16", UTF16)
.with("iso-8859-1", ISO_8859_1)
.with("iso_8859_1", ISO_8859_1)
.build();

/** Enumeration of predefined MimeTypes. This is not exhaustive */
public enum Type
Expand Down Expand Up @@ -115,30 +124,30 @@ public HttpField getContentTypeField(Charset charset)
private final boolean _assumedCharset;
private final HttpField _field;

Type(String s)
Type(String name)
{
_string = s;
_string = name;
_base = this;
_charset = null;
_charsetString = null;
_assumedCharset = false;
_field = new PreEncodedHttpField(HttpHeader.CONTENT_TYPE, _string);
}

Type(String s, Type base)
Type(String name, Type base)
{
_string = s;
_string = name;
_base = base;
int i = s.indexOf(";charset=");
_charset = Charset.forName(s.substring(i + 9));
int i = name.indexOf(";charset=");
_charset = Charset.forName(name.substring(i + 9));
_charsetString = _charset.toString().toLowerCase(Locale.ENGLISH);
_assumedCharset = false;
_field = new PreEncodedHttpField(HttpHeader.CONTENT_TYPE, _string);
}

Type(String s, Charset cs)
Type(String name, Charset cs)
{
_string = s;
_string = name;
_base = this;
_charset = cs;
_charsetString = _charset == null ? null : _charset.toString().toLowerCase(Locale.ENGLISH);
Expand All @@ -156,9 +165,9 @@ public String getCharsetString()
return _charsetString;
}

public boolean is(String s)
public boolean is(String type)
{
return _string.equalsIgnoreCase(s);
return _string.equalsIgnoreCase(type);
}

public String asString()
Expand Down Expand Up @@ -235,6 +244,62 @@ public static Type getBaseType(String contentType)
return null;
}

public static boolean isKnownLocale(Locale locale)
{
return KNOWN_LOCALES.contains(locale);
}

/**
* Convert alternate charset names (eg utf8) to normalized
* name (eg UTF-8).
*
* @param charsetName the charset to normalize
* @return the normalized charset (or null if normalized version not found)
*/
public static String normalizeCharset(String charsetName)
{
String n = CHARSETS.get(charsetName);
return (n == null) ? charsetName : n;
}

/**
* Convert alternate charset names (eg utf8) to normalized
* name (eg UTF-8).
*
* @param charsetName the charset to normalize
* @param offset the offset in the charset
* @param length the length of the charset in the input param
* @return the normalized charset (or null if not found)
*/
public static String normalizeCharset(String charsetName, int offset, int length)
{
String n = CHARSETS.get(charsetName, offset, length);
return (n == null) ? charsetName.substring(offset, offset + length) : n;
}

/**
* @param charsetName The name of the charset
* @return The {@link Charset} for the normalized name
* @throws UnsupportedEncodingException Thrown if the charset is not known to the JVM.
*/
public static Charset getKnownCharset(String charsetName) throws UnsupportedEncodingException
{
// check encoding is supported
if (StandardCharsets.UTF_8.name().equalsIgnoreCase(charsetName))
return StandardCharsets.UTF_8;
charsetName = normalizeCharset(charsetName);
if (StandardCharsets.UTF_8.name().equalsIgnoreCase(charsetName))
return StandardCharsets.UTF_8;
try
{
return Charset.forName(charsetName);
}
catch (UnsupportedCharsetException e)
{
throw new UnsupportedEncodingException(e.getMessage());
}
}

protected final Map<String, String> _mimeMap = new HashMap<>();
protected final Map<String, String> _inferredEncodings = new HashMap<>();
protected final Map<String, String> _assumedEncodings = new HashMap<>();
Expand Down Expand Up @@ -625,15 +690,15 @@ else if (' ' != b)
case 10:
if (!quote && (';' == b || ' ' == b) ||
(quote && '"' == b))
return StringUtil.normalizeCharset(value, start, i - start);
return normalizeCharset(value, start, i - start);
break;
default:
throw new IllegalStateException();
}
}

if (state == 10)
return StringUtil.normalizeCharset(value, start, i - start);
return normalizeCharset(value, start, i - start);

return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.eclipse.jetty.http.compression.HuffmanEncoder;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
Expand Down Expand Up @@ -65,7 +64,7 @@ public static Stream<Arguments> data()
@MethodSource("data")
public void testDecode(String specSection, String hex, String expected) throws Exception
{
byte[] encoded = TypeUtil.fromHexString(hex);
byte[] encoded = StringUtil.fromHexString(hex);
HuffmanDecoder huffmanDecoder = new HuffmanDecoder();
huffmanDecoder.setLength(encoded.length);
String decoded = huffmanDecoder.decode(ByteBuffer.wrap(encoded));
Expand All @@ -80,7 +79,8 @@ public void testEncode(String specSection, String hex, String expected)
int pos = BufferUtil.flipToFill(buf);
HuffmanEncoder.encode(buf, expected);
BufferUtil.flipToFlush(buf, pos);
String encoded = TypeUtil.toHexString(BufferUtil.toArray(buf)).toLowerCase(Locale.ENGLISH);
byte[] b = BufferUtil.toArray(buf);
String encoded = StringUtil.toHexString(b).toLowerCase(Locale.ENGLISH);
assertEquals(hex, encoded, specSection);
assertEquals(hex.length() / 2, HuffmanEncoder.octetsNeeded(expected));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import org.eclipse.jetty.http.compression.NBitIntegerDecoder;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.StringUtil;
import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
Expand All @@ -32,7 +32,7 @@ public void testParsingOverByteBoundary()
NBitIntegerDecoder decoder = new NBitIntegerDecoder();

String encoded = "FFBA09";
byte[] bytes = TypeUtil.fromHexString(encoded);
byte[] bytes = StringUtil.fromHexString(encoded);
bytes[0] = (byte)(bytes[0] | 0x80); // set the first bit so it is a section acknowledgement.
ByteBuffer buffer1 = BufferUtil.toBuffer(bytes, 0, 2);
ByteBuffer buffer2 = BufferUtil.toBuffer(bytes, 2, 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import org.eclipse.jetty.http.compression.NBitIntegerEncoder;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
Expand Down Expand Up @@ -85,7 +84,8 @@ public void testEncode(int n, int i, String expected)
buf.put((byte)0x00);
NBitIntegerEncoder.encode(buf, n, i);
BufferUtil.flipToFlush(buf, p);
String r = TypeUtil.toHexString(BufferUtil.toArray(buf));
byte[] b = BufferUtil.toArray(buf);
String r = StringUtil.toHexString(b);
assertEquals(expected, r);

assertEquals(expected.length() / 2, NBitIntegerEncoder.octetsNeeded(n, i));
Expand Down Expand Up @@ -125,7 +125,7 @@ public void testDecode()

public void testDecode(int n, int expected, String encoded)
{
ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString(encoded));
ByteBuffer buf = ByteBuffer.wrap(StringUtil.fromHexString(encoded));
_decoder.setPrefix(n);
assertEquals(expected, _decoder.decodeInt(buf));
}
Expand All @@ -140,15 +140,16 @@ public void testEncodeExampleD11()
NBitIntegerEncoder.encode(buf, 5, 10);
BufferUtil.flipToFlush(buf, p);

String r = TypeUtil.toHexString(BufferUtil.toArray(buf));
byte[] b = BufferUtil.toArray(buf);
String r = StringUtil.toHexString(b);

assertEquals("77Ea", r);
}

@Test
public void testDecodeExampleD11()
{
ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("77EaFF"));
ByteBuffer buf = ByteBuffer.wrap(StringUtil.fromHexString("77EaFF"));
buf.position(1);
_decoder.setPrefix(5);
assertEquals(10, _decoder.decodeInt(buf));
Expand All @@ -171,7 +172,7 @@ public void testEncodeExampleD12()
@Test
public void testDecodeExampleD12()
{
ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("881f9a0aff"));
ByteBuffer buf = ByteBuffer.wrap(StringUtil.fromHexString("881f9a0aff"));
buf.position(1);
_decoder.setPrefix(5);
assertEquals(1337, _decoder.decodeInt(buf));
Expand All @@ -187,15 +188,16 @@ public void testEncodeExampleD13()
NBitIntegerEncoder.encode(buf, 8, 42);
BufferUtil.flipToFlush(buf, p);

String r = TypeUtil.toHexString(BufferUtil.toArray(buf));
byte[] b = BufferUtil.toArray(buf);
String r = StringUtil.toHexString(b);

assertEquals("88Ff2a", r);
}

@Test
public void testDecodeExampleD13()
{
ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("882aFf"));
ByteBuffer buf = ByteBuffer.wrap(StringUtil.fromHexString("882aFf"));
buf.position(1);
_decoder.setPrefix(8);
assertEquals(42, _decoder.decodeInt(buf));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import org.eclipse.jetty.http3.qpack.internal.parser.EncoderInstructionParser;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.StringUtil;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

Expand All @@ -42,42 +42,42 @@ public void testSectionAcknowledgement() throws Exception
{
// Example from the spec, section acknowledgement instruction with stream id 4.
String encoded = "84";
ByteBuffer buffer = BufferUtil.toBuffer(TypeUtil.fromHexString(encoded));
ByteBuffer buffer = BufferUtil.toBuffer(StringUtil.fromHexString(encoded));
_instructionParser.parse(buffer);
assertThat(_handler.sectionAcknowledgements.poll(), is(4L));
assertTrue(_handler.isEmpty());

// 1111 1110 == FE is largest value we can do without continuation should be stream ID 126.
encoded = "FE";
buffer = BufferUtil.toBuffer(TypeUtil.fromHexString(encoded));
buffer = BufferUtil.toBuffer(StringUtil.fromHexString(encoded));
_instructionParser.parse(buffer);
assertThat(_handler.sectionAcknowledgements.poll(), is(126L));
assertTrue(_handler.isEmpty());

// 1111 1111 0000 0000 == FF00 is next value, stream id 127.
encoded = "FF00";
buffer = BufferUtil.toBuffer(TypeUtil.fromHexString(encoded));
buffer = BufferUtil.toBuffer(StringUtil.fromHexString(encoded));
_instructionParser.parse(buffer);
assertThat(_handler.sectionAcknowledgements.poll(), is(127L));
assertTrue(_handler.isEmpty());

// 1111 1111 0000 0001 == FF01 is next value, stream id 128.
encoded = "FF01";
buffer = BufferUtil.toBuffer(TypeUtil.fromHexString(encoded));
buffer = BufferUtil.toBuffer(StringUtil.fromHexString(encoded));
_instructionParser.parse(buffer);
assertThat(_handler.sectionAcknowledgements.poll(), is(128L));
assertTrue(_handler.isEmpty());

// FFBA09 contains section ack with stream ID of 1337, this contains an octet with continuation bit.
encoded = "FFBA09";
buffer = BufferUtil.toBuffer(TypeUtil.fromHexString(encoded));
buffer = BufferUtil.toBuffer(StringUtil.fromHexString(encoded));
_instructionParser.parse(buffer);
assertThat(_handler.sectionAcknowledgements.poll(), is(1337L));
assertTrue(_handler.isEmpty());

// Test with continuation.
encoded = "FFBA09";
byte[] bytes = TypeUtil.fromHexString(encoded);
byte[] bytes = StringUtil.fromHexString(encoded);
for (int i = 0; i < 10; i++)
{
ByteBuffer buffer1 = BufferUtil.toBuffer(bytes, 0, 2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.StringUtil;
import org.hamcrest.Matcher;

import static org.hamcrest.MatcherAssert.assertThat;
Expand Down Expand Up @@ -71,7 +71,7 @@ public static ByteBuffer toBuffer(List<Instruction> instructions)
public static ByteBuffer hexToBuffer(String hexString)
{
hexString = hexString.replaceAll("\\s+", "");
return ByteBuffer.wrap(TypeUtil.fromHexString(hexString));
return ByteBuffer.wrap(StringUtil.fromHexString(hexString));
}

public static String toHexString(Instruction instruction)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

import org.eclipse.jetty.security.UserPrincipal;
import org.eclipse.jetty.security.jaas.callback.ObjectCallback;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.security.Credential;
import org.slf4j.Logger;
Expand Down Expand Up @@ -750,7 +751,7 @@ private static String base64ToHex(String src)

private static String hexToBase64(String src)
{
byte[] bytes = TypeUtil.fromHexString(src);
byte[] bytes = StringUtil.fromHexString(src);
return Base64.getEncoder().encodeToString(bytes);
}
}
Loading