HeadersParser { public static Map<String, List<String>> parseHeaders(final InputStream headersSection, final String charset) { Map<String, List<String>> headers = new HashMap<String, List<String>>(); String name = null; StringBuffer value = null; for (; ;) { String line = readLine(headersSection, charset); if ((line == null) || (line.trim().length() < 1)) { break; } if ((line.charAt(0) == ' ') || (line.charAt(0) == '\t')) { if (value != null) { value.append(' '); value.append(line.trim()); } } else { if (name != null) { addHeader(headers, name, value.toString()); } int colon = line.indexOf(":"); if (colon < 0) { throw new IllegalStateException("Unable to parse header: " + line); } name = line.substring(0, colon).trim(); value = new StringBuffer(line.substring(colon + 1).trim()); } } if (name != null) { addHeader(headers, name, value.toString()); } return headers; } private  HeadersParser(); static Map<String, List<String>> parseHeaders(final InputStream headersSection, final String charset); static final String EMPTY_STRING; }
@Test public void testReadHeaders_folded() throws Exception { InputStream headersSection = new ByteArrayInputStream("headerNameA: headerValueA\r\nheaderNameB: headerValueB\r\n part of b".getBytes(CHARACTER_SET)); Map<String, List<String>> headers = HeadersParser.parseHeaders(headersSection, CHARACTER_SET); assertNotNull(headers); assertNotNull(headers); assertEquals(2, headers.size()); assertEquals(singletonList("headerValueA"), headers.get("headerNameA".toLowerCase())); assertEquals(singletonList("headerValueB part of b"), headers.get("headerNameB".toLowerCase())); headersSection = new ByteArrayInputStream("headerNameA: headerValueA\r\nheaderNameB: headerValueB\r\n\t\t\tpart of b".getBytes(CHARACTER_SET)); headers = HeadersParser.parseHeaders(headersSection, CHARACTER_SET); assertNotNull(headers); assertNotNull(headers); assertEquals(2, headers.size()); assertEquals(singletonList("headerValueA"), headers.get("headerNameA".toLowerCase())); assertEquals(singletonList("headerValueB part of b"), headers.get("headerNameB".toLowerCase())); }
@Test public void testReadHeaders() throws Exception { InputStream headersSection = new ByteArrayInputStream("headerNameA: headerValueA\r\nheaderNameB: headerValueB\r\n\r\nmore stuff here".getBytes(CHARACTER_SET)); Map<String, List<String>> headers = HeadersParser.parseHeaders(headersSection, CHARACTER_SET); assertNotNull(headers); assertEquals(2, headers.size()); assertEquals(singletonList("headerValueA"), headers.get("headerNameA".toLowerCase())); assertEquals(singletonList("headerValueB"), headers.get("headerNameB".toLowerCase())); }
@Test public void testReadHeaders_malformed() throws Exception { InputStream headersSection = new ByteArrayInputStream("headerNameA: headerValueA\r\nheaderNameB headerValueB\r\n\r\nmore stuff here".getBytes(CHARACTER_SET)); Exception expected = null; try { Map<String, List<String>> headers = HeadersParser.parseHeaders(headersSection, CHARACTER_SET); } catch (Exception e) { expected = e; } assertNotNull(expected); assertTrue(expected instanceof IllegalStateException); }
@Test public void testReadHeaders_lenientTerminator() throws Exception { InputStream headersSection = new ByteArrayInputStream("headerNameA: headerValueA\r\nheaderNameB: headerValueB\r\n\r\r\nmore stuff here".getBytes(CHARACTER_SET)); Map<String, List<String>> headers = HeadersParser.parseHeaders(headersSection, CHARACTER_SET); assertNotNull(headers); assertNotNull(headers); assertEquals(2, headers.size()); assertEquals(singletonList("headerValueA"), headers.get("headerNameA".toLowerCase())); assertEquals(singletonList("headerValueB"), headers.get("headerNameB".toLowerCase())); headersSection = new ByteArrayInputStream("headerNameA: headerValueA\r\nheaderNameB: headerValueB\r\n \r\nmore stuff here".getBytes(CHARACTER_SET)); headers = HeadersParser.parseHeaders(headersSection, CHARACTER_SET); assertNotNull(headers); assertNotNull(headers); assertEquals(2, headers.size()); assertEquals(singletonList("headerValueA"), headers.get("headerNameA".toLowerCase())); assertEquals(singletonList("headerValueB"), headers.get("headerNameB".toLowerCase())); }