/*
* This software is distributed under the terms of the FSF
* Gnu Lesser General Public License (see lgpl.txt).
*
* This program is distributed WITHOUT ANY WARRANTY. See the
* GNU General Public License for more details.
*/
package com.scooterframework.common.http;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HeaderIterator;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
/**
* HTTPClient class represents a http response.
*
* @author (Fei) John Chen
*
*/
public class HTTPResponse {
private HttpResponse response;
public HTTPResponse(HttpResponse response) {
if (response == null) {
throw new IllegalArgumentException("HTTP response may not be null");
}
this.response = response;
}
/**
* Returns http response status code.
*
* @return status code
*/
public int getStatusCode() {
return response.getStatusLine().getStatusCode();
}
/**
* Returns http response reason phrase.
*
* @return reason phrase
*/
public String getReasonPhrase() {
return response.getStatusLine().getReasonPhrase();
}
/**
* Returns http response protocol version.
*
* @return protocol version
*/
public String getProtocolVersion() {
return response.getProtocolVersion().toString();
}
/**
* Returns http response status.
*
* @return status string
*/
public String getStatusLine() {
return response.getStatusLine().toString();
}
/**
* Returns the content encoding string, if known.
*
* @return the content encoding string, or <code>null</code> if the content
* encoding is unknown
*/
public String getContentEncodingLine() {
String s = null;
HttpEntity entity = response.getEntity();
if (entity != null) {
Header header = entity.getContentEncoding();
if (header != null)
s = header.toString();
}
return s;
}
/**
* Returns the content encoding name, if known.
*
* @return the content encoding name, or <code>null</code> if the content
* encoding is unknown
*/
public String getContentEncodingName() {
String s = null;
HttpEntity entity = response.getEntity();
if (entity != null) {
Header header = entity.getContentEncoding();
if (header != null)
s = header.getName();
}
return s;
}
/**
* Returns the content encoding value, if known.
*
* @return the content encoding value, or <code>null</code> if the content
* encoding is unknown
*/
public String getContentEncodingValue() {
String s = null;
HttpEntity entity = response.getEntity();
if (entity != null) {
Header header = entity.getContentEncoding();
if (header != null)
s = header.getValue();
}
return s;
}
/**
* Returns the content type string, if known.
*
* @return the content type header string, or <code>null</code> if the
* content type is unknown
*/
public String getContentTypeLine() {
String s = null;
HttpEntity entity = response.getEntity();
if (entity != null) {
Header header = entity.getContentType();
if (header != null)
s = header.toString();
}
return s;
}
/**
* Returns the content type name, if known.
*
* @return the content type name, or <code>null</code> if the content type
* is unknown
*/
public String getContentTypeName() {
String s = null;
HttpEntity entity = response.getEntity();
if (entity != null) {
Header header = entity.getContentType();
if (header != null)
s = header.getName();
}
return s;
}
/**
* Returns the content type value, if known.
*
* @return the content type value, or <code>null</code> if the content type
* is unknown
*/
public String getContentTypeValue() {
String s = null;
HttpEntity entity = response.getEntity();
if (entity != null) {
Header header = entity.getContentType();
if (header != null)
s = header.getValue();
}
return s;
}
/**
* Returns the length of the content, if known.
*
* @return the number of bytes of the content, or a negative number if
* unknown. If the content length is known but exceeds
* {@link java.lang.Long#MAX_VALUE Long.MAX_VALUE}, a negative
* number is returned.
*/
public long getContentLength() {
long l = -1;
HttpEntity entity = response.getEntity();
if (entity != null) {
l = entity.getContentLength();
}
if (l == -1) {
Set<String> set = getHeaderValuesForName("Content-Length");
if (set.size() > 0) {
Iterator<String> it = set.iterator();
if (it.hasNext()) {
String s = it.next();
try {
l = Long.parseLong(s);
} catch (Exception ex) {
;
}
}
}
}
return l;
}
/**
* Returns all headers.
*
* @return headers array
*/
public String[] getAllHeaders() {
Header[] headers = response.getAllHeaders();
if (headers == null || headers.length == 0)
return null;
String[] hs = new String[headers.length];
for (int i = 0; i < headers.length; i++) {
hs[i] = headers[i].toString();
}
return hs;
}
/**
* Returns a map of all headers. If there is no headers, an empty map
* instance is returned.
*
* @return headers map
*/
public Map<String, String> getAllHeadersAsMap() {
Header[] headers = response.getAllHeaders();
if (headers == null || headers.length == 0)
return new HashMap<String, String>();
Map<String, String> hs = new HashMap<String, String>(headers.length);
for (int i = 0; i < headers.length; i++) {
hs.put(headers[i].getName(), headers[i].getValue());
}
return hs;
}
/**
* Returns a set of values in the header associated with the <tt>name</tt>.
*
* @param name name of a head property
* @return a set of values
*/
public Set<String> getHeaderValuesForName(String name) {
HeaderIterator it = response.headerIterator(name);
Set<String> values = new HashSet<String>();
while (it.hasNext()) {
Header header = it.nextHeader();
HeaderElement[] elements = header.getElements();
for (HeaderElement element : elements) {
values.add(element.getName());
}
}
return values;
}
/**
* Returns a set of allowed methods.
*
* @return a set of allowed methods.
*/
public Set<String> getAllowedMethods() {
return getHeaderValuesForName("Allow");
}
/**
* Returns content as string by using the platform's default charset.
*
* Please notice that you can only call one of
* the <tt>getContentAsXXX()</tt> once.
*
* @return a string of content
* @throws IOException
*/
public String getContentAsString() throws IOException {
byte[] content = getContentAsBytes();
return (content != null) ? (new String(content)) : "";
}
/**
* Returns content as string by using the specified charset.
*
* Please notice that you can only call one of
* the <tt>getContentAsXXX()</tt> once.
*
* @param charsetName the name of a supported charset
* @return a string of content
* @throws IOException
*/
public String getContentAsString(String charsetName) throws IOException {
byte[] content = getContentAsBytes();
return (content != null) ? (new String(content, charsetName)) : "";
}
/**
* Returns content as bytes.
*
* Please notice that you can only call one of the
* <tt>getContentAsXXX()</tt> once.
*
* @return a byte array of content
* @throws IOException
*/
public byte[] getContentAsBytes() throws IOException {
byte[] content = null;
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream is = null;
ByteArrayOutputStream out = null;
try {
is = entity.getContent();
if (is == null) {
return new byte[] {};
}
out = new ByteArrayOutputStream(2048);
int n = 0;
byte[] b = new byte[2048];
while ((n = is.read(b)) != -1) {
out.write(b, 0, n);
}
} catch (IOException ex) {
throw ex;
} finally {
closeInputStream(is);
closeOutputStream(out);
}
content = out.toByteArray();
}
return content;
}
/**
* Returns content as input stream.
*
* Please notice that you can only call one of the
* <tt>getContentAsXXX()</tt> once.
*
* @return a stream of content
* @throws IOException
*/
public InputStream getContentAsInputStream() throws IOException {
InputStream is = null;
HttpEntity entity = response.getEntity();
if (entity != null) {
is = entity.getContent();
}
return is;
}
private void closeInputStream(InputStream is) {
if (is != null) {
try {
is.close();
} catch (Exception ex) {
is = null;
}
}
}
private void closeOutputStream(OutputStream out) {
if (out != null) {
try {
out.close();
} catch (Exception ex) {
out = null;
}
}
}
}