Help please! I'm struggling with: HttpUrlConnection converts request headers to lowercase HttpUrlConnection.addRequestProperty overrides existing properties https://issues.apache.org/jira/browse/HARMONY-6452
The JIRA is slightly confusing because it contains two issues. However, they are rather closely linked and this confusion is trivial in comparison to the confusion I now face trying to figure out what behaviour to implement to be compatible with the reference implementation. The reference implementation seems rather inconsistent so I am wonder if it is really worth trying to match its behaviour rather than merely meeting the spec with a simpler implementation. For example, my testing suggests that the reference implementation treats keys provided to the setRequestProperty method case-insensitively and additionally preserves the case of the first instance of a particular key string. So if you do: URLConnection conn = (URLConnection)(new URL("http://example.org/").openConnection()); conn.setRequestProperty("KEY", "upper"); conn.setRequestProperty("key", "lower"); System.out.println("KEY=" + conn.getRequestProperty("KEY")); System.out.println("key=" + conn.getRequestProperty("key")); System.out.println("properties=" + conn.getRequestProperties()); then the RI outputs: KEY=lower key=lower properties={KEY=[lower]} and if you do: URLConnection conn = (URLConnection)(new URL("http://example.org/").openConnection()); conn.setRequestProperty("key", "lower"); conn.setRequestProperty("KEY", "upper"); System.out.println("KEY=" + conn.getRequestProperty("KEY")); System.out.println("key=" + conn.getRequestProperty("key")); System.out.println("properties=" + conn.getRequestProperties()); then the RI outputs: KEY=upper key=upper properties={key=[upper]} This appears to be consistent - albeit over-complicated IMHO. But my testing also shows that the addRequestProperty (which appends the value to the value list associated with the key) does not treat keys case-insensitively so if you do: URLConnection conn = (URLConnection)(new URL("http://example.org/").openConnection()); conn.setRequestProperty("KEY", "upper"); conn.addRequestProperty("key", "lower"); System.out.println("KEY=" + conn.getRequestProperty("KEY")); System.out.println("key=" + conn.getRequestProperty("key")); System.out.println("properties=" + conn.getRequestProperties()); you get: KEY=lower key=lower properties={KEY=[upper], key=[lower]} where as I'd have expected: properties={KEY=[lower,upper]} (since that is what you get if you do set* and add* with "KEY" in upper case for both calls). Personally, I struggle to see any consistency in the RI and suspect that we'd be better of just treating keys case-sensitively in all cases. This would at least have the virtue of being self-consistent and more predictable than the current implementation. I tried writing test cases to map out the behaviour of the RI but just when I thought I'd figured it out I'd write another test and find that it didn't behave as I'd have expected. What do people think? By my reading, treating keys case-sensitively in all cases would be consistent with the spec but will this cause problems for users? Am I missing something and in fact the RI consistent? I think since the same class is used to implement response headers, we may have to "be liberal"[0] and treat keys case-insensitively for the getRequestProperty() method or at least lookup case-sensitively thent also look them up case-insensitively before returning null. Regards, Mark. [0] "Be liberal in what you accept, and conservative in what you send." - Jon Postel