Skip to content

Commit 1719f82

Browse files
committed
TIKA-4809: Remove meta_* injection and the dead X-Tika-Handler constant
1 parent b0a24fe commit 1719f82

6 files changed

Lines changed: 80 additions & 52 deletions

File tree

docs/modules/ROOT/pages/migration-to-4x/migrating-tika-server-4x.adoc

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,75 @@ The following `TikaServerConfig` options have been removed:
151151
* `taskPulseMillis` - No longer needed
152152
* `minimumTimeoutMillis` - No longer needed
153153
154+
=== Configuration via HTTP Headers Removed
155+
156+
4.x configures parsing through the tika-config file, not through request headers.
157+
The remaining per-request configuration headers have been removed and are now
158+
**silently ignored** if sent — the request succeeds, the header has no effect:
159+
160+
|===
161+
|Removed header |Replacement
162+
163+
|`writeLimit`
164+
|`parse-context.output-limits.writeLimit`
165+
166+
|`throwOnWriteLimitReached`
167+
|`parse-context.output-limits.throwOnWriteLimit`
168+
169+
|`maxEmbeddedResources`, `maxEmbeddedCount`
170+
|`parse-context.embedded-limits.maxCount`
171+
172+
|`meta_*` (arbitrary metadata injection)
173+
|_no replacement_ — see below
174+
175+
|`X-Tika-Handler`
176+
|Use an explicit handler path (`/tika/text`, `/rmeta/xml`, `/tika/json/html`, ...)
177+
|===
178+
179+
The `X-Tika-OCR*` and `X-Tika-PDF*` header families were removed earlier in the
180+
4.x line. Parser configuration is now supplied as JSON.
181+
182+
[source,json]
183+
----
184+
{
185+
"parse-context": {
186+
"output-limits": {
187+
"writeLimit": 100000,
188+
"throwOnWriteLimit": false
189+
},
190+
"embedded-limits": {
191+
"maxCount": 10
192+
}
193+
}
194+
}
195+
----
196+
197+
**Migration:** move these settings into your tika-config. For per-request values,
198+
POST to a `/config` endpoint (`/tika/config`, `/tika/config/json`, `/rmeta/config`,
199+
`/meta/config`) with the JSON above as the multipart `config` part; this requires
200+
`allowPerRequestConfig=true`.
201+
202+
[IMPORTANT]
203+
====
204+
Two capabilities are genuinely gone, not relocated.
205+
206+
**Per-request output bounds without `allowPerRequestConfig`.** With the headers
207+
removed and per-request config off by default, a caller can no longer bound the
208+
output of a single request; the limits are whatever the operator configured. If
209+
you relied on clients setting their own `writeLimit`, either enable
210+
`allowPerRequestConfig` or set a server-wide limit.
211+
212+
**Client-supplied metadata (`meta_*`).** Headers prefixed `meta_` were copied
213+
into the returned metadata under the remainder of the header name, with no key
214+
restrictions — so a request could also overwrite keys Tika itself populates.
215+
There is no replacement on the push endpoints; attach provenance on your side of
216+
the call, or use `/pipes`, where the `FetchEmitTuple` carries metadata.
217+
====
218+
219+
Transport headers are unaffected: `Content-Disposition`/`File-Name`,
220+
`Content-Type` and `Content-Length` still describe the payload and still
221+
influence detection.
222+
154223
=== Removed Features
155224
156225
* **Fetcher-based streaming** - The `InputStreamFactory` pattern for fetching documents via HTTP headers (`fetcherName`, `fetchKey`) has been removed. All documents are now processed via temp files through the pipes infrastructure.

docs/modules/ROOT/pages/migration-to-4x/migrating-to-4x.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ If you have build scripts or container images that drop in just the jar, update
4545
In 3.x the default content handler produced XHTML/XML. In 4.x the default is **Markdown** everywhere:
4646

4747
* `tika-app` outputs Markdown by default (was XHTML). Pass `-x`/`--xml`, `-h`/`--html`, or `-t`/`--text` to choose another format.
48-
* `tika-server` — the `/tika` and `/rmeta` endpoints return Markdown content by default (was XHTML/XML). Use an explicit handler path (`/tika/xml`, `/rmeta/xml`, ...) or the `X-Tika-Handler` header to choose another format.
48+
* `tika-server` — the `/tika` and `/rmeta` endpoints return Markdown content by default (was XHTML/XML). Use an explicit handler path (`/tika/xml`, `/rmeta/xml`, ...) to choose another format.
4949
* The async/pipes CLI emits Markdown by default (was plain text). Use `--handler x` (etc.) to choose another format.
5050

5151
If you parse the extracted content programmatically and expect XHTML/XML, request it explicitly as shown above (TIKA-4663).

docs/modules/ROOT/pages/pipes/cpu-sizing.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ report `autoCap=user-set in forkedJvmArgs`.
169169
A reasonable starting point is **~2 GB of heap per forked worker** (passed via `-Xmx2g` in `forkedJvmArgs`). The number falls out of three independent constraints any of which can dominate:
170170

