Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make MessageHeaders get() and containsKey() methods case-insensitive [SPR-17553] #22085

Closed
spring-projects-issues opened this issue Jan 10, 2011 · 12 comments
Labels
in: messaging status: bulk-closed

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Jan 10, 2011

tony kerz opened SPR-17553 and commented

ok, I just came to the realization that tomcat converts header names to lower case,
and I guess it is within it's right to do so because the servlet spec states that headers are case-insensitive:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2

it follows that any servlet container may do what ever it wants with the case of headers,
so any search for a header by key must be done in a case-insensitive way.

coincidentally, I see that you have just been doing some cleanup associated with this as well:
http://forum.springframework.org/showpost.php?s=2fa1e38186a0a8b234adf885aca690ca&p=337615&postcount=20

my issue is that if a Spring Integration Message passes over an HTTP transport,
that although you may now do the right thing with respect to DefaultHttpHeaderMapper,
the original case of the header name may have changed from when I placed it in the Message,
so if I search for it via MessageHeaders get() or containsKey() I will not find it.

How would you guys feel about making MessageHeaders.get()/containsKey() operate in a case insensitive manner as does HttpServletRequest.getHeader()...?

http://download.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#getHeader%28java.lang.String%29


No further details from SPR-17553

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jan 10, 2011

Oleg Zhurakousky commented

Tony

It has been fixed last week https://jira.springsource.org/browse/INT-1734

Are you running with the snapshot build?

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jan 10, 2011

Oleg Zhurakousky commented

Just to add a little more; Yes since the specs mandates that Http header names case should be ignored we have to honor this. However, i don't yet see a compelling reason to propagate such behavior to MessageHeaders.
I understand that you may be setting 'Accept' and receiving it as 'accept', but what you can do is use DefaultHttpHeaderMapper.fromHeaders(MessageHeaders, HttpHeaders) and operate on the instance of HttpHeaders for all headers that were transported over HTTP and should not be case sensitive.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jan 10, 2011

tony kerz commented

do you see my point though that once a Message and it's associated MessageHeaders has passed over HTTP,
that you can no longer count on a particular case of a header name...?

take this simple pseudo example:

public class HeaderTest {
  public final static String MY_HEADER_NAME = "MyHeaderName";

  @Test
  public void test() {  
    Message message = MessageBuilder.withPayload("myPayload").setHeader(MY_HEADER_NAME, "myHeaderValue").build();
    
    // send this over a flow containing an http outbound/inbound gateway pair....
    message = MessagingTemplate.sendAndReceive(message, inputChannel);

    Object resultantHeaderValue = message.getHeaders().get(MY_HEADER_NAME);
    Assert.notNull(resultantHeaderValue); // FAIL, the header name is no longer "MyHeaderName", but is now "myheadername"...!
  }
}

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jan 10, 2011

Oleg Zhurakousky commented

Yes I understand
And what I am saying is that for operating on headers in a case insensitive way for the situations where such headers were transported over HTTP you can use DefaulyHeaderMapper as such:

Message message = MessageBuilder.withPayload("hello").setHeader("foo", "Foo").setHeader("Accept", "text/html").build();
HttpHeaders httpHeaders = new HttpHeaders();
DefaultHttpHeaderMapper headerMapper = new DefaultHttpHeaderMapper();
headerMapper.setOutboundHeaderNames(new String[]{"foo", "HTTP_REQUEST_HEADERS"});
headerMapper.fromHeaders(message.getHeaders(), httpHeaders);
System.out.println("Foo: " + httpHeaders.get("x-FoO"));
System.out.println("Accept: " + httpHeaders.get("aCcEpT"));

and the output:

Foo: [Foo]
Accept: [text/html]

Note that I am completely ignoring case when operating HTTP Headers

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jan 10, 2011

Oleg Zhurakousky commented

Or if you want to completely ignore the case for all MessageHeaders regardless of HTTP then you can simply do this

LinkedCaseInsensitiveMap map = new LinkedCaseInsensitiveMap();
map.putAll(message.getHeaders());
System.out.println("Foo: " + map.get("FoO"));
System.out.println("Accept: " + map.get("aCcEpT"));

The bottom line there are several simple options to accomplish it, but making it a default behavior. . . not yet convinced ;)

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jan 10, 2011

tony kerz commented

in my use case, i may arrive at a downstream flow via an arbitrary transport, JMS, HTTP, MAIL, FTP, etc.

i.e. the transport is supposed to be transparent to the flows prior to and following the transport step(s).

in general, i thought that transparency of upstream and downstream details was one of the fundamentals of the integration programming model.

in order to account for the potential that a message may have crossed HTTP upstream,
i would have to account for case-insensitivity (via LinkedCaseInsensitiveMap or similar) in all interactions with MessageHeaders across the board.

unless i'm missing something, this seems unduly cumbersome...

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jan 10, 2011

Oleg Zhurakousky commented

I am not sure what is so cumbersome in the last solution i provided. You basically saying that you want to be able to look at MH in a case-insensitive way, then what is wrong in using LinkedCaseInsensitiveMap? I understand its an extra line of code, but is this the only concern you have or is there something else?

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jan 10, 2011

tony kerz commented

yes, it's just extra lines of code, but it propagates to all interactions with MessageHeaders.

unless a developer using Spring Integration is absolutely sure (which is kind of impossible) that an HTTP jump will not be added upstream to their flow, it is a trap waiting for all users.

this being the case, i think it is reasonable to expect that this would be accounted for by the framework itself.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jan 10, 2011

Oleg Zhurakousky commented

Tony, don't get me wrong, we will certainly consider that, just wanted to make sure that you are aware of the alternative and that it is not complicated.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jan 10, 2011

Mark Fisher commented

I think the root of this problem is that while HTTP headers are case insensitve, other sources/targets of mapping will be case sensitive. We cannot satisfy both in every case. I do understand the rationale for case-insensitivity in hindsight, but I think that is too much of a breaking change to be introduced in a point release.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Nov 30, 2018

Artem Bilan commented

Moved from Spring Integration since MessageHeaders class is hosted here in Spring Framework.

I'm personally OK to close it as Won't Fix, but I'm open for your opinion on the matter anyway.

Thanks

@spring-projects-issues spring-projects-issues added in: messaging status: waiting-for-triage type: enhancement and removed type: enhancement labels Jan 11, 2019
@rstoyanchev rstoyanchev added status: bulk-closed and removed status: waiting-for-triage labels Jan 11, 2019
@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jan 11, 2019

Bulk closing outdated, unresolved issues. Please, reopen if still relevant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: messaging status: bulk-closed
Projects
None yet
Development

No branches or pull requests

2 participants