1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.apache.commons.httpclient.server;
31
32 import java.io.ByteArrayInputStream;
33 import java.io.ByteArrayOutputStream;
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.io.UnsupportedEncodingException;
37 import java.util.Iterator;
38
39 import org.apache.commons.httpclient.ChunkedInputStream;
40 import org.apache.commons.httpclient.ContentLengthInputStream;
41 import org.apache.commons.httpclient.Header;
42 import org.apache.commons.httpclient.HeaderElement;
43 import org.apache.commons.httpclient.HeaderGroup;
44 import org.apache.commons.httpclient.HttpStatus;
45 import org.apache.commons.httpclient.HttpVersion;
46 import org.apache.commons.httpclient.NameValuePair;
47 import org.apache.commons.httpclient.StatusLine;
48
49 /***
50 * A generic HTTP response.
51 *
52 * @author Christian Kohlschuetter
53 * @author Oleg Kalnichevski
54 */
55 public class SimpleResponse {
56
57 public static final String DEFAULT_CONTENT_CHARSET = "ISO-8859-1";
58
59 private HttpVersion ver = HttpVersion.HTTP_1_1;
60 private int statuscode = HttpStatus.SC_OK;
61 private String phrase = HttpStatus.getStatusText(HttpStatus.SC_OK);
62 private HeaderGroup headers = new HeaderGroup();
63 private InputStream entity = null;
64
65 public SimpleResponse() {
66 super();
67 }
68
69 public SimpleResponse(
70 final StatusLine statusline,
71 final Header[] headers,
72 final InputStream content)
73 throws IOException {
74 super();
75 if (statusline == null) {
76 throw new IllegalArgumentException("Status line may not be null");
77 }
78 setStatusLine(HttpVersion.parse(statusline.getHttpVersion()),
79 statusline.getStatusCode(), statusline.getReasonPhrase());
80 setHeaders(headers);
81 if (content != null) {
82 InputStream in = content;
83 Header contentLength = this.headers.getFirstHeader("Content-Length");
84 Header transferEncoding = this.headers.getFirstHeader("Transfer-Encoding");
85
86 if (transferEncoding != null) {
87 if (transferEncoding.getValue().indexOf("chunked") != -1) {
88 in = new ChunkedInputStream(in);
89 }
90 } else if (contentLength != null) {
91 long len = getContentLength();
92 if (len >= 0) {
93 in = new ContentLengthInputStream(in, len);
94 }
95 }
96 this.entity = in;
97 }
98 }
99
100
101 public void setStatusLine(final HttpVersion ver, int statuscode, final String phrase) {
102 if (ver == null) {
103 throw new IllegalArgumentException("HTTP version may not be null");
104 }
105 if (statuscode <= 0) {
106 throw new IllegalArgumentException("Status code may not be negative or zero");
107 }
108 this.ver = ver;
109 this.statuscode = statuscode;
110 if (phrase != null) {
111 this.phrase = phrase;
112 } else {
113 this.phrase = HttpStatus.getStatusText(statuscode);
114 }
115 }
116
117 public void setStatusLine(final HttpVersion ver, int statuscode) {
118 setStatusLine(ver, statuscode, null);
119 }
120
121 public String getPhrase() {
122 return this.phrase;
123 }
124
125 public int getStatuscode() {
126 return this.statuscode;
127 }
128
129 public HttpVersion getHttpVersion() {
130 return this.ver;
131 }
132
133 public String getStatusLine() {
134 StringBuffer buffer = new StringBuffer();
135 buffer.append(this.ver);
136 buffer.append(' ');
137 buffer.append(this.statuscode);
138 if (this.phrase != null) {
139 buffer.append(' ');
140 buffer.append(this.phrase);
141 }
142 return buffer.toString();
143 }
144
145 public boolean containsHeader(final String name) {
146 return this.headers.containsHeader(name);
147 }
148
149 public Header[] getHeaders() {
150 return this.headers.getAllHeaders();
151 }
152
153 public Header getFirstHeader(final String name) {
154 return this.headers.getFirstHeader(name);
155 }
156
157 public void removeHeaders(final String s) {
158 if (s == null) {
159 return;
160 }
161 Header[] headers = this.headers.getHeaders(s);
162 for (int i = 0; i < headers.length; i++) {
163 this.headers.removeHeader(headers[i]);
164 }
165 }
166
167 public void addHeader(final Header header) {
168 if (header == null) {
169 return;
170 }
171 this.headers.addHeader(header);
172 }
173
174 public void setHeader(final Header header) {
175 if (header == null) {
176 return;
177 }
178 removeHeaders(header.getName());
179 addHeader(header);
180 }
181
182 public void setHeaders(final Header[] headers) {
183 if (headers == null) {
184 return;
185 }
186 this.headers.setHeaders(headers);
187 }
188
189 public Iterator getHeaderIterator() {
190 return this.headers.getIterator();
191 }
192
193 public String getCharset() {
194 String charset = DEFAULT_CONTENT_CHARSET;
195 Header contenttype = this.headers.getFirstHeader("Content-Type");
196 if (contenttype != null) {
197 HeaderElement values[] = contenttype.getElements();
198 if (values.length == 1) {
199 NameValuePair param = values[0].getParameterByName("charset");
200 if (param != null) {
201 charset = param.getValue();
202 }
203 }
204 }
205 return charset;
206 }
207
208 public long getContentLength() {
209 Header contentLength = this.headers.getFirstHeader("Content-Length");
210 if (contentLength != null) {
211 try {
212 return Long.parseLong(contentLength.getValue());
213 } catch (NumberFormatException e) {
214 return -1;
215 }
216 } else {
217 return -1;
218 }
219 }
220
221 public void setBodyString(final String string) {
222 if (string != null) {
223 byte[] raw = null;
224 try {
225 raw = string.getBytes(DEFAULT_CONTENT_CHARSET);
226 } catch (UnsupportedEncodingException e) {
227 raw = string.getBytes();
228 }
229 this.entity = new ByteArrayInputStream(raw);
230 if (!containsHeader("Content-Type")) {
231 setHeader(new Header("Content-Type", "text/plain"));
232 }
233 setHeader(new Header("Content-Length", Long.toString(raw.length)));
234 } else {
235 this.entity = null;
236 }
237 }
238
239 public void setBody(final InputStream instream) {
240 this.entity = instream;
241 }
242
243 public InputStream getBody() {
244 return this.entity;
245 }
246
247 public byte[] getBodyBytes() throws IOException {
248 InputStream in = getBody();
249 if (in != null) {
250 byte[] tmp = new byte[4096];
251 int bytesRead = 0;
252 ByteArrayOutputStream buffer = new ByteArrayOutputStream(1024);
253 while ((bytesRead = in.read(tmp)) != -1) {
254 buffer.write(tmp, 0, bytesRead);
255 }
256 return buffer.toByteArray();
257 } else {
258 return null;
259 }
260 }
261
262 public String getBodyString() throws IOException {
263 byte[] raw = getBodyBytes();
264 if (raw != null) {
265 return new String(raw, getCharset());
266 } else {
267 return null;
268 }
269 }
270 }