171171
* **Worst-case PDF parsing.** A handful of pathological PDFs in any reasonably large corpus will allocate hundreds of MB of intermediate object data per document — large image streams, deeply nested form fields, big embedded fonts. Smaller heaps OOM on those documents; larger heaps just let GC clean up between docs.
172-
* **Embedded-document explosion.** A zip-bomb-shaped office document with thousands of embedded objects multiplies per-doc allocation by the embedding count. The `maxEmbeddedResources` setting caps the count, but each retained object still lives in the heap until the whole tree finishes parsing.
172+
* **Embedded-document explosion.** A zip-bomb-shaped office document with thousands of embedded objects multiplies per-doc allocation by the embedding count. The `parse-context.embedded-limits.maxCount` setting caps the count, but each retained object still lives in the heap until the whole tree finishes parsing.
173173
* **GC headroom.** G1GC behaves poorly above ~85% occupancy. A `-Xmx2g` worker comfortably handles documents that allocate up to ~1.5 GB of live data; below that you start trading throughput for memory.
174174

175175
This is a default — not a tuning recommendation. To right-size for your specific corpus:

docs/modules/ROOT/pages/using-tika/server/index.adoc

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -143,17 +143,6 @@ the JSON variant, you can also nest a handler — `/tika/json/text`,
143143
envelope; that nested handler accepts the full set (`text`, `html`, `xml`,
144144
`md`, `markdown`, `body`, `ignore`).
145145

146-
==== `X-Tika-Handler` header
147-
148-
For the root `/tika` PUT endpoint you can also pick the handler with a header:
149-
150-
[source,bash]
151-
----
152-
curl -T document.pdf -H "X-Tika-Handler: markdown" http://localhost:9998/tika
153-
----
154-
155-
Accepted values: `text`, `html`, `xml`, `markdown` (or `md`), `body`, `ignore`. The default is `markdown`.
156-
157146
=== Recursive Metadata (`/rmeta`)
158147

159148
Returns metadata for the container document and all embedded documents as a JSON

tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/TikaResource.java

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,6 @@
7676
public class TikaResource {
7777

7878
public static final String GREETING = "This is Tika Server (" + Tika.getString() + "). Please PUT\n";
79-
/**
80-
* Header to specify the handler type for content extraction.
81-
* Valid values: text, html, xml, markdown, ignore (default: text)
82-
*/
83-
public static final String HANDLER_TYPE_HEADER = "X-Tika-Handler";
84-
private static final String META_PREFIX = "meta_";
8579
private static final Logger LOG = LoggerFactory.getLogger(TikaResource.class);
8680

8781
// Instance (not static): production only ever creates one CXF server -- and so
@@ -211,6 +205,15 @@ public static void fillMetadata(Parser parser, Metadata metadata, MultivaluedMap
211205
mediaType = null;
212206
}
213207

208+
// Transport content types, not statements about the document: curl sends
209+
// x-www-form-urlencoded by default for --data-binary, and multipart/form-data
210+
// describes the envelope rather than the file inside it.
211+
if (mediaType != null
212+
&& (mediaType.equals(jakarta.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED_TYPE)
213+
|| mediaType.equals(jakarta.ws.rs.core.MediaType.MULTIPART_FORM_DATA_TYPE))) {
214+
mediaType = null;
215+
}
216+
214217
if (mediaType != null) {
215218
metadata.set(Metadata.CONTENT_TYPE, mediaType.toString());
216219
metadata.add(TikaCoreProperties.CONTENT_TYPE_USER_OVERRIDE, mediaType.toString());
@@ -219,19 +222,6 @@ public static void fillMetadata(Parser parser, Metadata metadata, MultivaluedMap
219222
if (httpHeaders.containsKey("Content-Length")) {
220223
metadata.set(Metadata.CONTENT_LENGTH, httpHeaders.getFirst("Content-Length"));
221224
}
222-
223-
for (Map.Entry<String, List<String>> e : httpHeaders.entrySet()) {
224-
if (e
225-
.getKey()
226-
.startsWith(META_PREFIX)) {
227-
String tikaKey = e
228-
.getKey()
229-
.substring(META_PREFIX.length());
230-
for (String value : e.getValue()) {
231-
metadata.add(tikaKey, value);
232-
}
233-
}
234-
}
235225
}
236226

237227
/**

tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/RecursiveMetadataResourceTest.java

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
import java.util.Arrays;
3131
import java.util.List;
3232

33-
import jakarta.ws.rs.core.MultivaluedHashMap;
34-
import jakarta.ws.rs.core.MultivaluedMap;
3533
import jakarta.ws.rs.core.Response;
3634
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
3735
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
@@ -175,24 +173,6 @@ public void testSimpleWord() throws Exception {
175173
.get("tk:digest:MD5"));
176174
}
177175

178-
@Test
179-
public void testHeaders() throws Exception {
180-
MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
181-
map.addAll("meta_mymeta", "first", "second", "third");
182-
183-
Response response = WebClient
184-
.create(endPoint + META_PATH)
185-
.headers(map)
186-
.accept("application/json")
187-
.put(ClassLoader.getSystemResourceAsStream(TEST_RECURSIVE_DOC));
188-
189-
Reader reader = new InputStreamReader((InputStream) response.getEntity(), UTF_8);
190-
List<Metadata> metadataList = JsonMetadataList.fromJson(reader);
191-
assertEquals("first,second,third", metadataList
192-
.get(0)
193-
.get("mymeta"));
194-
}
195-
196176
@Test
197177
public void testPasswordProtected() throws Exception {
198178
// Test that encrypted document without password shows error

0 commit comments

Comments
 (0)