init
This commit is contained in:
74
java/org/apache/tomcat/util/http/parser/AcceptEncoding.java
Normal file
74
java/org/apache/tomcat/util/http/parser/AcceptEncoding.java
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* 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 implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.tomcat.util.http.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AcceptEncoding {
|
||||
|
||||
private final String encoding;
|
||||
private final double quality;
|
||||
|
||||
protected AcceptEncoding(String encoding, double quality) {
|
||||
this.encoding = encoding;
|
||||
this.quality = quality;
|
||||
}
|
||||
|
||||
public String getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
public double getQuality() {
|
||||
return quality;
|
||||
}
|
||||
|
||||
|
||||
public static List<AcceptEncoding> parse(StringReader input) throws IOException {
|
||||
|
||||
List<AcceptEncoding> result = new ArrayList<>();
|
||||
|
||||
do {
|
||||
String encoding = HttpParser.readToken(input);
|
||||
if (encoding == null) {
|
||||
// Invalid encoding, skip to the next one
|
||||
HttpParser.skipUntil(input, 0, ',');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (encoding.length() == 0) {
|
||||
// No more data to read
|
||||
break;
|
||||
}
|
||||
|
||||
// See if a quality has been provided
|
||||
double quality = 1;
|
||||
SkipResult lookForSemiColon = HttpParser.skipConstant(input, ";");
|
||||
if (lookForSemiColon == SkipResult.FOUND) {
|
||||
quality = HttpParser.readWeight(input, ',');
|
||||
}
|
||||
|
||||
if (quality > 0) {
|
||||
result.add(new AcceptEncoding(encoding, quality));
|
||||
}
|
||||
} while (true);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
78
java/org/apache/tomcat/util/http/parser/AcceptLanguage.java
Normal file
78
java/org/apache/tomcat/util/http/parser/AcceptLanguage.java
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* 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 implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.tomcat.util.http.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class AcceptLanguage {
|
||||
|
||||
private final Locale locale;
|
||||
private final double quality;
|
||||
|
||||
protected AcceptLanguage(Locale locale, double quality) {
|
||||
this.locale = locale;
|
||||
this.quality = quality;
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
public double getQuality() {
|
||||
return quality;
|
||||
}
|
||||
|
||||
|
||||
public static List<AcceptLanguage> parse(StringReader input) throws IOException {
|
||||
|
||||
List<AcceptLanguage> result = new ArrayList<>();
|
||||
|
||||
do {
|
||||
// Token is broader than what is permitted in a language tag
|
||||
// (alphanumeric + '-') but any invalid values that slip through
|
||||
// will be caught later
|
||||
String languageTag = HttpParser.readToken(input);
|
||||
if (languageTag == null) {
|
||||
// Invalid tag, skip to the next one
|
||||
HttpParser.skipUntil(input, 0, ',');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (languageTag.length() == 0) {
|
||||
// No more data to read
|
||||
break;
|
||||
}
|
||||
|
||||
// See if a quality has been provided
|
||||
double quality = 1;
|
||||
SkipResult lookForSemiColon = HttpParser.skipConstant(input, ";");
|
||||
if (lookForSemiColon == SkipResult.FOUND) {
|
||||
quality = HttpParser.readWeight(input, ',');
|
||||
}
|
||||
|
||||
if (quality > 0) {
|
||||
result.add(new AcceptLanguage(Locale.forLanguageTag(languageTag), quality));
|
||||
}
|
||||
} while (true);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
146
java/org/apache/tomcat/util/http/parser/Authorization.java
Normal file
146
java/org/apache/tomcat/util/http/parser/Authorization.java
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* 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 implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.tomcat.util.http.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.tomcat.util.res.StringManager;
|
||||
|
||||
/**
|
||||
* Parser for an "Authorization" header.
|
||||
*/
|
||||
public class Authorization {
|
||||
|
||||
private static final StringManager sm = StringManager.getManager(Authorization.class);
|
||||
|
||||
@SuppressWarnings("unused") // Unused due to buggy client implementations
|
||||
private static final Integer FIELD_TYPE_TOKEN = Integer.valueOf(0);
|
||||
private static final Integer FIELD_TYPE_QUOTED_STRING = Integer.valueOf(1);
|
||||
private static final Integer FIELD_TYPE_TOKEN_OR_QUOTED_STRING = Integer.valueOf(2);
|
||||
private static final Integer FIELD_TYPE_LHEX = Integer.valueOf(3);
|
||||
private static final Integer FIELD_TYPE_QUOTED_TOKEN = Integer.valueOf(4);
|
||||
|
||||
private static final Map<String,Integer> fieldTypes = new HashMap<>();
|
||||
|
||||
static {
|
||||
// Digest field types.
|
||||
// Note: These are more relaxed than RFC2617. This adheres to the
|
||||
// recommendation of RFC2616 that servers are tolerant of buggy
|
||||
// clients when they can be so without ambiguity.
|
||||
fieldTypes.put("username", FIELD_TYPE_QUOTED_STRING);
|
||||
fieldTypes.put("realm", FIELD_TYPE_QUOTED_STRING);
|
||||
fieldTypes.put("nonce", FIELD_TYPE_QUOTED_STRING);
|
||||
fieldTypes.put("digest-uri", FIELD_TYPE_QUOTED_STRING);
|
||||
// RFC2617 says response is <">32LHEX<">. 32LHEX will also be accepted
|
||||
fieldTypes.put("response", FIELD_TYPE_LHEX);
|
||||
// RFC2617 says algorithm is token. <">token<"> will also be accepted
|
||||
fieldTypes.put("algorithm", FIELD_TYPE_QUOTED_TOKEN);
|
||||
fieldTypes.put("cnonce", FIELD_TYPE_QUOTED_STRING);
|
||||
fieldTypes.put("opaque", FIELD_TYPE_QUOTED_STRING);
|
||||
// RFC2617 says qop is token. <">token<"> will also be accepted
|
||||
fieldTypes.put("qop", FIELD_TYPE_QUOTED_TOKEN);
|
||||
// RFC2617 says nc is 8LHEX. <">8LHEX<"> will also be accepted
|
||||
fieldTypes.put("nc", FIELD_TYPE_LHEX);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an HTTP Authorization header for DIGEST authentication as per RFC
|
||||
* 2617 section 3.2.2.
|
||||
*
|
||||
* @param input The header value to parse
|
||||
*
|
||||
* @return A map of directives and values as {@link String}s or
|
||||
* <code>null</code> if a parsing error occurs. Although the
|
||||
* values returned are {@link String}s they will have been
|
||||
* validated to ensure that they conform to RFC 2617.
|
||||
*
|
||||
* @throws IllegalArgumentException If the header does not conform to RFC
|
||||
* 2617
|
||||
* @throws java.io.IOException If an error occurs while reading the input
|
||||
*/
|
||||
public static Map<String,String> parseAuthorizationDigest (StringReader input)
|
||||
throws IllegalArgumentException, IOException {
|
||||
|
||||
Map<String,String> result = new HashMap<>();
|
||||
|
||||
if (HttpParser.skipConstant(input, "Digest") != SkipResult.FOUND) {
|
||||
return null;
|
||||
}
|
||||
// All field names are valid tokens
|
||||
String field = HttpParser.readToken(input);
|
||||
if (field == null) {
|
||||
return null;
|
||||
}
|
||||
while (!field.equals("")) {
|
||||
if (HttpParser.skipConstant(input, "=") != SkipResult.FOUND) {
|
||||
return null;
|
||||
}
|
||||
String value;
|
||||
Integer type = fieldTypes.get(field.toLowerCase(Locale.ENGLISH));
|
||||
if (type == null) {
|
||||
// auth-param = token "=" ( token | quoted-string )
|
||||
type = FIELD_TYPE_TOKEN_OR_QUOTED_STRING;
|
||||
}
|
||||
switch (type.intValue()) {
|
||||
case 0:
|
||||
// FIELD_TYPE_TOKEN
|
||||
value = HttpParser.readToken(input);
|
||||
break;
|
||||
case 1:
|
||||
// FIELD_TYPE_QUOTED_STRING
|
||||
value = HttpParser.readQuotedString(input, false);
|
||||
break;
|
||||
case 2:
|
||||
// FIELD_TYPE_TOKEN_OR_QUOTED_STRING
|
||||
value = HttpParser.readTokenOrQuotedString(input, false);
|
||||
break;
|
||||
case 3:
|
||||
// FIELD_TYPE_LHEX
|
||||
value = HttpParser.readLhex(input);
|
||||
break;
|
||||
case 4:
|
||||
// FIELD_TYPE_QUOTED_TOKEN
|
||||
value = HttpParser.readQuotedToken(input);
|
||||
break;
|
||||
default:
|
||||
// Error
|
||||
throw new IllegalArgumentException(
|
||||
sm.getString("authorization.unknownType", type));
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
result.put(field, value);
|
||||
|
||||
if (HttpParser.skipConstant(input, ",") == SkipResult.NOT_FOUND) {
|
||||
return null;
|
||||
}
|
||||
field = HttpParser.readToken(input);
|
||||
if (field == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
108
java/org/apache/tomcat/util/http/parser/ContentRange.java
Normal file
108
java/org/apache/tomcat/util/http/parser/ContentRange.java
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* 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 implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.tomcat.util.http.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
|
||||
public class ContentRange {
|
||||
|
||||
private final String units;
|
||||
private final long start;
|
||||
private final long end;
|
||||
private final long length;
|
||||
|
||||
|
||||
public ContentRange(String units, long start, long end, long length) {
|
||||
this.units = units;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
|
||||
public String getUnits() {
|
||||
return units;
|
||||
}
|
||||
|
||||
|
||||
public long getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
public long getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
|
||||
public long getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a Content-Range header from an HTTP header.
|
||||
*
|
||||
* @param input a reader over the header text
|
||||
*
|
||||
* @return the range parsed from the input, or null if not valid
|
||||
*
|
||||
* @throws IOException if there was a problem reading the input
|
||||
*/
|
||||
public static ContentRange parse(StringReader input) throws IOException {
|
||||
// Units (required)
|
||||
String units = HttpParser.readToken(input);
|
||||
if (units == null || units.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Must be followed by '='
|
||||
if (HttpParser.skipConstant(input, "=") == SkipResult.NOT_FOUND) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Start
|
||||
long start = HttpParser.readLong(input);
|
||||
|
||||
// Must be followed by '-'
|
||||
if (HttpParser.skipConstant(input, "-") == SkipResult.NOT_FOUND) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// End
|
||||
long end = HttpParser.readLong(input);
|
||||
|
||||
// Must be followed by '/'
|
||||
if (HttpParser.skipConstant(input, "/") == SkipResult.NOT_FOUND) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Length
|
||||
long length = HttpParser.readLong(input);
|
||||
|
||||
// Doesn't matter what we look for, result should be EOF
|
||||
SkipResult skipResult = HttpParser.skipConstant(input, "X");
|
||||
|
||||
if (skipResult != SkipResult.EOF) {
|
||||
// Invalid range
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ContentRange(units, start, end, length);
|
||||
}
|
||||
}
|
||||
682
java/org/apache/tomcat/util/http/parser/Cookie.java
Normal file
682
java/org/apache/tomcat/util/http/parser/Cookie.java
Normal file
File diff suppressed because it is too large
Load Diff
139
java/org/apache/tomcat/util/http/parser/Host.java
Normal file
139
java/org/apache/tomcat/util/http/parser/Host.java
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* 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 implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.tomcat.util.http.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
|
||||
import org.apache.tomcat.util.buf.ByteChunk;
|
||||
import org.apache.tomcat.util.buf.MessageBytes;
|
||||
|
||||
public class Host {
|
||||
|
||||
/**
|
||||
* Parse the given input as an HTTP Host header value.
|
||||
*
|
||||
* @param mb The host header value
|
||||
*
|
||||
* @return The position of ':' that separates the host from the port or -1
|
||||
* if it is not present
|
||||
*
|
||||
* @throws IllegalArgumentException If the host header value is not
|
||||
* specification compliant
|
||||
*/
|
||||
public static int parse(MessageBytes mb) {
|
||||
return parse(new MessageBytesReader(mb));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the given input as an HTTP Host header value.
|
||||
*
|
||||
* @param string The host header value
|
||||
*
|
||||
* @return The position of ':' that separates the host from the port or -1
|
||||
* if it is not present
|
||||
*
|
||||
* @throws IllegalArgumentException If the host header value is not
|
||||
* specification compliant
|
||||
*/
|
||||
public static int parse(String string) {
|
||||
return parse(new StringReader(string));
|
||||
}
|
||||
|
||||
|
||||
private static int parse(Reader reader) {
|
||||
try {
|
||||
reader.mark(1);
|
||||
int first = reader.read();
|
||||
reader.reset();
|
||||
if (HttpParser.isAlpha(first)) {
|
||||
return HttpParser.readHostDomainName(reader);
|
||||
} else if (HttpParser.isNumeric(first)) {
|
||||
return HttpParser.readHostIPv4(reader, false);
|
||||
} else if ('[' == first) {
|
||||
return HttpParser.readHostIPv6(reader);
|
||||
} else {
|
||||
// Invalid
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
// Should never happen
|
||||
throw new IllegalArgumentException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class MessageBytesReader extends Reader {
|
||||
|
||||
private final byte[] bytes;
|
||||
private final int end;
|
||||
private int pos;
|
||||
private int mark;
|
||||
|
||||
public MessageBytesReader(MessageBytes mb) {
|
||||
ByteChunk bc = mb.getByteChunk();
|
||||
bytes = bc.getBytes();
|
||||
pos = bc.getOffset();
|
||||
end = bc.getEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(char[] cbuf, int off, int len) throws IOException {
|
||||
for (int i = off; i < off + len; i++) {
|
||||
// Want output in range 0 to 255, not -128 to 127
|
||||
cbuf[i] = (char) (bytes[pos++] & 0xFF);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
// Over-ridden methods to improve performance
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if (pos < end) {
|
||||
// Want output in range 0 to 255, not -128 to 127
|
||||
return bytes[pos++] & 0xFF;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Methods to support mark/reset
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mark(int readAheadLimit) throws IOException {
|
||||
mark = pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() throws IOException {
|
||||
pos = mark;
|
||||
}
|
||||
}
|
||||
}
|
||||
999
java/org/apache/tomcat/util/http/parser/HttpParser.java
Normal file
999
java/org/apache/tomcat/util/http/parser/HttpParser.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,49 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# 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 implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
authorization.unknownType=Unknown Type [{0}]
|
||||
|
||||
cookie.fallToDebug=\n\
|
||||
\ Note: further occurrences of this error will be logged at DEBUG level.
|
||||
cookie.invalidCookieValue=A cookie header was received [{0}] that contained an invalid cookie. That cookie will be ignored.
|
||||
cookie.invalidCookieVersion=A cookie header was received using an unrecognised cookie version of [{0}]. The header and the cookies it contains will be ignored.
|
||||
cookie.valueNotPresent=<not present>
|
||||
|
||||
http.closingBracket=A closing bracket ']' was found in a non-IPv6 host name.
|
||||
http.illegalAfterIpv6=The character [{0}] is not permitted to follow an IPv6 address in a host name
|
||||
http.illegalCharacterDomain=The character [{0}] is never valid in a domain name.
|
||||
http.illegalCharacterIpv4=The character [{0}] is never valid in an IPv4 address.
|
||||
http.illegalCharacterIpv6=The character [{0}] is never valid in an IPv6 address.
|
||||
http.invalidCharacterDomain.afterColon=The character [{0}] is not valid after a colon in a domain name.
|
||||
http.invalidCharacterDomain.afterHyphen=The character [{0}] is not valid after a hyphen in a domain name.
|
||||
http.invalidCharacterDomain.afterLetter=The character [{0}] is not valid after a letter in a domain name.
|
||||
http.invalidCharacterDomain.afterNumber=The character [{0}] is not valid after a number in a domain name.
|
||||
http.invalidCharacterDomain.afterPeriod=The character [{0}] is not valid after a period in a domain name.
|
||||
http.invalidCharacterDomain.atEnd=The character [{0}] is not valid at the end of a domain name.
|
||||
http.invalidCharacterDomain.atStart=The character [{0}] is not valid at the start of a domain name.
|
||||
http.invalidHextet=Invalid hextet. A hextet must consist of 4 or less hex characters.
|
||||
http.invalidIpv4Location=The IPv6 address contains an embedded IPv4 address at an invalid location.
|
||||
http.invalidLeadingZero=A non-zero IPv4 octet may not contain a leading zero.
|
||||
http.invalidOctet=Invalid octet [{0}]. The valid range for IPv4 octets is 0 to 255.
|
||||
http.invalidRequestTargetCharacter=Character [{0}] is not allowed and will continue to be rejected.
|
||||
http.invalidSegmentEndState=The state [{0}] is not valid for the end of a segment.
|
||||
http.noClosingBracket=The IPv6 address is missing a closing bracket.
|
||||
http.noOpeningBracket=The IPv6 address is missing an opening bracket.
|
||||
http.singleColonEnd=An IPv6 address may not end with a single ':'.
|
||||
http.singleColonStart=An IPv6 address may not start with a single ':'.
|
||||
http.tooFewHextets=An IPv6 address must consist of 8 hextets but this address contains [{0}] hextets and no ''::'' sequence to represent one or more zero hextets.
|
||||
http.tooManyColons=An IPv6 address may not contain more than 2 sequential colon characters.
|
||||
http.tooManyDoubleColons=An IPv6 address may only contain a single '::' sequence.
|
||||
http.tooManyHextets=The IPv6 address contains [{0}] hextets but a valid IPv6 address may not have more than 8.
|
||||
@@ -0,0 +1,22 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# 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 implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
cookie.valueNotPresent=<nicht vorhanden>
|
||||
|
||||
http.illegalCharacterIpv4=Das Zeichen [{0}] ist in einer IPv4-Adresse niemals erlaubt.
|
||||
http.invalidHextet=Ungültiges Hextet. Ein Hextet muss aus 4 oder weniger Hexadecimalzeichen bestehen.
|
||||
http.invalidIpv4Location=Die IPV6-Adresse enthält eine eingebettete IPv4-Adresse an einer ungültigen Position.
|
||||
http.invalidOctet=Invalides Oktett [{0}]. Der gültige Bereich für IPv4 Oktette geht von 0 bis 255.
|
||||
http.invalidSegmentEndState=Der Zustand [{0}] ist nicht gültig für das Ende eines Segments.
|
||||
@@ -0,0 +1,22 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# 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 implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
cookie.valueNotPresent=<no presente>
|
||||
|
||||
http.illegalCharacterIpv4=El caracter [{0}] nunca es válido en una dirección IPv4.\n
|
||||
http.illegalCharacterIpv6=El caracter [{0}] nunca es válido en una dirección IPv6.\n
|
||||
http.invalidHextet=Hextet no válido. Hextet debe consistir de 4 caracteres hexadecimales o menos.
|
||||
http.singleColonEnd=Una dirección IPv6 no puede terminar con solo un ':'.\n
|
||||
http.tooManyColons=Una dirección IPv6 no puede contener más de 2 caracteres ":" seguidos
|
||||
@@ -0,0 +1,45 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# 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 implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
cookie.fallToDebug=\ Note: toutes les occurrences suivantes de cette erreur seront enregistrées au niveau DEBUG
|
||||
cookie.invalidCookieValue=Un en-tête de cookie a été reçu [{0}] qui contenait un cookie invalide, celui ci sera ignoré
|
||||
cookie.invalidCookieVersion=Un en-tête de cookie a été reçu utilisant une version [{0}] non reconnue, les cookies seront ignorés
|
||||
cookie.valueNotPresent=<non présent>
|
||||
|
||||
http.closingBracket=Un crochet ']' a été trouvé dans un nom d'hôte non IPv6
|
||||
http.illegalAfterIpv6=Le caractère [{0}] n''est pas permis dans un nom d''hôte à la suite d''une adresse IPv6
|
||||
http.illegalCharacterDomain=Le caractère [{0}] n''est jamais valide pour un nom de domaine
|
||||
http.illegalCharacterIpv4=Le caractère [{0}] n''est pas valide pour une adresse IPV4.
|
||||
http.illegalCharacterIpv6=Le caractère [{0}] n''est jamais valide dans une adresse IPv6
|
||||
http.invalidCharacterDomain.afterColon=Le caractère [{0}] n''est pas valide après deux-point pour un nom de domaine
|
||||
http.invalidCharacterDomain.afterHyphen=Le caractère [{0}] n''est pas valide après un trait d''union pour un nom de domaine
|
||||
http.invalidCharacterDomain.afterLetter=Le caractère [{0}] n''est pas valide après une lettre pour un nom de domaine
|
||||
http.invalidCharacterDomain.afterNumber=Le caractère [{0}] n''est pas valide après un nombre pour un nom de domaine
|
||||
http.invalidCharacterDomain.afterPeriod=Le caractère [{0}] n''est pas valide après une virgule pour un nom de domaine
|
||||
http.invalidCharacterDomain.atEnd=Le caractère [{0}] n''est pas valide à la fin d''un nom de domaine
|
||||
http.invalidCharacterDomain.atStart=Le caractère [{0}] n''est pas valide au début d''un nom de domaine
|
||||
http.invalidHextet="hextet" invalide. Un "hextet" doit consister au maximum de 4 caractères hexadécimaux.
|
||||
http.invalidIpv4Location=L'adresse IPv6 contient une adresse IPv4 incluse à un endroit invalide
|
||||
http.invalidLeadingZero=Un octet IPv4 non nul ne doit pas commencer par un zéro
|
||||
http.invalidOctet=Octet [{0}] invalide. L''éventail valide pour les octets IPv4 est 0-255.
|
||||
http.invalidSegmentEndState=L''état [{0}] n''est pas valide à la fin d''un segment
|
||||
http.noClosingBracket=L'adresse IPv6 n'a pas de crochet de fermeture
|
||||
http.noOpeningBracket=Cette adresse IPv6 n'a pas de crochet d'ouverture '['
|
||||
http.singleColonEnd=Une adresse IPv6 ne doit pas se terminer par un seul ':'
|
||||
http.singleColonStart=Une adresse IPv6 ne doit pas commencer par un seul ':'
|
||||
http.tooFewHextets=Une adresse IPv6 doit être constitué de 8 groupes de 4 octets mais cette adresse en contient [{0}] et pas de séquence "::" pour représenter un ou plusieurs groupes de 4 octets
|
||||
http.tooManyColons=Une adresse IPv6 ne peut pas contenir plus de deux caractères deux-points à la suite
|
||||
http.tooManyDoubleColons=Une adresse IPv6 ne peut contenir qu'une seule séquence "::"
|
||||
http.tooManyHextets=L''adresse IPv6 contient [{0}] groupes de 4 octets mais une adresse IPv6 valide ne doit pas en avoir plus de 8
|
||||
@@ -0,0 +1,45 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# 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 implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
cookie.fallToDebug=注:さらなるこのエラーの発生はDEBUGレベルで記録されます。
|
||||
cookie.invalidCookieValue=無効なCookieを含むCookieヘッダーが受信されました[{0}]。 そのクッキーは無視されます。
|
||||
cookie.invalidCookieVersion=[{0}]の認識できないクッキーバージョンを使用して、Cookieヘッダーが受信されました。 ヘッダーとそれに含まれるクッキーは無視されます。
|
||||
cookie.valueNotPresent=<値が存在しません>
|
||||
|
||||
http.closingBracket=非IPv6ホスト名に閉じ括弧 ']'が見つかりました。
|
||||
http.illegalAfterIpv6=文字[{0}]はホスト名のIPv6アドレスに従うことはできません。
|
||||
http.illegalCharacterDomain=文字 [{0}] をドメイン名に含めることはできません。
|
||||
http.illegalCharacterIpv4=文字 [{0}] は正常な IPv4 アドレスに利用できません。
|
||||
http.illegalCharacterIpv6=IPv6 アドレスに文字 [{0}] を使用することはできません。
|
||||
http.invalidCharacterDomain.afterColon=ドメイン名のコロンの後の文字[{0}]は無効です。
|
||||
http.invalidCharacterDomain.afterHyphen=ドメイン名のハイフンの後の文字[{0}]は無効です
|
||||
http.invalidCharacterDomain.afterLetter=文字 [{0}] はドメイン名に利用できません。
|
||||
http.invalidCharacterDomain.afterNumber=ドメイン名の数字の後の文字[{0}]は無効です。
|
||||
http.invalidCharacterDomain.afterPeriod=ドメイン名のピリオドの後の文字[{0}]は無効です。
|
||||
http.invalidCharacterDomain.atEnd=文字[{0}]はドメイン名の最後には無効です。
|
||||
http.invalidCharacterDomain.atStart=文字[{0}]はドメイン名の先頭には無効です。
|
||||
http.invalidHextet=不正な 16 進数文字列です。16 進数文字列に使用できるのは 4 文字以下の 16 進数だけです。
|
||||
http.invalidIpv4Location=IPv6 アドレスは不正な位置に埋め込み IPv4 アドレスを含んでいます。
|
||||
http.invalidLeadingZero=IPv4 アドレスの 0 でないオクテットは先行する0を含まないかもしれません。
|
||||
http.invalidOctet=無効なオクテット[{0}]。 IPv4オクテットの有効範囲は0〜255です。
|
||||
http.invalidSegmentEndState=状態[{0}]はセグメントの最後には無効です。
|
||||
http.noClosingBracket=IPv6アドレスに閉じ括弧がありません。
|
||||
http.noOpeningBracket=IPv6 アドレスに開き括弧がありません。
|
||||
http.singleColonEnd=IPv6 アドレス文字列は単独のコロン (:) で終端してはなりません。
|
||||
http.singleColonStart=IPv6アドレスは単一の ':'で始まらない場合があります
|
||||
http.tooFewHextets=IPv6 アドレスは 8 個のヘクステットで構成しなければなりませんが [{0}] 個しかありません。また1つ以上のヘクステットを意味する "::" もありません。
|
||||
http.tooManyColons=IPv6 アドレスでは文字 : を 2 つ以上連続することはできません。
|
||||
http.tooManyDoubleColons=IPv6アドレスは単一の '::'シーケンスのみを含むことができます。
|
||||
http.tooManyHextets=IPv6 アドレスは [{0}] ヘクステットで構成されていますが、正常な IPv6 アドレスなら 8 ヘクステット以上になりません。
|
||||
@@ -0,0 +1,46 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# 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 implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
cookie.fallToDebug=\n\
|
||||
비고: 이 오류가 더 발생하는 경우 DEBUG 레벨 로그로 기록될 것입니다.
|
||||
cookie.invalidCookieValue=유효하지 않은 쿠키가 포함된 쿠키 헤더 [{0}]을(를) 받았습니다. 이 쿠키는 무시될 것입니다.
|
||||
cookie.invalidCookieVersion=인식되지 않는 쿠키 버전 [{0}]을(를) 사용한 쿠키 헤더를 받았습니다. 해당 헤더와 그에 포함된 쿠키들은 무시될 것입니다.
|
||||
cookie.valueNotPresent=<not present>
|
||||
|
||||
http.closingBracket=닫는 대괄호(']')가 IPv6 이름이 아닌 호스트 이름에서 발견되었습니다.
|
||||
http.illegalAfterIpv6=호스트 이름 내에서, IPv6 주소 이후에 문자 [{0}]은(는) 허용되지 않습니다.
|
||||
http.illegalCharacterDomain=문자 [{0}]은(는) 도메인 이름 내에서 유효하지 않은 문자입니다.
|
||||
http.illegalCharacterIpv4=문자 [{0}]은(는) IPv4 주소에서 절대 유효하지 않은 것입니다.
|
||||
http.illegalCharacterIpv6=문자 [{0}]은(는) IPv6 주소 내에서 유효하지 않은 것입니다.
|
||||
http.invalidCharacterDomain.afterColon=도메인 이름 내에서, 콜론 이후의 문자 [{0}]은(는) 유효하지 않습니다.
|
||||
http.invalidCharacterDomain.afterHyphen=도메인 이름 내에서, 붙임표(하이픈) 이후의 문자 [{0}]은(는) 유효하지 않습니다.
|
||||
http.invalidCharacterDomain.afterLetter=도메인 이름 내에서, 한 글자 이후의 문자 [{0}]은(는) 유효하지 않습니다.
|
||||
http.invalidCharacterDomain.afterNumber=도메인 이름 내에서, 숫자 이후의 문자 [{0}]은(는) 유효하지 않습니다.
|
||||
http.invalidCharacterDomain.afterPeriod=도메인 이름 내에서, 마침표 이후의 문자 [{0}]은(는) 유효하지 않습니다.
|
||||
http.invalidCharacterDomain.atEnd=도메인 이름의 끝 위치에, 문자 [{0}]은(는) 유효하지 않습니다.
|
||||
http.invalidCharacterDomain.atStart=도메인 이름의 시작 위치에, 문자 [{0}]은(는) 유효하지 않습니다.
|
||||
http.invalidHextet=유효하지 않은 헥스텟(hextet)입니다. 헥스텟은 반드시 네 개 이하의 문자들이어야 합니다.
|
||||
http.invalidIpv4Location=IPv6 주소가, 유효하지 않은 위치에 내장 IPv4 주소를 포함하고 있습니다.
|
||||
http.invalidLeadingZero=IPv4 옥텟(octet)은, 값이 0이 아닌 이상, 0으로 시작해서는 안됩니다.
|
||||
http.invalidOctet=유효하지 않은 옥텟(octet) [{0}]. IPv4 옥텟의 유효한 범위는 0에서 255까지입니다.
|
||||
http.invalidSegmentEndState=상태 [{0}]은(는) segment의 끝으로 유효하지 않습니다.
|
||||
http.noClosingBracket=IPv6 주소에 닫는 대괄호가 없습니다.
|
||||
http.noOpeningBracket=IPv6 주소에 여는 대괄호가 없습니다.
|
||||
http.singleColonEnd=IPv6 주소는 단일 ':' 문자로 끝나서는 안됩니다.
|
||||
http.singleColonStart=IPv6 주소는 단일의 ':'으로 시작할 수 없습니다.
|
||||
http.tooFewHextets=IPv6 주소는 반드시 8개의 헥스텟(hextet)들로 이루어져야 하지만, 이 주소는 [{0}] 개의 헥스텟들으로 이루어져 있고, 하나 이상의 0 헥스텟들을 표시하기 위한 ''::'' 시퀀스도 존재하지 않습니다.
|
||||
http.tooManyColons=IPv6 주소는 연속으로 두 개를 초과한 콜론 문자('':'')들을 포함할 수 없습니다.
|
||||
http.tooManyDoubleColons=IPv6 주소는 단일한 '::' 시퀀스만을 포함해야 합니다.
|
||||
http.tooManyHextets=IPv6 주소가 [{0}]개의 헥스텟(hextet)들을 포함하고 있지만, 유효한 IPv6 주소는 8개를 초과할 수 없습니다.
|
||||
@@ -0,0 +1,38 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# 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 implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
cookie.valueNotPresent=<不存在>
|
||||
|
||||
http.closingBracket=在非IPv6主机名中找到了右括号']'。
|
||||
http.illegalCharacterIpv4=字符[{0}]为非法的IPv4地址。
|
||||
http.illegalCharacterIpv6=字符[{0}]为非法的IPv6地址。
|
||||
http.invalidCharacterDomain.afterColon=字符 [{0}] 在域名中的冒号后无效。
|
||||
http.invalidCharacterDomain.afterHyphen=字符 [{0}] 在域名中的连字符后无效。
|
||||
http.invalidCharacterDomain.afterLetter=字符 [{0}] 在域名中的字母后无效。
|
||||
http.invalidCharacterDomain.afterNumber=字符 [{0}] 在域名中的数字后无效。
|
||||
http.invalidCharacterDomain.afterPeriod=字符 [{0}] 在域名中的句号后无效。
|
||||
http.invalidCharacterDomain.atEnd=字符 [{0}] 在域名末尾无效。
|
||||
http.invalidCharacterDomain.atStart=字符 [{0}] 在域名开头无效。
|
||||
http.invalidHextet=hextet无效。 hextet必须包含4个或更少的十六进制字符。
|
||||
http.invalidIpv4Location=IPv6地址在无效位置包含嵌入的IPv4地址。
|
||||
http.invalidLeadingZero=非零的IPv4字符可能不包含前导零。
|
||||
http.invalidOctet=无效字符[{0}].IPv4字符的有效范围为0~255。
|
||||
http.invalidSegmentEndState=状态[{0}]对于段的结尾无效。
|
||||
http.noClosingBracket=ipv6 地址缺失一个闭合的圆括号
|
||||
http.noOpeningBracket=IPv6地址缺少开括号(
|
||||
http.singleColonEnd=IPv6地址不能以单个“.”结尾。
|
||||
http.singleColonStart=一个IPv6地址也许不是以单个冒号":"开头的。
|
||||
http.tooManyColons=IPv6地址不能包含超过2个连续冒号字符。
|
||||
http.tooManyDoubleColons=一个IPv6地址只能包含一个 '::' 序列。
|
||||
178
java/org/apache/tomcat/util/http/parser/MediaType.java
Normal file
178
java/org/apache/tomcat/util/http/parser/MediaType.java
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* 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 implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.tomcat.util.http.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class MediaType {
|
||||
|
||||
private final String type;
|
||||
private final String subtype;
|
||||
private final LinkedHashMap<String,String> parameters;
|
||||
private final String charset;
|
||||
private volatile String noCharset;
|
||||
private volatile String withCharset;
|
||||
|
||||
protected MediaType(String type, String subtype, LinkedHashMap<String,String> parameters) {
|
||||
this.type = type;
|
||||
this.subtype = subtype;
|
||||
this.parameters = parameters;
|
||||
|
||||
String cs = parameters.get("charset");
|
||||
if (cs != null && cs.length() > 0 && cs.charAt(0) == '"') {
|
||||
cs = HttpParser.unquote(cs);
|
||||
}
|
||||
this.charset = cs;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getSubtype() {
|
||||
return subtype;
|
||||
}
|
||||
|
||||
public String getCharset() {
|
||||
return charset;
|
||||
}
|
||||
|
||||
public int getParameterCount() {
|
||||
return parameters.size();
|
||||
}
|
||||
|
||||
public String getParameterValue(String parameter) {
|
||||
return parameters.get(parameter.toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (withCharset == null) {
|
||||
synchronized (this) {
|
||||
if (withCharset == null) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append(type);
|
||||
result.append('/');
|
||||
result.append(subtype);
|
||||
for (Map.Entry<String, String> entry : parameters.entrySet()) {
|
||||
String value = entry.getValue();
|
||||
if (value == null || value.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
result.append(';');
|
||||
// Workaround for Adobe Read 9 plug-in on IE bug
|
||||
// Can be removed after 26 June 2013 (EOL of Reader 9)
|
||||
// See BZ 53814
|
||||
result.append(' ');
|
||||
result.append(entry.getKey());
|
||||
result.append('=');
|
||||
result.append(value);
|
||||
}
|
||||
|
||||
withCharset = result.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return withCharset;
|
||||
}
|
||||
|
||||
public String toStringNoCharset() {
|
||||
if (noCharset == null) {
|
||||
synchronized (this) {
|
||||
if (noCharset == null) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append(type);
|
||||
result.append('/');
|
||||
result.append(subtype);
|
||||
for (Map.Entry<String, String> entry : parameters.entrySet()) {
|
||||
if (entry.getKey().equalsIgnoreCase("charset")) {
|
||||
continue;
|
||||
}
|
||||
result.append(';');
|
||||
// Workaround for Adobe Read 9 plug-in on IE bug
|
||||
// Can be removed after 26 June 2013 (EOL of Reader 9)
|
||||
// See BZ 53814
|
||||
result.append(' ');
|
||||
result.append(entry.getKey());
|
||||
result.append('=');
|
||||
result.append(entry.getValue());
|
||||
}
|
||||
|
||||
noCharset = result.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return noCharset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a MediaType value, either from an HTTP header or from an application.
|
||||
*
|
||||
* @param input a reader over the header text
|
||||
* @return a MediaType parsed from the input, or null if not valid
|
||||
* @throws IOException if there was a problem reading the input
|
||||
*/
|
||||
public static MediaType parseMediaType(StringReader input) throws IOException {
|
||||
|
||||
// Type (required)
|
||||
String type = HttpParser.readToken(input);
|
||||
if (type == null || type.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (HttpParser.skipConstant(input, "/") == SkipResult.NOT_FOUND) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Subtype (required)
|
||||
String subtype = HttpParser.readToken(input);
|
||||
if (subtype == null || subtype.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
LinkedHashMap<String,String> parameters = new LinkedHashMap<>();
|
||||
|
||||
SkipResult lookForSemiColon = HttpParser.skipConstant(input, ";");
|
||||
if (lookForSemiColon == SkipResult.NOT_FOUND) {
|
||||
return null;
|
||||
}
|
||||
while (lookForSemiColon == SkipResult.FOUND) {
|
||||
String attribute = HttpParser.readToken(input);
|
||||
|
||||
String value = "";
|
||||
if (HttpParser.skipConstant(input, "=") == SkipResult.FOUND) {
|
||||
value = HttpParser.readTokenOrQuotedString(input, true);
|
||||
}
|
||||
|
||||
if (attribute != null) {
|
||||
parameters.put(attribute.toLowerCase(Locale.ENGLISH), value);
|
||||
}
|
||||
|
||||
lookForSemiColon = HttpParser.skipConstant(input, ";");
|
||||
if (lookForSemiColon == SkipResult.NOT_FOUND) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return new MediaType(type, subtype, parameters);
|
||||
}
|
||||
|
||||
}
|
||||
65
java/org/apache/tomcat/util/http/parser/MediaTypeCache.java
Normal file
65
java/org/apache/tomcat/util/http/parser/MediaTypeCache.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* 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 implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.tomcat.util.http.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
|
||||
import org.apache.tomcat.util.collections.ConcurrentCache;
|
||||
|
||||
/**
|
||||
* Caches the results of parsing content-type headers.
|
||||
*/
|
||||
public class MediaTypeCache {
|
||||
|
||||
private final ConcurrentCache<String,String[]> cache;
|
||||
|
||||
public MediaTypeCache(int size) {
|
||||
cache = new ConcurrentCache<>(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks in the cache and returns the cached value if one is present. If no
|
||||
* match exists in the cache, a new parser is created, the input parsed and
|
||||
* the results placed in the cache and returned to the user.
|
||||
*
|
||||
* @param input The content-type header value to parse
|
||||
* @return The results are provided as a two element String array. The
|
||||
* first element is the media type less the charset and
|
||||
* the second element is the charset
|
||||
*/
|
||||
public String[] parse(String input) {
|
||||
String[] result = cache.get(input);
|
||||
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
MediaType m = null;
|
||||
try {
|
||||
m = MediaType.parseMediaType(new StringReader(input));
|
||||
} catch (IOException e) {
|
||||
// Ignore - return null
|
||||
}
|
||||
if (m != null) {
|
||||
result = new String[] {m.toStringNoCharset(), m.getCharset()};
|
||||
cache.put(input, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
124
java/org/apache/tomcat/util/http/parser/Ranges.java
Normal file
124
java/org/apache/tomcat/util/http/parser/Ranges.java
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* 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 implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.tomcat.util.http.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Ranges {
|
||||
|
||||
private final String units;
|
||||
private final List<Entry> entries;
|
||||
|
||||
|
||||
private Ranges(String units, List<Entry> entries) {
|
||||
this.units = units;
|
||||
this.entries = Collections.unmodifiableList(entries);
|
||||
}
|
||||
|
||||
|
||||
public List<Entry> getEntries() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
public String getUnits() {
|
||||
return units;
|
||||
}
|
||||
|
||||
|
||||
public static class Entry {
|
||||
|
||||
private final long start;
|
||||
private final long end;
|
||||
|
||||
|
||||
public Entry(long start, long end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
|
||||
public long getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
public long getEnd() {
|
||||
return end;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a Range header from an HTTP header.
|
||||
*
|
||||
* @param input a reader over the header text
|
||||
*
|
||||
* @return a set of ranges parsed from the input, or null if not valid
|
||||
*
|
||||
* @throws IOException if there was a problem reading the input
|
||||
*/
|
||||
public static Ranges parse(StringReader input) throws IOException {
|
||||
|
||||
// Units (required)
|
||||
String units = HttpParser.readToken(input);
|
||||
if (units == null || units.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Must be followed by '='
|
||||
if (HttpParser.skipConstant(input, "=") == SkipResult.NOT_FOUND) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Range entries
|
||||
List<Entry> entries = new ArrayList<>();
|
||||
|
||||
SkipResult skipResult;
|
||||
do {
|
||||
long start = HttpParser.readLong(input);
|
||||
// Must be followed by '-'
|
||||
if (HttpParser.skipConstant(input, "-") == SkipResult.NOT_FOUND) {
|
||||
return null;
|
||||
}
|
||||
long end = HttpParser.readLong(input);
|
||||
|
||||
if (start == -1 && end == -1) {
|
||||
// Invalid range
|
||||
return null;
|
||||
}
|
||||
|
||||
entries.add(new Entry(start, end));
|
||||
|
||||
skipResult = HttpParser.skipConstant(input, ",");
|
||||
if (skipResult == SkipResult.NOT_FOUND) {
|
||||
// Invalid range
|
||||
return null;
|
||||
}
|
||||
} while (skipResult == SkipResult.FOUND);
|
||||
|
||||
// There must be at least one entry
|
||||
if (entries.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Ranges(units, entries);
|
||||
}
|
||||
}
|
||||
23
java/org/apache/tomcat/util/http/parser/SkipResult.java
Normal file
23
java/org/apache/tomcat/util/http/parser/SkipResult.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* 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 implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.tomcat.util.http.parser;
|
||||
|
||||
enum SkipResult {
|
||||
FOUND,
|
||||
NOT_FOUND,
|
||||
EOF
|
||||
}
|
||||
113
java/org/apache/tomcat/util/http/parser/TokenList.java
Normal file
113
java/org/apache/tomcat/util/http/parser/TokenList.java
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* 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 implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.tomcat.util.http.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Locale;
|
||||
|
||||
public class TokenList {
|
||||
|
||||
private TokenList() {
|
||||
// Utility class. Hide default constructor.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses an enumeration of header values of the form 1#token, forcing all
|
||||
* parsed values to lower case.
|
||||
*
|
||||
* @param inputs The headers to parse
|
||||
* @param collection The Collection (usually a list of a set) to which the
|
||||
* parsed tokens should be added
|
||||
*
|
||||
* @return {@code} true if the header values were parsed cleanly, otherwise
|
||||
* {@code false} (e.g. if a non-token value was encountered)
|
||||
*
|
||||
* @throws IOException If an I/O error occurs reading the header
|
||||
*/
|
||||
public static boolean parseTokenList(Enumeration<String> inputs, Collection<String> collection) throws IOException {
|
||||
boolean result = true;
|
||||
while (inputs.hasMoreElements()) {
|
||||
String nextHeaderValue = inputs.nextElement();
|
||||
if (nextHeaderValue != null) {
|
||||
if (!TokenList.parseTokenList(new StringReader(nextHeaderValue), collection)) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a header of the form 1#token, forcing all parsed values to lower
|
||||
* case. This is typically used when header values are case-insensitive.
|
||||
*
|
||||
* @param input The header to parse
|
||||
* @param collection The Collection (usually a list of a set) to which the
|
||||
* parsed tokens should be added
|
||||
*
|
||||
* @return {@code} true if the header was parsed cleanly, otherwise
|
||||
* {@code false} (e.g. if a non-token value was encountered)
|
||||
*
|
||||
* @throws IOException If an I/O error occurs reading the header
|
||||
*/
|
||||
public static boolean parseTokenList(Reader input, Collection<String> collection) throws IOException {
|
||||
boolean invalid = false;
|
||||
boolean valid = false;
|
||||
|
||||
do {
|
||||
String fieldName = HttpParser.readToken(input);
|
||||
if (fieldName == null) {
|
||||
// Invalid field-name, skip to the next one
|
||||
invalid = true;
|
||||
HttpParser.skipUntil(input, 0, ',');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fieldName.length() == 0) {
|
||||
// No more data to read
|
||||
break;
|
||||
}
|
||||
|
||||
SkipResult skipResult = HttpParser.skipConstant(input, ",");
|
||||
if (skipResult == SkipResult.EOF) {
|
||||
// EOF
|
||||
valid = true;
|
||||
collection.add(fieldName.toLowerCase(Locale.ENGLISH));
|
||||
break;
|
||||
} else if (skipResult == SkipResult.FOUND) {
|
||||
valid = true;
|
||||
collection.add(fieldName.toLowerCase(Locale.ENGLISH));
|
||||
continue;
|
||||
} else {
|
||||
// Not a token - ignore it
|
||||
invalid = true;
|
||||
HttpParser.skipUntil(input, 0, ',');
|
||||
continue;
|
||||
}
|
||||
} while (true);
|
||||
|
||||
// Only return true if at least one valid token was read and no invalid
|
||||
// entries were found
|
||||
return valid && !invalid;
|
||||
}
|
||||
}
|
||||
37
java/org/apache/tomcat/util/http/parser/Vary.java
Normal file
37
java/org/apache/tomcat/util/http/parser/Vary.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* 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 implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.tomcat.util.http.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link TokenList}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class Vary {
|
||||
|
||||
private Vary() {
|
||||
// Utility class. Hide default constructor.
|
||||
}
|
||||
|
||||
|
||||
public static void parseVary(StringReader input, Set<String> result) throws IOException {
|
||||
TokenList.parseTokenList(input, result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user