package com.jpexs.proxy; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.io.StringBufferInputStream; import java.io.SequenceInputStream; import java.util.Hashtable; import java.util.StringTokenizer; public class Reply extends Message { InputStream in = null; int statusCode = -1; public Reply() { } public Reply(InputStream in) { setContent(in); } public void setContent(InputStream in) { this.in = in; } public InputStream getContent() { return in; } void read() throws IOException { if (in != null) { read(in); } } void read(InputStream in) throws IOException { statusLine = readLine(in); if (statusLine == null || statusLine.length() == 0) { throw new IOException("Missing HTTP status line"); } /* Look for HTTP/0.9 */ if (!statusLine.startsWith("HTTP")) { /* Put back the line */ if (this.in != null) { String putback = new String(statusLine + "\n"); this.in = new SequenceInputStream(new StringBufferInputStream(putback), in); } /* Fake a status line and upgrade to HTTP/1.0 */ statusLine = "HTTP/1.0 200 OK"; return; } readHeaders(in); int code = getStatusCode(); /* RFC 2068: 204 and 304 MUST NOT contain a message body. */ switch (code) { case 204: /* No Content */ case 304: /* Not Modified */ /* Ignore the message body if it exists */ if (containsHeaderField("Content-length")) { int contentLength = 0; try { contentLength = Integer.parseInt(getHeaderField("Content-length")); } catch (NumberFormatException e) { } int n; byte[] buffer = new byte[8192]; while ((n = in.read(buffer, 0, buffer.length)) > 0) { /* ignore */ } removeHeaderField("Content-length"); } break; } } public boolean hasContent() { switch (getStatusCode()) { case 204: case 304: return false; default: return true; } } public String getProtocol() { StringTokenizer st = new StringTokenizer(statusLine); String protocol = (String) st.nextToken(); return protocol; } public int getStatusCode() { if (statusCode == -1) { StringTokenizer st = new StringTokenizer(statusLine); String protocol = (String) st.nextToken(); String status = (String) st.nextToken(); try { statusCode = Integer.parseInt(status); } catch (NumberFormatException e) { System.out.println("Malformed or missing status code"); statusCode = 0; } } return statusCode; } private Hashtable headerParser(String header) { Hashtable table = new Hashtable(); String type = getHeaderField(header); if (type == null) { return table; } StringTokenizer st = new StringTokenizer(type, ";"); int count = 0; while (st.hasMoreTokens()) { String token = st.nextToken(); token = token.trim(); String name; String value; int i = token.indexOf('='); if (i != -1) { name = token.substring(0, i); value = token.substring(i + 1); } else { name = token; value = ""; } if (count == 0) { table.put(header, name); } else { table.put(name, value); } count++; } return table; } public String getContentType() { Hashtable table = headerParser("Content-type"); return (String) table.get("Content-type"); } public String getBoundary() { Hashtable table = headerParser("Content-type"); return (String) table.get("boundary"); } public String getTransferEncoding() { Hashtable table = headerParser("Transfer-Encoding"); return (String) table.get("Transfer-Encoding"); } public int getChunkSize(InputStream in) throws IOException { String line = readLine(in); line = line.trim(); /* apache can have trailing spaces */ int size = -1; try { size = Integer.valueOf(line, 16).intValue(); } catch (NumberFormatException e) { System.out.println(e); } return size; } public void getChunkedFooter(InputStream in) throws IOException { for (;;) { String line = readLine(in); if (line == null) { break; } int i = line.indexOf(':'); if (i == -1) { break; } } } public void setStatusLine(String line) { this.statusLine = line; } public static Reply createRedirect(String url) { Reply r = new Reply(); r.setStatusLine("HTTP/1.0 302 Moved Temporarily"); r.setHeaderField("Location", url); return r; } }