/* * Copyright (C) 2012 Pixmob (http://github.com/pixmob) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.pixmob.httpclient; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import android.os.Build; /** * When the Http server receives a request from a client, the Http response is * sent back. * @author Pixmob */ public final class HttpResponse { private final int statusCode; private final Map<String, String> cookies; private final Map<String, List<String>> headers; private InputStream payload; HttpResponse(final int statusCode, final InputStream payload, final Map<String, List<String>> rawHeaders, final Map<String, String> cookies) { this.statusCode = statusCode; this.payload = payload; this.cookies = Collections.unmodifiableMap(cookies); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) { // Before Gingerbread, Android has a bug where all headers are // stored in lower-case: // http://code.google.com/p/android/issues/detail?id=6684 final Map<String, List<String>> newHeaders = new HashMap<String, List<String>>(rawHeaders.size()); for (final Map.Entry<String, List<String>> e : rawHeaders.entrySet()) { final String key = e.getKey(); final int keyLen = key.length(); final StringBuilder newKey = new StringBuilder(keyLen); for (int i = 0; i < keyLen; ++i) { final char c = key.charAt(i); final char c2; if (i == 0 || key.charAt(i - 1) == '-') { c2 = Character.toUpperCase(c); } else { c2 = c; } newKey.append(c2); } newHeaders.put(newKey.toString(), e.getValue()); } this.headers = Collections.unmodifiableMap(newHeaders); } else { this.headers = Collections.unmodifiableMap(rawHeaders); } } /** * Get the content type for this response, or <code>null</code> if unknown. */ public String getContentType() { final String contentType = getFirstHeaderValue("Content-Type"); if (contentType == null) { return null; } final int i = contentType.indexOf(';'); return i == -1 ? contentType : contentType.substring(0, i).trim(); } /** * Get the charset for this response, or <code>null</code> if unknown. */ public String getContentCharset() { final String contentType = getFirstHeaderValue("Content-Type"); if (contentType == null) { return null; } final int i = contentType.indexOf('='); return i == -1 ? null : contentType.substring(i + 1).trim(); } /** * Get the response payload. */ public InputStream getPayload() { return payload; } void preload(File temp) throws IOException { final FileOutputStream out = new FileOutputStream(temp); final byte[] inBuf = new byte[1024]; final InputStream in = getPayload(); for (int bytesRead = 0; (bytesRead = in.read(inBuf)) != -1;) { out.write(inBuf, 0, bytesRead); } payload = new FileInputStream(temp); } public void read(StringBuilder buffer) throws IOException { String enc = getContentCharset(); if (enc == null) { enc = "UTF-8"; } final InputStream input = getPayload(); final InputStreamReader reader = new InputStreamReader(input, enc); final char[] inBuf = new char[64]; for (int charsRead; (charsRead = reader.read(inBuf)) != -1;) { buffer.append(inBuf, 0, charsRead); } } /** * Get the response status code. */ public int getStatusCode() { return statusCode; } /** * Get the response headers. */ public Map<String, List<String>> getHeaders() { return headers; } /** * Get the first header value, or <code>null</code> if unset. */ public String getFirstHeaderValue(String name) { final List<String> values = headers.get(name); if (values == null || values.isEmpty()) { return null; } return values.get(0); } /** * Get the response cookies. */ public Map<String, String> getCookies() { return cookies; } }