ExceptionReporting.java
/*
* 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.tika.config;
import java.io.Serializable;
import java.util.Objects;
import org.apache.tika.annotation.TikaComponent;
import org.apache.tika.parser.ParseContext;
/**
* How much detail Tika reports when an exception is turned into a string: the
* {@code tk:exception:*} metadata values, tika-server error bodies and pipes result messages.
* <p>
* Stack traces and exception messages can carry file paths, hostnames and fragments of the
* document being parsed. Operators who expose Tika to untrusted callers can reduce that with
* {@link Level} and bound the size with {@code maxLength}.
* <ul>
* <li>{@link Level#FULL} - the complete stack trace (default)</li>
* <li>{@link Level#MESSAGE_REDACTED} - the complete stack trace with every exception message
* removed; class names, frames and the cause chain are kept</li>
* <li>{@link Level#REDACTED} - exception class names only (the cause chain, no frames,
* no messages)</li>
* </ul>
* {@code maxLength} caps the formatted string: a longer value is cut to {@code maxLength}
* characters and a {@code ...[truncated]} marker is appended (-1 = unlimited).
* <p>
* Loaded from the {@code parse-context} section of the config and deliberately not settable
* per request: a caller could otherwise turn redaction back off.
*
* @since Apache Tika 4.1
*/
@TikaComponent(name = "exception-reporting", spi = false)
public class ExceptionReporting implements Serializable {
private static final long serialVersionUID = 1L;
public enum Level {
REDACTED, MESSAGE_REDACTED, FULL
}
public static final int UNLIMITED = -1;
private Level level = Level.FULL;
private int maxLength = UNLIMITED;
public ExceptionReporting() {
}
public ExceptionReporting(Level level, int maxLength) {
setLevel(level);
setMaxLength(maxLength);
}
public Level getLevel() {
return level;
}
public void setLevel(Level level) {
this.level = Objects.requireNonNull(level, "level");
}
public int getMaxLength() {
return maxLength;
}
public void setMaxLength(int maxLength) {
//0 is rejected rather than treated as "report nothing": it would emit only the marker
if (maxLength < UNLIMITED || maxLength == 0) {
throw new IllegalArgumentException(
"maxLength must be positive or -1 for unlimited, was " + maxLength);
}
this.maxLength = maxLength;
}
/**
* @return the context's policy, or a new instance with the defaults
*/
public static ExceptionReporting get(ParseContext context) {
if (context == null) {
return new ExceptionReporting();
}
ExceptionReporting reporting = context.get(ExceptionReporting.class);
return reporting != null ? reporting : new ExceptionReporting();
}
@Override
public String toString() {
return "ExceptionReporting{level=" + level + ", maxLength=" + maxLength + '}';
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ExceptionReporting that = (ExceptionReporting) o;
return maxLength == that.maxLength && level == that.level;
}
@Override
public int hashCode() {
return 31 * level.hashCode() + maxLength;
}
}