- Moved the dtstart,dtend fixing to icalUtilities so it can be called from updateFrom...
[jgroupdav.git] / src / main / java / net / bionicmessage / groupdav / HTTPInputStream.java
blob85c310dd347043bca31a62d1c6123b8ce2a3028d
1 /* HTTPInputStream.java created 19th October 2008
2 * Copyright (c) 2007-2008 Mathew McBride / "BionicMessage.net"
3 * Permission is hereby granted, free of charge, to any person obtaining a
4 * copy of this software and associated documentation files (the "Software"),
5 * to deal in the Software without restriction, including without limitation
6 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 * and/or sell copies of the Software, and to permit persons to whom the
8 * Software is furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
15 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18 * IN THE SOFTWARE.
21 package net.bionicmessage.groupdav;
23 import java.io.BufferedInputStream;
24 import java.io.IOException;
25 import java.net.Socket;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
30 /**
31 * A HTTP Input Stream that supports chunked-transfer-encoding
32 * and hides HTTP headers from the reader.
33 * @author matt
35 public class HTTPInputStream extends BufferedInputStream {
37 protected Socket sock;
38 protected HashMap headers;
39 protected List<HTTPCookie> setCookies;
40 protected boolean chunked = false;
41 protected boolean headersRead = false;
42 protected int headerLinesRead = 0;
43 protected int returnedStatus = 0;
44 protected String returnedReason = "";
45 protected boolean outOfChunks = false;
47 public HTTPInputStream(Socket parent) throws IOException {
48 super(parent.getInputStream());
49 sock = parent;
50 headers = new HashMap(10);
51 setCookies = new ArrayList<HTTPCookie>(10);
54 @Override
55 public synchronized int read() throws IOException {
56 byte[] d = new byte[1];
57 this.read(d,0,1);
58 return (int)d[0];
61 @Override
62 public int read(byte[] b) throws IOException {
63 return this.read(b,0,b.length);
66 @Override
67 public synchronized int read(byte[] b, int off, int len) throws IOException {
68 int bytesAck = 0;
69 String str = null;
70 // Intercept the read request if we don't have headers.
71 if (!headersRead) {
72 while ((str = readLineASCII()) != null) {
73 if (headerLinesRead == 0) {
74 returnedStatus = Integer.parseInt(str.substring(10, 12));
75 returnedReason = str.substring(13);
76 headerLinesRead++;
77 bytesAck = bytesAck + str.length();
78 } else if (str.contains(":")) {
79 String[] kv = str.split(":");
80 String name = kv[0].toLowerCase().trim();
81 if (name.contains("set-cookie")) {
82 HTTPCookie cookie = new HTTPCookie(kv[1].trim());
83 setCookies.add(cookie);
84 } else {
85 headers.put(name, kv[1].trim());
87 headerLinesRead++;
88 bytesAck = bytesAck + str.length();
89 } else {
90 headersRead = true;
91 break;
94 this.reset();
96 if ("chunked".equals(headers.get("transfer-encoding"))) {
97 chunked = true;
98 // read one line for size, then read n bytes
99 String chunkheader = readLineASCII();
100 chunkheader = chunkheader.trim();
101 int size = Integer.parseInt(chunkheader, 16)+2; // add two for CRLF
102 if (size != 0 && (size-2) != 0) { // stupid hack to see if s-2, should be fixed
103 byte[] chunk = new byte[size];
104 do {
106 } while (size > super.available());
107 int read = super.read(chunk,off,size);
108 //if (size != read) {
109 // System.err.println("OOPS! Read "+read + " out of "+size);
111 System.arraycopy(chunk, 0, b, off, size-2);
112 return (read-2);
114 outOfChunks = true;
115 return -1;
117 return super.read(b, off, len);
120 protected String readLineASCII() throws IOException {
121 int b;
122 int read = 0;
123 byte[] buf = new byte[65535];
124 while ((b = super.read()) != -1) {
125 read++;
126 buf[read] = (byte) b;
127 if (b == '\r') {
128 this.mark(1);
129 b = super.read();
130 if (b == '\n') {
131 this.mark(1);
132 break;
133 } else {
134 this.reset();
136 } else if (b == '\n') {
137 break;
140 return new String(buf, 0, read);
143 public HashMap getHeaders() {
144 return headers;
146 public List<HTTPCookie> getCookies() {
147 return setCookies;