001: /*
002: * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/test/org/apache/commons/httpclient/server/SimpleHttpServerConnection.java,v 1.21 2004/12/11 22:35:26 olegk Exp $
003: * $Revision: 480424 $
004: * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
005: *
006: * ====================================================================
007: *
008: * Licensed to the Apache Software Foundation (ASF) under one or more
009: * contributor license agreements. See the NOTICE file distributed with
010: * this work for additional information regarding copyright ownership.
011: * The ASF licenses this file to You under the Apache License, Version 2.0
012: * (the "License"); you may not use this file except in compliance with
013: * the License. You may obtain a copy of the License at
014: *
015: * http://www.apache.org/licenses/LICENSE-2.0
016: *
017: * Unless required by applicable law or agreed to in writing, software
018: * distributed under the License is distributed on an "AS IS" BASIS,
019: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
020: * See the License for the specific language governing permissions and
021: * limitations under the License.
022: * ====================================================================
023: *
024: * This software consists of voluntary contributions made by many
025: * individuals on behalf of the Apache Software Foundation. For more
026: * information on the Apache Software Foundation, please see
027: * <http://www.apache.org/>.
028: *
029: */
030:
031: package org.apache.commons.httpclient.server;
032:
033: import java.io.IOException;
034: import java.io.InputStream;
035: import java.io.OutputStream;
036: import java.io.UnsupportedEncodingException;
037: import java.net.Socket;
038: import java.net.SocketException;
039: import java.util.Iterator;
040:
041: import org.apache.commons.httpclient.ChunkedOutputStream;
042: import org.apache.commons.httpclient.Header;
043: import org.apache.commons.httpclient.HttpParser;
044: import org.apache.commons.httpclient.StatusLine;
045:
046: /**
047: * A connection to the SimpleHttpServer.
048: *
049: * @author Christian Kohlschuetter
050: * @author Oleg Kalnichevski
051: */
052: public class SimpleHttpServerConnection {
053:
054: private static final String HTTP_ELEMENT_CHARSET = "US-ASCII";
055:
056: private Socket socket = null;
057: private InputStream in = null;
058: private OutputStream out = null;
059: private boolean keepAlive = false;
060:
061: public SimpleHttpServerConnection(final Socket socket)
062: throws IOException {
063: super ();
064: if (socket == null) {
065: throw new IllegalArgumentException("Socket may not be null");
066: }
067: this .socket = socket;
068: this .socket.setSoTimeout(500);
069: this .in = socket.getInputStream();
070: this .out = socket.getOutputStream();
071: }
072:
073: public synchronized void close() {
074: try {
075: if (socket != null) {
076: in.close();
077: out.close();
078: socket.close();
079: socket = null;
080: }
081: } catch (IOException e) {
082: }
083: }
084:
085: public synchronized boolean isOpen() {
086: return this .socket != null;
087: }
088:
089: public void setKeepAlive(boolean b) {
090: this .keepAlive = b;
091: }
092:
093: public boolean isKeepAlive() {
094: return this .keepAlive;
095: }
096:
097: public InputStream getInputStream() {
098: return this .in;
099: }
100:
101: public OutputStream getOutputStream() {
102: return this .out;
103: }
104:
105: /**
106: * Returns the ResponseWriter used to write the output to the socket.
107: *
108: * @return This connection's ResponseWriter
109: */
110: public ResponseWriter getWriter()
111: throws UnsupportedEncodingException {
112: return new ResponseWriter(out);
113: }
114:
115: public SimpleRequest readRequest() throws IOException {
116: try {
117: String line = null;
118: do {
119: line = HttpParser.readLine(in, HTTP_ELEMENT_CHARSET);
120: } while (line != null && line.length() == 0);
121:
122: if (line == null) {
123: setKeepAlive(false);
124: return null;
125: }
126: SimpleRequest request = new SimpleRequest(RequestLine
127: .parseLine(line), HttpParser.parseHeaders(this .in,
128: HTTP_ELEMENT_CHARSET), this .in);
129: return request;
130: } catch (IOException e) {
131: close();
132: throw e;
133: }
134: }
135:
136: public SimpleResponse readResponse() throws IOException {
137: try {
138: String line = null;
139: do {
140: line = HttpParser.readLine(in, HTTP_ELEMENT_CHARSET);
141: } while (line != null && line.length() == 0);
142:
143: if (line == null) {
144: setKeepAlive(false);
145: return null;
146: }
147: SimpleResponse response = new SimpleResponse(
148: new StatusLine(line), HttpParser.parseHeaders(
149: this .in, HTTP_ELEMENT_CHARSET), this .in);
150: return response;
151: } catch (IOException e) {
152: close();
153: throw e;
154: }
155: }
156:
157: public void writeRequest(final SimpleRequest request)
158: throws IOException {
159: if (request == null) {
160: return;
161: }
162: ResponseWriter writer = new ResponseWriter(this .out,
163: HTTP_ELEMENT_CHARSET);
164: writer.println(request.getRequestLine().toString());
165: Iterator item = request.getHeaderIterator();
166: while (item.hasNext()) {
167: Header header = (Header) item.next();
168: writer.print(header.toExternalForm());
169: }
170: writer.println();
171: writer.flush();
172:
173: OutputStream outsream = this .out;
174: InputStream content = request.getBody();
175: if (content != null) {
176:
177: Header transferenc = request
178: .getFirstHeader("Transfer-Encoding");
179: if (transferenc != null) {
180: request.removeHeaders("Content-Length");
181: if (transferenc.getValue().indexOf("chunked") != -1) {
182: outsream = new ChunkedOutputStream(outsream);
183: }
184: }
185: byte[] tmp = new byte[4096];
186: int i = 0;
187: while ((i = content.read(tmp)) >= 0) {
188: outsream.write(tmp, 0, i);
189: }
190: if (outsream instanceof ChunkedOutputStream) {
191: ((ChunkedOutputStream) outsream).finish();
192: }
193: }
194: outsream.flush();
195: }
196:
197: public void writeResponse(final SimpleResponse response)
198: throws IOException {
199: if (response == null) {
200: return;
201: }
202: ResponseWriter writer = new ResponseWriter(this .out,
203: HTTP_ELEMENT_CHARSET);
204: writer.println(response.getStatusLine());
205: Iterator item = response.getHeaderIterator();
206: while (item.hasNext()) {
207: Header header = (Header) item.next();
208: writer.print(header.toExternalForm());
209: }
210: writer.println();
211: writer.flush();
212:
213: OutputStream outsream = this .out;
214: InputStream content = response.getBody();
215: if (content != null) {
216:
217: Header transferenc = response
218: .getFirstHeader("Transfer-Encoding");
219: if (transferenc != null) {
220: response.removeHeaders("Content-Length");
221: if (transferenc.getValue().indexOf("chunked") != -1) {
222: outsream = new ChunkedOutputStream(outsream);
223: }
224: }
225:
226: byte[] tmp = new byte[1024];
227: int i = 0;
228: while ((i = content.read(tmp)) >= 0) {
229: outsream.write(tmp, 0, i);
230: }
231: if (outsream instanceof ChunkedOutputStream) {
232: ((ChunkedOutputStream) outsream).finish();
233: }
234: }
235: outsream.flush();
236: }
237:
238: public int getSocketTimeout() throws SocketException {
239: return this .socket.getSoTimeout();
240: }
241:
242: public void setSocketTimeout(int timeout) throws SocketException {
243: this.socket.setSoTimeout(timeout);
244: }
245:
246: }
|