PipesWorkerCallerHintsTest.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.pipes.core.server;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import org.junit.jupiter.api.Test;
import org.apache.tika.io.TikaInputStream;
import org.apache.tika.metadata.HttpHeaders;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.metadata.TikaCoreProperties;
import org.apache.tika.mime.MediaType;
import org.apache.tika.mime.MimeTypes;
import org.apache.tika.parser.ParseContext;
/**
* Unit tests for {@link PipesWorker#carryCallerHints(Metadata, Metadata)}, which carries the
* caller-supplied detection hints across the worker's fresh-metadata boundary.
*/
public class PipesWorkerCallerHintsTest {
@Test
public void testCarriesResourceNameAndContentType() {
Metadata tuple = new Metadata();
tuple.set(TikaCoreProperties.RESOURCE_NAME_KEY, "photo.nef");
tuple.set(HttpHeaders.CONTENT_TYPE, "image/x-raw-nikon");
Metadata target = new Metadata();
PipesWorker.carryCallerHints(tuple, target);
assertEquals("photo.nef", target.get(TikaCoreProperties.RESOURCE_NAME_KEY));
assertEquals("image/x-raw-nikon", target.get(HttpHeaders.CONTENT_TYPE));
}
/**
* The Content-Type is carried only as a soft hint. The unconditional override keys
* must never be carried, or a caller could force any type past detection.
*/
@Test
public void testDoesNotCarryOverrides() {
Metadata tuple = new Metadata();
tuple.set(TikaCoreProperties.CONTENT_TYPE_USER_OVERRIDE, "image/x-raw-nikon");
tuple.set(TikaCoreProperties.CONTENT_TYPE_PARSER_OVERRIDE, "image/x-raw-nikon");
Metadata target = new Metadata();
PipesWorker.carryCallerHints(tuple, target);
assertNull(target.get(TikaCoreProperties.CONTENT_TYPE_USER_OVERRIDE));
assertNull(target.get(TikaCoreProperties.CONTENT_TYPE_PARSER_OVERRIDE));
assertNull(target.get(HttpHeaders.CONTENT_TYPE));
}
@Test
public void testNullTupleIsNoOp() {
Metadata target = new Metadata();
target.set(TikaCoreProperties.RESOURCE_NAME_KEY, "keep.me");
PipesWorker.carryCallerHints(null, target);
assertEquals("keep.me", target.get(TikaCoreProperties.RESOURCE_NAME_KEY));
}
@Test
public void testBlankValuesNotCarried() {
Metadata tuple = new Metadata();
tuple.set(TikaCoreProperties.RESOURCE_NAME_KEY, " ");
tuple.set(HttpHeaders.CONTENT_TYPE, "");
Metadata target = new Metadata();
PipesWorker.carryCallerHints(tuple, target);
assertNull(target.get(TikaCoreProperties.RESOURCE_NAME_KEY));
assertNull(target.get(HttpHeaders.CONTENT_TYPE));
}
//content that magic-detects as image/tiff (little-endian TIFF marker, no CR2 marker)
private static final byte[] TIFF_BYTES = {'I', 'I', 0x2A, 0x00, 0, 0, 0, 8};
private static MediaType detectWithCarriedContentType(String contentType) throws Exception {
Metadata tuple = new Metadata();
tuple.set(HttpHeaders.CONTENT_TYPE, contentType);
Metadata target = new Metadata();
PipesWorker.carryCallerHints(tuple, target);
try (TikaInputStream tis = TikaInputStream.get(TIFF_BYTES)) {
return MimeTypes.getDefaultMimeTypes().detect(tis, target, new ParseContext());
}
}
/**
* A carried Content-Type that specializes the content-detected type refines detection.
* image/x-canon-cr2 is a sub-class-of image/tiff, and these bytes lack the CR2 marker.
*/
@Test
public void testSpecializingContentTypeRefinesDetection() throws Exception {
assertEquals(MediaType.image("x-canon-cr2"),
detectWithCarriedContentType("image/x-canon-cr2"));
}
/**
* Security boundary: a carried Content-Type that does NOT specialize the content-detected
* type is ignored, so a caller cannot force an unrelated type onto the document.
*/
@Test
public void testNonSpecializingContentTypeIgnored() throws Exception {
assertEquals(MediaType.image("tiff"), detectWithCarriedContentType("audio/mpeg"));
assertEquals(MediaType.image("tiff"), detectWithCarriedContentType("not-a-media-type"));
}
}