package com.jpexs.proxy; import java.util.Hashtable; import java.util.Enumeration; import java.util.Vector; import java.io.*; public abstract class Message { /** * Hashtable used to store message headers. */ private Hashtable headers = new Hashtable(33); /** * */ String statusLine = null; public String readLine(InputStream in) throws IOException { char[] buf = new char[128]; int offset = 0; int ch; for (;;) { ch = in.read(); if (ch == -1 || ch == '\n') { break; } else if (ch == '\r') { int tmpch = in.read(); if (tmpch != '\n') { if (!(in instanceof PushbackInputStream)) { in = new PushbackInputStream(in); } ((PushbackInputStream) in).unread(tmpch); } break; } else { if (offset == buf.length) { char[] tmpbuf = buf; buf = new char[tmpbuf.length * 2]; System.arraycopy(tmpbuf, 0, buf, 0, offset); } buf[offset++] = (char) ch; } } return String.copyValueOf(buf, 0, offset); } /** * Read headers and store them in the hashtable. */ void readHeaders(InputStream in) throws IOException { int i; Key key = null; for (;;) { String s = readLine(in); if (s == null) { break; } i = s.indexOf(':'); if (i == -1) { /* end of header */ if (s.length() == 0) { break; } /* multi-line headers */ else if (key != null && (s.startsWith(" ") || s.startsWith("\t"))) { int index = getHeaderValueCount(key.toString()); index--; Vector v = (Vector) headers.get(key); v.setElementAt(v.elementAt(index) + "\n" + s, index); } } else { key = new Key(s.substring(0, i)); Vector v; if (headers.containsKey(key)) { v = (Vector) headers.get(key); } else { v = new Vector(); } v.addElement(s.substring(i + 1).trim()); headers.put(key, v); } } } public int headerCount() { return headers.size(); } /** * Set the Status line. */ public void setStatusLine(String l) { statusLine = l; } public int getHeaderValueCount(String name) { Vector v = (Vector) headers.get(new Key(name)); return v.size(); } public String getHeaderField(String name) { return getHeaderField(name, 0); } public String getHeaderField(String name, int index) { Vector v = (Vector) headers.get(new Key(name)); if (v == null) { return null; } return (String) v.elementAt(index); } public void setHeaderField(String name, String value) { setHeaderField(name, value, 0); } public void setHeaderField(String name, String value, int index) { Vector v; Key key = new Key(name); if (headers.containsKey(key)) { v = (Vector) headers.get(key); } else { v = new Vector(); if (index == 0) { v.addElement(""); } headers.put(key, v); } v.setElementAt(value, index); } public void setHeaderField(String name, int value) { setHeaderField(name, value, 0); } public void setHeaderField(String name, int value, int index) { setHeaderField(name, new Integer(value).toString(), index); } /** * Set all header fields with the give name to the specified value. */ public void setHeaderFields(String name, String value) { Vector v; Key key = new Key(name); v = (Vector) headers.get(key); if (v != null) { for (int i = 0; i < v.size(); i++) { v.setElementAt(value, i); } } } public void appendHeaderField(String name, String value) { appendHeaderField(name, value, 0); } public void appendHeaderField(String name, String value, int index) { setHeaderField(name, getHeaderField(name, index) + value, index); } public void removeHeaderField(String name) { headers.remove(new Key(name)); } /** * Return whether or not a header exists. * * @param name header name */ public boolean containsHeaderField(String name) { return headers.containsKey(new Key(name)); } /** * @return an Enumeration of Strings */ public Enumeration getHeaders() { Vector v = new Vector(); for (Enumeration e = headers.keys(); e.hasMoreElements();) { v.addElement(e.nextElement().toString()); } return v.elements(); } private final static byte[] COLON_SPACE = ": ".getBytes(); private final static byte[] CRLF = "\r\n".getBytes(); private ByteArray toByteArray(byte[] sep) { ByteArray buf = new ByteArray(); Key key; String value; Vector v; int i = 0; buf.append(statusLine); buf.append(sep); for (Enumeration e = headers.keys(); e.hasMoreElements();) { key = (Key) e.nextElement(); v = (Vector) headers.get(key); for (i = 0; i < v.size(); i++) { buf.append(key.toString()); buf.append(COLON_SPACE); buf.append(v.elementAt(i).toString()); buf.append(sep); } } buf.append(sep); return buf; } private ByteArray toByteArray() { return toByteArray(CRLF); } private ByteArray toByteArray(String sep) { return toByteArray(sep.getBytes()); } public String toString() { return toByteArray().toString(); } public String toString(String sep) { return toByteArray(sep).toString(); } public void write(OutputStream out) throws IOException { toByteArray().writeTo(out); out.flush(); } }