package ecologylab.bigsemantics.httpclient; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.ParseException; import org.apache.http.util.EntityUtils; import ecologylab.generic.HashMapArrayList; import ecologylab.net.ParsedURL; import ecologylab.serialization.annotations.Hint; import ecologylab.serialization.annotations.simpl_collection; import ecologylab.serialization.annotations.simpl_hints; import ecologylab.serialization.annotations.simpl_map; import ecologylab.serialization.annotations.simpl_scalar; /** * Response message from a HTTP request. NOT THREAD SAFE! You should NOT write to a HttpResponse * object from multiple threads. * * @author quyin */ public class SimplHttpResponse { @simpl_scalar private String url; /** * Other locations, e.g. redirected locations. */ @simpl_collection("other_url") private List<String> otherUrls; @simpl_scalar private int code; @simpl_scalar private String message; @simpl_map("header") private HashMapArrayList<String, SimplHttpHeader> headers; /** * The content of the page, e.g. in HTML. */ @simpl_scalar @simpl_hints(Hint.XML_LEAF) private String content; private String mimeType; private String charset; private InputStream contentStream; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public List<String> getOtherUrls() { return otherUrls; } List<String> otherUrls() { if (otherUrls == null) { otherUrls = new ArrayList<String>(); } return otherUrls; } public void addOtherUrl(String url) { otherUrls().add(url); } protected void setOtherUrls(List<String> otherUrls) { this.otherUrls = otherUrls; } public List<ParsedURL> getOtherPurls() { if (otherUrls != null) { List<ParsedURL> result = new ArrayList<ParsedURL>(); for (String url : otherUrls) { ParsedURL purl = ParsedURL.getAbsolute(url); result.add(purl); } return result; } return null; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } Map<String, SimplHttpHeader> headers() { if (headers == null) { headers = new HashMapArrayList<String, SimplHttpHeader>(); } return headers; } public String getHeader(String name) { if (headers != null) { SimplHttpHeader header = headers.get(name); return header == null ? null : header.getValue(); } return null; } public void setHeader(String name, String value) { String prevValue = getHeader(name); if (prevValue == null) { headers().put(name, new SimplHttpHeader(name, value)); } else if (!prevValue.equals(value)) { headers().get(name).setValue(value); } } protected void setHeaders(HashMapArrayList<String, SimplHttpHeader> headers) { this.headers = headers; } public String getMimeType() { if (mimeType == null) { parseContentType(); } return mimeType; } public String getCharset() { if (charset == null) { parseContentType(); } return charset; } protected void parseContentType() { String contentType = getHeader("Content-Type"); if (contentType != null) { int p = contentType.indexOf(';'); if (p < 0) { mimeType = contentType.trim(); } else { mimeType = contentType.substring(0, p).trim(); String charsetSpec = contentType.substring(p + 1).trim(); if (charsetSpec.startsWith("charset=")) { charset = charsetSpec.substring(8); } } } } public String getContent() { return content; } public void setContent(String content) { this.content = content; this.contentStream = null; } public int getContentLength() { return content == null ? 0 : content.length(); } public InputStream getContentAsStream() throws UnsupportedEncodingException { if (contentStream == null && content != null) { contentStream = new ByteArrayInputStream(content.getBytes("UTF-8")); } return contentStream; } public static SimplHttpResponse parse(String initialUrl, InputStream istream) throws Exception { return new HttpResponseParser().parse(initialUrl, istream); } public static SimplHttpResponse parse(String initialUrl, List<String> redirectedUrls, HttpResponse resp) throws ParseException, IOException { SimplHttpResponse result = new SimplHttpResponse(); if (redirectedUrls == null || redirectedUrls.isEmpty()) { result.setUrl(initialUrl); } else { List<String> otherUrls = new ArrayList<String>(); String url = initialUrl; for (String redirectedUrl : redirectedUrls) { otherUrls.add(url); if (HttpClientUtils.looksLikeRelative(redirectedUrl)) { redirectedUrl = HttpClientUtils.relativeToAbsolute(url, redirectedUrl); } url = redirectedUrl; } result.setUrl(url); result.otherUrls = otherUrls; } result.setCode(resp.getStatusLine().getStatusCode()); result.setMessage(resp.getStatusLine().getReasonPhrase()); Header[] headers = resp.getAllHeaders(); for (Header header : headers) { result.setHeader(header.getName(), header.getValue()); } result.parseContentType(); HttpEntity entity = resp.getEntity(); String content = EntityUtils.toString(entity, Charset.forName("UTF-8")); result.setContent(content); return result; } }