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