/* * 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;
/** * Set to the reason for the failure (the first failure if there is more than one) if there were failures during * parameter parsing.
*/ private FailReason parseFailedReason = null;
// -------------------- Data access -------------------- // Access to the current name/values, no side effect ( processing ). // You must explicitly call handleQueryParameters and the post methods.
public String[] getParameterValues(String name) {
handleQueryParameters(); // no "facade"
ArrayList<String> values = paramHashValues.get(name); if (values == null) { returnnull;
} return values.toArray(new String[0]);
}
public Enumeration<String> getParameterNames() {
handleQueryParameters(); return Collections.enumeration(paramHashValues.keySet());
}
public String getParameter(String name) {
handleQueryParameters();
ArrayList<String> values = paramHashValues.get(name); if (values != null) { if (values.size() == 0) { return"";
} return values.get(0);
} else { returnnull;
}
}
// -------------------- Processing -------------------- /** * Process the query string into parameters
*/ publicvoid handleQueryParameters() { if (didQueryParameters) { return;
}
didQueryParameters = true;
if (queryMB == null || queryMB.isNull()) { return;
}
if (limit > -1 && parameterCount >= limit) { // Processing this parameter will push us over the limit. ISE is // what Request.parseParts() uses for requests that are too big
setParseFailedReason(FailReason.TOO_MANY_PARAMETERS); thrownew IllegalStateException(sm.getString("parameters.maxCountFail", Integer.valueOf(limit)));
}
parameterCount++;
paramHashValues.computeIfAbsent(key, k -> new ArrayList<>(1)).add(value);
}
// -------------------- Parameter parsing -------------------- // we are called from a single thread - we can do it the hard way // if needed privatefinal ByteChunk tmpName = new ByteChunk(); privatefinal ByteChunk tmpValue = new ByteChunk(); privatefinal ByteChunk origName = new ByteChunk(); privatefinal ByteChunk origValue = new ByteChunk(); privatestaticfinal Charset DEFAULT_BODY_CHARSET = StandardCharsets.ISO_8859_1; privatestaticfinal Charset DEFAULT_URI_CHARSET = StandardCharsets.UTF_8;
publicvoid processParameters(byte bytes[], int start, int len) {
processParameters(bytes, start, len, charset);
}
privatevoid processParameters(byte bytes[], int start, int len, Charset charset) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("parameters.bytes", new String(bytes, start, len, DEFAULT_BODY_CHARSET)));
}
int decodeFailCount = 0;
int pos = start; int end = start + len;
while (pos < end) { int nameStart = pos; int nameEnd = -1; int valueStart = -1; int valueEnd = -1;
// Take copies as if anything goes wrong originals will be // corrupted. This means original values can be logged. // For performance - only done for debug if (log.isDebugEnabled()) { try {
origName.append(bytes, nameStart, nameEnd - nameStart); if (valueStart >= 0) {
origValue.append(bytes, valueStart, valueEnd - valueStart);
} else {
origValue.append(bytes, 0, 0);
}
} catch (IOException ioe) { // Should never happen...
log.error(sm.getString("parameters.copyFail"), ioe);
}
}
try {
String name;
String value;
if (decodeName) {
urlDecode(tmpName);
}
tmpName.setCharset(charset);
name = tmpName.toString();
if (valueStart >= 0) { if (decodeValue) {
urlDecode(tmpValue);
}
tmpValue.setCharset(charset);
value = tmpValue.toString();
} else {
value = "";
}
try {
addParameter(name, value);
} catch (IllegalStateException ise) { // Hitting limit stops processing further params but does // not cause request to fail.
UserDataHelper.Mode logMode = maxParamCountLog.getNextMode(); if (logMode != null) {
String message = ise.getMessage(); switch (logMode) { case INFO_THEN_DEBUG:
message += sm.getString("parameters.maxCountFail.fallToDebug"); //$FALL-THROUGH$ case INFO:
log.info(message); break; case DEBUG:
log.debug(message);
}
} break;
}
} catch (IOException e) {
setParseFailedReason(FailReason.URL_DECODING);
decodeFailCount++; if (decodeFailCount == 1 || log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(
sm.getString("parameters.decodeFail.debug", origName.toString(), origValue.toString()),
e);
} elseif (log.isInfoEnabled()) {
UserDataHelper.Mode logMode = userDataLog.getNextMode(); if (logMode != null) {
String message =
sm.getString("parameters.decodeFail.info", tmpName.toString(), tmpValue.toString()); switch (logMode) { case INFO_THEN_DEBUG:
message += sm.getString("parameters.fallToDebug"); //$FALL-THROUGH$ case INFO:
log.info(message); break; case DEBUG:
log.debug(message);
}
}
}
}
}
tmpName.recycle();
tmpValue.recycle(); // Only recycle copies if we used them if (log.isDebugEnabled()) {
origName.recycle();
origValue.recycle();
}
}
if (decodeFailCount > 1 && !log.isDebugEnabled()) {
UserDataHelper.Mode logMode = userDataLog.getNextMode(); if (logMode != null) {
String message = sm.getString("parameters.multipleDecodingFail", Integer.valueOf(decodeFailCount)); switch (logMode) { case INFO_THEN_DEBUG:
message += sm.getString("parameters.fallToDebug"); //$FALL-THROUGH$ case INFO:
log.info(message); break; case DEBUG:
log.debug(message);
}
}
}
}
privatevoid urlDecode(ByteChunk bc) throws IOException { if (urlDec == null) {
urlDec = new UDecoder();
}
urlDec.convert(bc, true);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.