-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Use lowercase for charsets #11741 #12347
Changes from 6 commits
8c33aa4
ccec3e4
1001c31
8c25183
3d7f5da
6c0b6f9
c87adb6
1172d59
7913cbb
c454e33
c429740
99fbfc3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -124,7 +124,7 @@ public HttpField getContentTypeField(Charset charset) | |
private final Charset _charset; | ||
private final String _charsetString; | ||
private final boolean _assumedCharset; | ||
private final HttpField _field; | ||
private final ContentTypeField _field; | ||
|
||
Type(String name) | ||
{ | ||
|
@@ -133,18 +133,18 @@ public HttpField getContentTypeField(Charset charset) | |
_charset = null; | ||
_charsetString = null; | ||
_assumedCharset = false; | ||
_field = new PreEncodedHttpField(HttpHeader.CONTENT_TYPE, _string); | ||
_field = new ContentTypeField(this); | ||
} | ||
|
||
Type(String name, Type base) | ||
{ | ||
_string = name; | ||
_base = base; | ||
_base = Objects.requireNonNull(base); | ||
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); | ||
_field = new ContentTypeField(this); | ||
} | ||
|
||
Type(String name, Charset cs) | ||
|
@@ -154,9 +154,12 @@ public HttpField getContentTypeField(Charset charset) | |
_charset = cs; | ||
_charsetString = _charset == null ? null : _charset.toString().toLowerCase(Locale.ENGLISH); | ||
_assumedCharset = true; | ||
_field = new PreEncodedHttpField(HttpHeader.CONTENT_TYPE, _string); | ||
_field = new ContentTypeField(this); | ||
} | ||
|
||
/** | ||
* @return The {@link Charset} for this type or {@code null} if it is not known | ||
*/ | ||
public Charset getCharset() | ||
{ | ||
return _charset; | ||
|
@@ -167,6 +170,11 @@ public String getCharsetString() | |
return _charsetString; | ||
} | ||
|
||
/** | ||
* Check if this type is equal to the type passed as a string | ||
* @param type The type to compare to | ||
* @return {@code true} if this is the same type | ||
*/ | ||
public boolean is(String type) | ||
{ | ||
return _string.equalsIgnoreCase(type); | ||
|
@@ -183,12 +191,15 @@ public String toString() | |
return _string; | ||
} | ||
|
||
/** | ||
* @return {@code true} If the {@link Charset} for this type is assumed rather than being explicitly declared. | ||
*/ | ||
public boolean isCharsetAssumed() | ||
{ | ||
return _assumedCharset; | ||
} | ||
|
||
public HttpField getContentTypeField() | ||
public ContentTypeField getContentTypeField() | ||
{ | ||
return _field; | ||
} | ||
|
@@ -200,6 +211,10 @@ public HttpField getContentTypeField(Charset charset) | |
return new HttpField(HttpHeader.CONTENT_TYPE, getContentTypeWithoutCharset(_string) + ";charset=" + charset.name()); | ||
} | ||
|
||
/** | ||
* Get the base type of this type, which is the type without a charset specified | ||
* @return The base type or this type if it is a base type | ||
*/ | ||
public Type getBaseType() | ||
{ | ||
return _base; | ||
|
@@ -227,23 +242,34 @@ public Type getBaseType() | |
}) | ||
.build(); | ||
|
||
/** | ||
* Get the base value, stripped of any parameters | ||
* @param value The value | ||
* @return A string with any semicolon separated parameters removed | ||
*/ | ||
public static String getBase(String value) | ||
{ | ||
int index = value.indexOf(';'); | ||
return index == -1 ? value : value.substring(0, index); | ||
} | ||
|
||
/** | ||
* Get the base type of this type, which is the type without a charset specified | ||
* @param contentType The mimetype as a string | ||
* @return The base type or this type if it is a base type | ||
*/ | ||
public static Type getBaseType(String contentType) | ||
{ | ||
if (StringUtil.isEmpty(contentType)) | ||
return null; | ||
Type type = CACHE.getBest(contentType); | ||
if (type == null) | ||
return null; | ||
if (type.asString().length() == contentType.length()) | ||
return type.getBaseType(); | ||
if (contentType.charAt(type.asString().length()) == ';') | ||
return type.getBaseType(); | ||
contentType = contentType.replace(" ", ""); | ||
if (type.asString().length() == contentType.length()) | ||
return type.getBaseType(); | ||
if (contentType.charAt(type.asString().length()) == ';') | ||
return type.getBaseType(); | ||
return null; | ||
{ | ||
type = CACHE.get(getBase(contentType)); | ||
if (type == null) | ||
return null; | ||
} | ||
return type.getBaseType(); | ||
} | ||
|
||
public static boolean isKnownLocale(Locale locale) | ||
|
@@ -326,6 +352,23 @@ public MimeTypes(MimeTypes defaults) | |
} | ||
} | ||
|
||
/** | ||
* Get the explicit, assumed, or inferred Charset for a HttpField containing a mime type value | ||
* @param field HttpField with a mime type value (e.g. Content-Type) | ||
* @return A {@link Charset} or null; | ||
* @throws IllegalCharsetNameException | ||
* If the given charset name is illegal | ||
* @throws UnsupportedCharsetException | ||
* If no support for the named charset is available | ||
* in this instance of the Java virtual machine | ||
*/ | ||
public Charset getCharset(HttpField field) throws IllegalCharsetNameException, UnsupportedCharsetException | ||
{ | ||
if (field instanceof ContentTypeField contentTypeField) | ||
return contentTypeField.getMimeType().getCharset(); | ||
return getCharset(field.getValue()); | ||
} | ||
|
||
/** | ||
* Get the explicit, assumed, or inferred Charset for a mime type | ||
* @param mimeType String form or a mimeType | ||
|
@@ -876,4 +919,25 @@ else if (' ' != b) | |
return value; | ||
return builder.toString(); | ||
} | ||
|
||
public static class ContentTypeField extends PreEncodedHttpField | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't this make more sense as a standalone class? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only other extension of So this is not unusual. It is a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I kind of agree that this would be better as standalone class, especially now that is the return value of a method: it's shorter to assign to a variable than There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As this is a rather special purpose class, I've just made is package protected and provided static methods to extract the info if needed. I could make it fully private if we want to give up on the optimized lookup of content-types with spaces in HttpParser |
||
{ | ||
private final Type _type; | ||
|
||
public ContentTypeField(MimeTypes.Type type) | ||
{ | ||
this(type, type.toString()); | ||
} | ||
|
||
public ContentTypeField(MimeTypes.Type type, String value) | ||
{ | ||
super(HttpHeader.CONTENT_TYPE, value); | ||
_type = type; | ||
} | ||
|
||
public Type getMimeType() | ||
{ | ||
return _type; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should not the method below
public HttpField getContentTypeField(Charset charset)
also have its return type changed?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really, because there are two aspect of
ContentTypeField
: it has agetMimeType
method and it is aPreEncodedHttpField
. For an arbitrary contentType returned from this method, it is not guaranteed that it will have a known mimeType and it is not known if it is worthwhile going to the effort of pre-encoding.That is why I think this class belongs as a subtype of this class, as it is pretty special purpose for long held constants for known types.