/*
* Copyright 2010 Ning, Inc.
*
* Ning licenses this file to you 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 com.ning.http.client;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* Represents the asynchronous HTTP response callback for an {@link com.ning.http.client.AsyncCompletionHandler}
*/
public interface Response {
/**
* Returns the status code for the request.
*
* @return The status code
*/
public int getStatusCode();
/**
* Returns the status text for the request.
*
* @return The status text
*/
public String getStatusText();
/**
* Return the entire response body as a byte[].
*
* @return the entire response body as a byte[].
* @throws IOException
*/
public byte[] getResponseBodyAsBytes() throws IOException;
/**
* Returns an input stream for the response body. Note that you should not try to get this more than once,
* and that you should not close the stream.
*
* @return The input stream
* @throws java.io.IOException
*/
public InputStream getResponseBodyAsStream() throws IOException;
/**
* Returns the first maxLength bytes of the response body as a string. Note that this does not check
* whether the content type is actually a textual one, but it will use the charset if present in the content
* type header.
*
* @param maxLength The maximum number of bytes to read
* @param charset the charset to use when decoding the stream
* @return The response body
* @throws java.io.IOException
*/
public String getResponseBodyExcerpt(int maxLength, String charset) throws IOException;
/**
* Return the entire response body as a String.
*
* @param charset the charset to use when decoding the stream
* @return the entire response body as a String.
* @throws IOException
*/
public String getResponseBody(String charset) throws IOException;
/**
* Returns the first maxLength bytes of the response body as a string. Note that this does not check
* whether the content type is actually a textual one, but it will use the charset if present in the content
* type header.
*
* @param maxLength The maximum number of bytes to read
* @return The response body
* @throws java.io.IOException
*/
public String getResponseBodyExcerpt(int maxLength) throws IOException;
/**
* Return the entire response body as a String.
*
* @return the entire response body as a String.
* @throws IOException
*/
public String getResponseBody() throws IOException;
/**
* Return the request {@link URI}. Note that if the request got redirected, the value of the {@link URI} will be
* the last valid redirect url.
*
* @return the request {@link URI}.
* @throws MalformedURLException
*/
public URI getUri() throws MalformedURLException;
/**
* Return the content-type header value.
*
* @return the content-type header value.
*/
public String getContentType();
/**
* Return the response header
*
* @return the response header
*/
public String getHeader(String name);
/**
* Return a {@link List} of the response header value.
*
* @return the response header
*/
public List<String> getHeaders(String name);
public FluentCaseInsensitiveStringsMap getHeaders();
/**
* Return true if the response redirects to another object.
*
* @return True if the response redirects to another object.
*/
boolean isRedirected();
/**
* Subclasses SHOULD implement toString() in a way that identifies the request for logging.
*
* @return The textual representation
*/
public String toString();
/**
* Return the list of {@link Cookie}.
*/
public List<Cookie> getCookies();
/**
* Return true if the response's status has been computed by an {@link AsyncHandler}
*
* @return true if the response's status has been computed by an {@link AsyncHandler}
*/
public boolean hasResponseStatus();
/**
* Return true if the response's headers has been computed by an {@link AsyncHandler} It will return false if the
* either {@link com.ning.http.client.AsyncHandler#onStatusReceived(HttpResponseStatus)}
* or {@link AsyncHandler#onHeadersReceived(HttpResponseHeaders)} returned {@link com.ning.http.client.AsyncHandler.STATE#ABORT}
*
* @return true if the response's headers has been computed by an {@link AsyncHandler}
*/
public boolean hasResponseHeaders();
/**
* Return true if the response's body has been computed by an {@link AsyncHandler}. It will return false if the
* either {@link com.ning.http.client.AsyncHandler#onStatusReceived(HttpResponseStatus)}
* or {@link AsyncHandler#onHeadersReceived(HttpResponseHeaders)} returned {@link com.ning.http.client.AsyncHandler.STATE#ABORT}
*
* @return true if the response's body has been computed by an {@link AsyncHandler}
*/
public boolean hasResponseBody();
public static class ResponseBuilder {
private final Collection<HttpResponseBodyPart> bodies =
Collections.synchronizedCollection(new ArrayList<HttpResponseBodyPart>());
private HttpResponseStatus status;
private HttpResponseHeaders headers;
/**
* Accumulate {@link HttpContent} in order to build a {@link Response}
*
* @param httpContent {@link HttpContent}
* @return this
*/
public ResponseBuilder accumulate(HttpContent httpContent) {
if (httpContent instanceof HttpResponseStatus) {
status = (HttpResponseStatus) httpContent;
} else if (httpContent instanceof HttpResponseHeaders) {
headers = (HttpResponseHeaders) httpContent;
} else if (httpContent instanceof HttpResponseBodyPart) {
bodies.add((HttpResponseBodyPart) httpContent);
}
return this;
}
/**
* Build a {@link Response} instance
*
* @return a {@link Response} instance
*/
public Response build() {
return status == null ? null : status.provider().prepareResponse(status, headers, bodies);
}
/**
* Reset the internal state of this builder.
*/
public void reset() {
bodies.clear();
status = null;
headers = null;
}
}
}