camel-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Claus Ibsen <>
Subject [DISCUSS] - Camel 2.0 - Case insensitive headers on Camel Message
Date Sat, 08 Aug 2009 10:42:18 GMT

For background see ticket CAMEL-1886

The issue is that headers is stored using keys that are case
sensitive, and that leads to a few problems and differences in Camel:

- lookup is cumbersome as you must match case 100%
- errors in camel components that is unable to realize a header
already exists however with a different (case)
- some protocols are agnostic to header cases, such as HTTP (and all
its different transports using HTTP), Mail, and whatnot?
- camel-mail stores notoriously headers in lower keys only
- etc.

And most importantly
- no one wants to send different values using a key that have
different case, such as:

So James and I had a chat about it and to see if would could do
something about it.

The real reason that I picked up this issue is the tuning experiment
with Camel 2.x

Where we want to take a few short cuts and offer header lookup on the
source directly to avoid the "tiny" overhead of extracting headers
from the source
and populate the camel message. This is useful if you do message
routing that only uses headers. The camel-jms component did already
offer this but
it also had some inconsistency in this relation.

I have attempted a resolution in the tuning branch but discovered an
issue, that it does take some more grunt work to keep the lower case
index in sync etc.
So I wanted to try a different approach


I have implemented a small case insenstive map so we can store headers
in 1 map instead of keeping 2 maps in sync.
I am still amazed why such a Map does not exists directly in the JDK itself.

What does this offer then
- lookup is easy as you can lookup using any case
  and in the future we could also offer lookup for special keys people
spell differently such as: ContentType, content-type, content-type,
content_type and whatnot.
- put will also ensure that it replaces existing values
- and most importantly that it offers this as well when end users work
directly on the map using:
     exchange.getIn().getHeaders().put("foo", "beer")
  That will be able to replace existing keys if they are stored using:
Foo, FOO or what not
  This is not possible today and or with a 2nd map that tracks lower
case indexes

So how to retain the original keys.

Well I implemented that as well, so when you e.g. copy the map to
another or extract from it using keySet it exposes a Set that uses the
original key cases.
So if you have stored using
   exchange.getIn().setHeader("Foo", "cheese")

Then the key in the ketSet is the original key = Foo.
But you can do lookup using: foo, FOO, FoO, FOo, and whatnot :)

Using this implementation I actually find a few bugs in existing unit
tests and camel components that double add headers using different
For example camel-cxf in the new RS support.

I will later attach the code to the CAMEL-1886 ticket for people of
the community to take a look and review.

Here is a snippet from one of the test methods to give an idea

    public void testLookupCaseAgnosticAddHeaderRemoveHeader() {
        Map<String, Object> map = new CaseInsensitiveMap();

        map.put("foo", "cheese");

        assertEquals("cheese", map.get("foo"));
        assertEquals("cheese", map.get("Foo"));
        assertEquals("cheese", map.get("FOO"));

        map.put("bar", "beer");

        assertEquals("beer", map.get("bar"));
        assertEquals("beer", map.get("Bar"));
        assertEquals("beer", map.get("BAR"));


And when using the Message API

    public void testRemoveWithDifferentCase() {
        Message msg = new DefaultMessage();

        msg.setHeader("foo", "cheese");
        msg.setHeader("Foo", "bar");

        assertEquals("bar", msg.getHeader("FOO"));
        assertEquals("bar", msg.getHeader("foo"));
        assertEquals("bar", msg.getHeader("Foo"));


        assertEquals(null, msg.getHeader("foo"));
        assertEquals(null, msg.getHeader("Foo"));
        assertEquals(null, msg.getHeader("FOO"));


Claus Ibsen
Apache Camel Committer

Open Source Integration:

View raw message