151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 2545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*- 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * news stream opener 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.net.www; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.*; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Collections; 34545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thiererimport java.util.*; 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** An RFC 844 or MIME message header. Includes methods 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for parsing headers from incoming streams, fetching 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski values, setting values, and printing headers. 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Key values of null are legal: they indicate lines in 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski the header that don't have a valid key, but do have 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski a value (this isn't legal according to the standard, 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski but lines like this are everywhere). */ 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass MessageHeader { 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String keys[]; 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String values[]; 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int nkeys; 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public MessageHeader () { 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski grow(); 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public MessageHeader (InputStream is) throws java.io.IOException { 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parseHeader(is); 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 58545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer * Returns list of header names in a comma separated list 59545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer */ 60545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer public synchronized String getHeaderNamesInList() { 61545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer StringJoiner joiner = new StringJoiner(","); 62545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer for (int i=0; i<nkeys; i++) { 63545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer joiner.add(keys[i]); 64545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer } 65545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer return joiner.toString(); 66545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer } 67545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer 68545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer /** 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reset a message header (all key/values removed) 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void reset() { 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keys = null; 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski values = null; 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nkeys = 0; 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski grow(); 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Find the value that corresponds to this key. 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * It finds only the first occurrence of the key. 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param k the key to find. 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return null if not found. 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized String findValue(String k) { 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (k == null) { 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = nkeys; --i >= 0;) 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (keys[i] == null) 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return values[i]; 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = nkeys; --i >= 0;) { 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (k.equalsIgnoreCase(keys[i])) 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return values[i]; 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // return the location of the key 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized int getKey(String k) { 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = nkeys; --i >= 0;) 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((keys[i] == k) || 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (k != null && k.equalsIgnoreCase(keys[i]))) 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return i; 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized String getKey(int n) { 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n < 0 || n >= nkeys) return null; 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return keys[n]; 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized String getValue(int n) { 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n < 0 || n >= nkeys) return null; 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return values[n]; 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Deprecated: Use multiValueIterator() instead. 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Find the next value that corresponds to this key. 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * It finds the first value that follows v. To iterate 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * over all the values of a key use: 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre> 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for(String v=h.findValue(k); v!=null; v=h.findNextValue(k, v)) { 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ... 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * } 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre> 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized String findNextValue(String k, String v) { 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean foundV = false; 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (k == null) { 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = nkeys; --i >= 0;) 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (keys[i] == null) 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (foundV) 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return values[i]; 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if (values[i] == v) 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski foundV = true; 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = nkeys; --i >= 0;) 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (k.equalsIgnoreCase(keys[i])) 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (foundV) 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return values[i]; 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if (values[i] == v) 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski foundV = true; 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Removes bare Negotiate and Kerberos headers when an "NTLM ..." 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * appears. All Performed on headers with key being k. 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return true if there is a change 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean filterNTLMResponses(String k) { 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean found = false; 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i=0; i<nkeys; i++) { 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (k.equalsIgnoreCase(keys[i]) 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski && values[i] != null && values[i].length() > 5 156545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer && values[i].substring(0, 5).equalsIgnoreCase("NTLM ")) { 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski found = true; 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (found) { 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int j = 0; 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i=0; i<nkeys; i++) { 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (k.equalsIgnoreCase(keys[i]) && ( 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "Negotiate".equalsIgnoreCase(values[i]) || 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "Kerberos".equalsIgnoreCase(values[i]))) { 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (i != j) { 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keys[j] = keys[i]; 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski values[j] = values[i]; 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski j++; 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (j != nkeys) { 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nkeys = j; 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski class HeaderIterator implements Iterator<String> { 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int index = 0; 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int next = -1; 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String key; 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean haveNext = false; 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object lock; 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public HeaderIterator (String k, Object lock) { 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski key = k; 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.lock = lock; 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean hasNext () { 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lock) { 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (haveNext) { 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (index < nkeys) { 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (key.equalsIgnoreCase (keys[index])) { 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski haveNext = true; 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski next = index++; 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski index ++; 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String next() { 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lock) { 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (haveNext) { 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski haveNext = false; 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return values [next]; 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (hasNext()) { 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return next(); 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NoSuchElementException ("No more elements"); 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void remove () { 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UnsupportedOperationException ("remove not allowed"); 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * return an Iterator that returns all values of a particular 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * key in sequence 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Iterator<String> multiValueIterator (String k) { 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new HeaderIterator (k, this); 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized Map<String, List<String>> getHeaders() { 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getHeaders(null); 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized Map<String, List<String>> getHeaders(String[] excludeList) { 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return filterAndAddHeaders(excludeList, null); 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 244545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer public synchronized Map<String, List<String>> filterAndAddHeaders( 245545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer String[] excludeList, Map<String, List<String>> include) { 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean skipIt = false; 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Map<String, List<String>> m = new HashMap<String, List<String>>(); 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = nkeys; --i >= 0;) { 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (excludeList != null) { 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // check if the key is in the excludeList. 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if so, don't include it in the Map. 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int j = 0; j < excludeList.length; j++) { 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((excludeList[j] != null) && 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (excludeList[j].equalsIgnoreCase(keys[i]))) { 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski skipIt = true; 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!skipIt) { 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<String> l = m.get(keys[i]); 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (l == null) { 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski l = new ArrayList<String>(); 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski m.put(keys[i], l); 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski l.add(values[i]); 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // reset the flag 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski skipIt = false; 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (include != null) { 274545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer for (Map.Entry<String,List<String>> entry: include.entrySet()) { 275545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer List<String> l = m.get(entry.getKey()); 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (l == null) { 277545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer l = new ArrayList<String>(); 278545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer m.put(entry.getKey(), l); 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 280545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer l.addAll(entry.getValue()); 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (String key : m.keySet()) { 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski m.put(key, Collections.unmodifiableList(m.get(key))); 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Collections.unmodifiableMap(m); 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Prints the key-value pairs represented by this 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski header. Also prints the RFC required blank line 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski at the end. Omits pairs with a null key. */ 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void print(PrintStream p) { 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < nkeys; i++) 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (keys[i] != null) { 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski p.print(keys[i] + 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (values[i] != null ? ": "+values[i]: "") + "\r\n"); 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski p.print("\r\n"); 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski p.flush(); 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Adds a key value pair to the end of the 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski header. Duplicates are allowed */ 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void add(String k, String v) { 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski grow(); 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keys[nkeys] = k; 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski values[nkeys] = v; 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nkeys++; 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Prepends a key value pair to the beginning of the 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski header. Duplicates are allowed */ 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void prepend(String k, String v) { 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski grow(); 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = nkeys; i > 0; i--) { 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keys[i] = keys[i-1]; 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski values[i] = values[i-1]; 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keys[0] = k; 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski values[0] = v; 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nkeys++; 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Overwrite the previous key/val pair at location 'i' 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * with the new k/v. If the index didn't exist before 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the key/val is simply tacked onto the end. 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void set(int i, String k, String v) { 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski grow(); 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (i < 0) { 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (i >= nkeys) { 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski add(k, v); 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keys[i] = k; 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski values[i] = v; 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** grow the key/value arrays as needed */ 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void grow() { 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (keys == null || nkeys >= keys.length) { 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[] nk = new String[nkeys + 4]; 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[] nv = new String[nkeys + 4]; 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (keys != null) 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.arraycopy(keys, 0, nk, 0, nkeys); 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (values != null) 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.arraycopy(values, 0, nv, 0, nkeys); 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keys = nk; 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski values = nv; 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Remove the key from the header. If there are multiple values under 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the same key, they are all removed. 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Nothing is done if the key doesn't exist. 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * After a remove, the other pairs' order are not changed. 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param k the key to remove 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void remove(String k) { 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if(k == null) { 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < nkeys; i++) { 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (keys[i] == null && i < nkeys) { 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for(int j=i; j<nkeys-1; j++) { 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keys[j] = keys[j+1]; 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski values[j] = values[j+1]; 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nkeys--; 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < nkeys; i++) { 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (k.equalsIgnoreCase(keys[i]) && i < nkeys) { 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for(int j=i; j<nkeys-1; j++) { 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keys[j] = keys[j+1]; 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski values[j] = values[j+1]; 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nkeys--; 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Sets the value of a key. If the key already 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski exists in the header, it's value will be 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski changed. Otherwise a new key/value pair will 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski be added to the end of the header. */ 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void set(String k, String v) { 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = nkeys; --i >= 0;) 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (k.equalsIgnoreCase(keys[i])) { 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski values[i] = v; 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski add(k, v); 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Set's the value of a key only if there is no 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * key with that value already. 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void setIfNotSet(String k, String v) { 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (findValue(k) == null) { 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski add(k, v); 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Convert a message-id string to canonical form (strips off 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski leading and trailing <>s) */ 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static String canonicalID(String id) { 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (id == null) 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ""; 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int st = 0; 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int len = id.length(); 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean substr = false; 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int c; 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (st < len && ((c = id.charAt(st)) == '<' || 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c <= ' ')) { 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski st++; 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski substr = true; 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (st < len && ((c = id.charAt(len - 1)) == '>' || 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c <= ' ')) { 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski len--; 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski substr = true; 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return substr ? id.substring(st, len) : id; 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Parse a MIME header from an input stream. */ 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void parseHeader(InputStream is) throws java.io.IOException { 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (this) { 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nkeys = 0; 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mergeHeader(is); 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Parse and merge a MIME header from an input stream. */ 444545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer @SuppressWarnings("fallthrough") 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void mergeHeader(InputStream is) throws java.io.IOException { 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (is == null) 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char s[] = new char[10]; 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int firstc = is.read(); 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (firstc != '\n' && firstc != '\r' && firstc >= 0) { 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int len = 0; 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int keyend = -1; 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int c; 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean inKey = firstc > ' '; 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s[len++] = (char) firstc; 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parseloop:{ 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while ((c = is.read()) >= 0) { 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (c) { 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case ':': 46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (inKey && len > 0) 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keyend = len; 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski inKey = false; 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '\t': 46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = ' '; 466545619b8f363fbf58881e08f6a0a1008361eabf3Tobias Thierer /*fall through*/ 46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case ' ': 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski inKey = false; 46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '\r': 47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '\n': 47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski firstc = is.read(); 47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (c == '\r' && firstc == '\n') { 47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski firstc = is.read(); 47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (firstc == '\r') 47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski firstc = is.read(); 47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (firstc == '\n' || firstc == '\r' || firstc > ' ') 47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parseloop; 48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* continuation */ 48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = ' '; 48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (len >= s.length) { 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char ns[] = new char[s.length * 2]; 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.arraycopy(s, 0, ns, 0, len); 48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s = ns; 48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s[len++] = (char) c; 49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski firstc = -1; 49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (len > 0 && s[len - 1] <= ' ') 49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski len--; 49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String k; 49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (keyend <= 0) { 49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski k = null; 49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keyend = 0; 49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski k = String.copyValueOf(s, 0, keyend); 50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (keyend < len && s[keyend] == ':') 50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keyend++; 50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (keyend < len && s[keyend] <= ' ') 50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski keyend++; 50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String v; 50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (keyend >= len) 50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski v = new String(); 50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski v = String.copyValueOf(s, keyend, len - keyend); 51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski add(k, v); 51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized String toString() { 51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String result = super.toString() + nkeys + " pairs: "; 51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < keys.length && i < nkeys; i++) { 51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski result += "{"+keys[i]+": "+values[i]+"}"; 51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return result; 52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 523