diff --git a/lib/src/main/java/com/github/kevinsawicki/http/HttpRequest.java b/lib/src/main/java/com/github/kevinsawicki/http/HttpRequest.java
index d8876ba2..8dba9be2 100644
--- a/lib/src/main/java/com/github/kevinsawicki/http/HttpRequest.java
+++ b/lib/src/main/java/com/github/kevinsawicki/http/HttpRequest.java
@@ -260,6 +260,14 @@ public class HttpRequest {
private static HostnameVerifier TRUSTED_VERIFIER;
+ private static final int DEFAULT_READ_TIMEOUT = 5000;
+
+ private static final int DEFAULT_CONNECT_TIMEOUT = 5000;
+
+ private boolean defaultTimeOutFlag = false;
+
+ private HttpResponse httpResponse;
+
private static String getValidCharset(final String charset) {
if (charset != null && charset.length() > 0)
return charset;
@@ -1548,120 +1556,6 @@ public boolean ignoreCloseExceptions() {
return ignoreCloseExceptions;
}
- /**
- * Get the status code of the response
- *
- * @return the response code
- * @throws HttpRequestException
- */
- public int code() throws HttpRequestException {
- try {
- closeOutput();
- return getConnection().getResponseCode();
- } catch (IOException e) {
- throw new HttpRequestException(e);
- }
- }
-
- /**
- * Set the value of the given {@link AtomicInteger} to the status code of the
- * response
- *
- * @param output
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest code(final AtomicInteger output)
- throws HttpRequestException {
- output.set(code());
- return this;
- }
-
- /**
- * Is the response code a 200 OK?
- *
- * @return true if 200, false otherwise
- * @throws HttpRequestException
- */
- public boolean ok() throws HttpRequestException {
- return HTTP_OK == code();
- }
-
- /**
- * Is the response code a 201 Created?
- *
- * @return true if 201, false otherwise
- * @throws HttpRequestException
- */
- public boolean created() throws HttpRequestException {
- return HTTP_CREATED == code();
- }
-
- /**
- * Is the response code a 204 No Content?
- *
- * @return true if 204, false otherwise
- * @throws HttpRequestException
- */
- public boolean noContent() throws HttpRequestException {
- return HTTP_NO_CONTENT == code();
- }
-
- /**
- * Is the response code a 500 Internal Server Error?
- *
- * @return true if 500, false otherwise
- * @throws HttpRequestException
- */
- public boolean serverError() throws HttpRequestException {
- return HTTP_INTERNAL_ERROR == code();
- }
-
- /**
- * Is the response code a 400 Bad Request?
- *
- * @return true if 400, false otherwise
- * @throws HttpRequestException
- */
- public boolean badRequest() throws HttpRequestException {
- return HTTP_BAD_REQUEST == code();
- }
-
- /**
- * Is the response code a 404 Not Found?
- *
- * @return true if 404, false otherwise
- * @throws HttpRequestException
- */
- public boolean notFound() throws HttpRequestException {
- return HTTP_NOT_FOUND == code();
- }
-
- /**
- * Is the response code a 304 Not Modified?
- *
- * @return true if 304, false otherwise
- * @throws HttpRequestException
- */
- public boolean notModified() throws HttpRequestException {
- return HTTP_NOT_MODIFIED == code();
- }
-
- /**
- * Get status message of the response
- *
- * @return message
- * @throws HttpRequestException
- */
- public String message() throws HttpRequestException {
- try {
- closeOutput();
- return getConnection().getResponseMessage();
- } catch (IOException e) {
- throw new HttpRequestException(e);
- }
- }
-
/**
* Disconnect the connection
*
@@ -1735,1525 +1629,1654 @@ public HttpRequest uncompress(final boolean uncompress) {
return this;
}
+
/**
- * Create byte array output stream
+ * Set read timeout on connection to given value
*
- * @return stream
+ * @param timeout
+ * @return this request
*/
- protected ByteArrayOutputStream byteStream() {
- final int size = contentLength();
- if (size > 0)
- return new ByteArrayOutputStream(size);
- else
- return new ByteArrayOutputStream();
+ public HttpRequest readTimeout(final int timeout) {
+ getConnection().setReadTimeout(timeout);
+ return this;
}
/**
- * Get response as {@link String} in given character set
- *
- * This will fall back to using the UTF-8 character set if the given charset
- * is null
+ * Set connect timeout on connection to given value
*
- * @param charset
- * @return string
- * @throws HttpRequestException
+ * @param timeout
+ * @return this request
*/
- public String body(final String charset) throws HttpRequestException {
- final ByteArrayOutputStream output = byteStream();
- try {
- copy(buffer(), output);
- return output.toString(getValidCharset(charset));
- } catch (IOException e) {
- throw new HttpRequestException(e);
- }
+ public HttpRequest connectTimeout(final int timeout) {
+ getConnection().setConnectTimeout(timeout);
+ return this;
}
/**
- * Get response as {@link String} using character set returned from
- * {@link #charset()}
+ * Set header name to given value
*
- * @return string
- * @throws HttpRequestException
+ * @param name
+ * @param value
+ * @return this request
*/
- public String body() throws HttpRequestException {
- return body(charset());
+ public HttpRequest header(final String name, final String value) {
+ getConnection().setRequestProperty(name, value);
+ return this;
}
/**
- * Get the response body as a {@link String} and set it as the value of the
- * given reference.
+ * Set header name to given value
*
- * @param output
+ * @param name
+ * @param value
* @return this request
- * @throws HttpRequestException
*/
- public HttpRequest body(final AtomicReference output) throws HttpRequestException {
- output.set(body());
- return this;
+ public HttpRequest header(final String name, final Number value) {
+ return header(name, value != null ? value.toString() : null);
}
/**
- * Get the response body as a {@link String} and set it as the value of the
- * given reference.
+ * Set all headers found in given map where the keys are the header names and
+ * the values are the header values
*
- * @param output
- * @param charset
+ * @param headers
* @return this request
- * @throws HttpRequestException
*/
- public HttpRequest body(final AtomicReference output, final String charset) throws HttpRequestException {
- output.set(body(charset));
+ public HttpRequest headers(final Map headers) {
+ if (!headers.isEmpty())
+ for (Entry header : headers.entrySet())
+ header(header);
return this;
}
-
/**
- * Is the response body empty?
+ * Set header to have given entry's key as the name and value as the value
*
- * @return true if the Content-Length response header is 0, false otherwise
- * @throws HttpRequestException
+ * @param header
+ * @return this request
*/
- public boolean isBodyEmpty() throws HttpRequestException {
- return contentLength() == 0;
+ public HttpRequest header(final Entry header) {
+ return header(header.getKey(), header.getValue());
}
/**
- * Get response as byte array
+ * Get parameter values from header value
*
- * @return byte array
- * @throws HttpRequestException
+ * @param header
+ * @return parameter value or null if none
*/
- public byte[] bytes() throws HttpRequestException {
- final ByteArrayOutputStream output = byteStream();
- try {
- copy(buffer(), output);
- } catch (IOException e) {
- throw new HttpRequestException(e);
+ protected Map getParams(final String header) {
+ if (header == null || header.length() == 0)
+ return Collections.emptyMap();
+
+ final int headerLength = header.length();
+ int start = header.indexOf(';') + 1;
+ if (start == 0 || start == headerLength)
+ return Collections.emptyMap();
+
+ int end = header.indexOf(';', start);
+ if (end == -1)
+ end = headerLength;
+
+ Map params = new LinkedHashMap();
+ while (start < end) {
+ int nameEnd = header.indexOf('=', start);
+ if (nameEnd != -1 && nameEnd < end) {
+ String name = header.substring(start, nameEnd).trim();
+ if (name.length() > 0) {
+ String value = header.substring(nameEnd + 1, end).trim();
+ int length = value.length();
+ if (length != 0)
+ if (length > 2 && '"' == value.charAt(0)
+ && '"' == value.charAt(length - 1))
+ params.put(name, value.substring(1, length - 1));
+ else
+ params.put(name, value);
+ }
+ }
+
+ start = end + 1;
+ end = header.indexOf(';', start);
+ if (end == -1)
+ end = headerLength;
}
- return output.toByteArray();
- }
- /**
- * Get response in a buffered stream
- *
- * @see #bufferSize(int)
- * @return stream
- * @throws HttpRequestException
- */
- public BufferedInputStream buffer() throws HttpRequestException {
- return new BufferedInputStream(stream(), bufferSize);
+ return params;
}
/**
- * Get stream to response body
+ * Get parameter value from header value
*
- * @return stream
- * @throws HttpRequestException
+ * @param value
+ * @param paramName
+ * @return parameter value or null if none
*/
- public InputStream stream() throws HttpRequestException {
- InputStream stream;
- if (code() < HTTP_BAD_REQUEST)
- try {
- stream = getConnection().getInputStream();
- } catch (IOException e) {
- throw new HttpRequestException(e);
- }
- else {
- stream = getConnection().getErrorStream();
- if (stream == null)
- try {
- stream = getConnection().getInputStream();
- } catch (IOException e) {
- if (contentLength() > 0)
- throw new HttpRequestException(e);
+ protected String getParam(final String value, final String paramName) {
+ if (value == null || value.length() == 0)
+ return null;
+
+ final int length = value.length();
+ int start = value.indexOf(';') + 1;
+ if (start == 0 || start == length)
+ return null;
+
+ int end = value.indexOf(';', start);
+ if (end == -1)
+ end = length;
+
+ while (start < end) {
+ int nameEnd = value.indexOf('=', start);
+ if (nameEnd != -1 && nameEnd < end
+ && paramName.equals(value.substring(start, nameEnd).trim())) {
+ String paramValue = value.substring(nameEnd + 1, end).trim();
+ int valueLength = paramValue.length();
+ if (valueLength != 0)
+ if (valueLength > 2 && '"' == paramValue.charAt(0)
+ && '"' == paramValue.charAt(valueLength - 1))
+ return paramValue.substring(1, valueLength - 1);
else
- stream = new ByteArrayInputStream(new byte[0]);
- }
+ return paramValue;
+ }
+
+ start = end + 1;
+ end = value.indexOf(';', start);
+ if (end == -1)
+ end = length;
}
- if (!uncompress || !ENCODING_GZIP.equals(contentEncoding()))
- return stream;
- else
- try {
- return new GZIPInputStream(stream);
- } catch (IOException e) {
- throw new HttpRequestException(e);
- }
+ return null;
}
+
/**
- * Get reader to response body using given character set.
- *
- * This will fall back to using the UTF-8 character set if the given charset
- * is null
+ * Set the 'User-Agent' header to given value
*
- * @param charset
- * @return reader
- * @throws HttpRequestException
+ * @param userAgent
+ * @return this request
*/
- public InputStreamReader reader(final String charset)
- throws HttpRequestException {
- try {
- return new InputStreamReader(stream(), getValidCharset(charset));
- } catch (UnsupportedEncodingException e) {
- throw new HttpRequestException(e);
- }
+ public HttpRequest userAgent(final String userAgent) {
+ return header(HEADER_USER_AGENT, userAgent);
}
/**
- * Get reader to response body using the character set returned from
- * {@link #charset()}
+ * Set the 'Referer' header to given value
*
- * @return reader
- * @throws HttpRequestException
+ * @param referer
+ * @return this request
*/
- public InputStreamReader reader() throws HttpRequestException {
- return reader(charset());
+ public HttpRequest referer(final String referer) {
+ return header(HEADER_REFERER, referer);
}
/**
- * Get buffered reader to response body using the given character set r and
- * the configured buffer size
- *
+ * Set value of {@link HttpURLConnection#setUseCaches(boolean)}
*
- * @see #bufferSize(int)
- * @param charset
- * @return reader
- * @throws HttpRequestException
+ * @param useCaches
+ * @return this request
*/
- public BufferedReader bufferedReader(final String charset)
- throws HttpRequestException {
- return new BufferedReader(reader(charset), bufferSize);
+ public HttpRequest useCaches(final boolean useCaches) {
+ getConnection().setUseCaches(useCaches);
+ return this;
}
/**
- * Get buffered reader to response body using the character set returned from
- * {@link #charset()} and the configured buffer size
+ * Set the 'Accept-Encoding' header to given value
*
- * @see #bufferSize(int)
- * @return reader
- * @throws HttpRequestException
+ * @param acceptEncoding
+ * @return this request
*/
- public BufferedReader bufferedReader() throws HttpRequestException {
- return bufferedReader(charset());
+ public HttpRequest acceptEncoding(final String acceptEncoding) {
+ return header(HEADER_ACCEPT_ENCODING, acceptEncoding);
}
/**
- * Stream response body to file
+ * Set the 'Accept-Encoding' header to 'gzip'
*
- * @param file
+ * @see #uncompress(boolean)
* @return this request
- * @throws HttpRequestException
*/
- public HttpRequest receive(final File file) throws HttpRequestException {
- final OutputStream output;
- try {
- output = new BufferedOutputStream(new FileOutputStream(file), bufferSize);
- } catch (FileNotFoundException e) {
- throw new HttpRequestException(e);
- }
- return new CloseOperation(output, ignoreCloseExceptions) {
-
- @Override
- protected HttpRequest run() throws HttpRequestException, IOException {
- return receive(output);
- }
- }.call();
+ public HttpRequest acceptGzipEncoding() {
+ return acceptEncoding(ENCODING_GZIP);
}
/**
- * Stream response to given output stream
+ * Set the 'Accept-Charset' header to given value
*
- * @param output
+ * @param acceptCharset
* @return this request
- * @throws HttpRequestException
*/
- public HttpRequest receive(final OutputStream output)
- throws HttpRequestException {
- try {
- return copy(buffer(), output);
- } catch (IOException e) {
- throw new HttpRequestException(e);
- }
+ public HttpRequest acceptCharset(final String acceptCharset) {
+ return header(HEADER_ACCEPT_CHARSET, acceptCharset);
}
/**
- * Stream response to given print stream
+ * Set the 'Authorization' header to given value
*
- * @param output
+ * @param authorization
* @return this request
- * @throws HttpRequestException
*/
- public HttpRequest receive(final PrintStream output)
- throws HttpRequestException {
- return receive((OutputStream) output);
+ public HttpRequest authorization(final String authorization) {
+ return header(HEADER_AUTHORIZATION, authorization);
}
/**
- * Receive response into the given appendable
+ * Set the 'Proxy-Authorization' header to given value
*
- * @param appendable
+ * @param proxyAuthorization
* @return this request
- * @throws HttpRequestException
*/
- public HttpRequest receive(final Appendable appendable)
- throws HttpRequestException {
- final BufferedReader reader = bufferedReader();
- return new CloseOperation(reader, ignoreCloseExceptions) {
-
- @Override
- public HttpRequest run() throws IOException {
- final CharBuffer buffer = CharBuffer.allocate(bufferSize);
- int read;
- while ((read = reader.read(buffer)) != -1) {
- buffer.rewind();
- appendable.append(buffer, 0, read);
- buffer.rewind();
- }
- return HttpRequest.this;
- }
- }.call();
+ public HttpRequest proxyAuthorization(final String proxyAuthorization) {
+ return header(HEADER_PROXY_AUTHORIZATION, proxyAuthorization);
}
/**
- * Receive response into the given writer
+ * Set the 'Authorization' header to given values in Basic authentication
+ * format
*
- * @param writer
+ * @param name
+ * @param password
* @return this request
- * @throws HttpRequestException
*/
- public HttpRequest receive(final Writer writer) throws HttpRequestException {
- final BufferedReader reader = bufferedReader();
- return new CloseOperation(reader, ignoreCloseExceptions) {
-
- @Override
- public HttpRequest run() throws IOException {
- return copy(reader, writer);
- }
- }.call();
+ public HttpRequest basic(final String name, final String password) {
+ return authorization("Basic " + Base64.encode(name + ':' + password));
}
/**
- * Set read timeout on connection to given value
+ * Set the 'Proxy-Authorization' header to given values in Basic authentication
+ * format
*
- * @param timeout
+ * @param name
+ * @param password
* @return this request
*/
- public HttpRequest readTimeout(final int timeout) {
- getConnection().setReadTimeout(timeout);
- return this;
+ public HttpRequest proxyBasic(final String name, final String password) {
+ return proxyAuthorization("Basic " + Base64.encode(name + ':' + password));
}
/**
- * Set connect timeout on connection to given value
+ * Set the 'If-Modified-Since' request header to the given value
*
- * @param timeout
+ * @param ifModifiedSince
* @return this request
*/
- public HttpRequest connectTimeout(final int timeout) {
- getConnection().setConnectTimeout(timeout);
+ public HttpRequest ifModifiedSince(final long ifModifiedSince) {
+ getConnection().setIfModifiedSince(ifModifiedSince);
return this;
}
/**
- * Set header name to given value
+ * Set the 'If-None-Match' request header to the given value
*
- * @param name
- * @param value
+ * @param ifNoneMatch
* @return this request
*/
- public HttpRequest header(final String name, final String value) {
- getConnection().setRequestProperty(name, value);
- return this;
+ public HttpRequest ifNoneMatch(final String ifNoneMatch) {
+ return header(HEADER_IF_NONE_MATCH, ifNoneMatch);
}
/**
- * Set header name to given value
+ * Set the 'Content-Type' request header to the given value
*
- * @param name
- * @param value
+ * @param contentType
* @return this request
*/
- public HttpRequest header(final String name, final Number value) {
- return header(name, value != null ? value.toString() : null);
+ public HttpRequest contentType(final String contentType) {
+ return contentType(contentType, null);
}
/**
- * Set all headers found in given map where the keys are the header names and
- * the values are the header values
+ * Set the 'Content-Type' request header to the given value and charset
*
- * @param headers
+ * @param contentType
+ * @param charset
* @return this request
*/
- public HttpRequest headers(final Map headers) {
- if (!headers.isEmpty())
- for (Entry header : headers.entrySet())
- header(header);
- return this;
+ public HttpRequest contentType(final String contentType, final String charset) {
+ if (charset != null && charset.length() > 0) {
+ final String separator = "; " + PARAM_CHARSET + '=';
+ return header(HEADER_CONTENT_TYPE, contentType + separator + charset);
+ } else
+ return header(HEADER_CONTENT_TYPE, contentType);
}
+
/**
- * Set header to have given entry's key as the name and value as the value
+ * Set the 'Content-Length' request header to the given value
*
- * @param header
+ * @param contentLength
* @return this request
*/
- public HttpRequest header(final Entry header) {
- return header(header.getKey(), header.getValue());
+ public HttpRequest contentLength(final String contentLength) {
+ return contentLength(Integer.parseInt(contentLength));
}
/**
- * Get a response header
+ * Set the 'Content-Length' request header to the given value
*
- * @param name
- * @return response header
- * @throws HttpRequestException
+ * @param contentLength
+ * @return this request
*/
- public String header(final String name) throws HttpRequestException {
- closeOutputQuietly();
- return getConnection().getHeaderField(name);
+ public HttpRequest contentLength(final int contentLength) {
+ getConnection().setFixedLengthStreamingMode(contentLength);
+ return this;
}
/**
- * Get all the response headers
+ * Set the 'Accept' header to given value
*
- * @return map of response header names to their value(s)
- * @throws HttpRequestException
+ * @param accept
+ * @return this request
*/
- public Map> headers() throws HttpRequestException {
- closeOutputQuietly();
- return getConnection().getHeaderFields();
+ public HttpRequest accept(final String accept) {
+ return header(HEADER_ACCEPT, accept);
}
/**
- * Get a date header from the response falling back to returning -1 if the
- * header is missing or parsing fails
+ * Set the 'Accept' header to 'application/json'
*
- * @param name
- * @return date, -1 on failures
- * @throws HttpRequestException
+ * @return this request
*/
- public long dateHeader(final String name) throws HttpRequestException {
- return dateHeader(name, -1L);
+ public HttpRequest acceptJson() {
+ return accept(CONTENT_TYPE_JSON);
}
/**
- * Get a date header from the response falling back to returning the given
- * default value if the header is missing or parsing fails
+ * Copy from input stream to output stream
*
- * @param name
- * @param defaultValue
- * @return date, default value on failures
- * @throws HttpRequestException
+ * @param input
+ * @param output
+ * @return this request
+ * @throws IOException
*/
- public long dateHeader(final String name, final long defaultValue)
- throws HttpRequestException {
- closeOutputQuietly();
- return getConnection().getHeaderFieldDate(name, defaultValue);
+ protected HttpResponse copy(final InputStream input, final OutputStream output)
+ throws IOException {
+ return new CloseOperation(input, ignoreCloseExceptions) {
+
+ @Override
+ public HttpResponse run() throws IOException {
+ final byte[] buffer = new byte[bufferSize];
+ int read;
+ while ((read = input.read(buffer)) != -1) {
+ output.write(buffer, 0, read);
+ totalWritten += read;
+ progress.onUpload(totalWritten, totalSize);
+ }
+ return HttpRequest.this.httpResponse;
+ }
+ }.call();
}
/**
- * Get an integer header from the response falling back to returning -1 if the
- * header is missing or parsing fails
+ * Copy from reader to writer
*
- * @param name
- * @return header value as an integer, -1 when missing or parsing fails
- * @throws HttpRequestException
+ * @param input
+ * @param output
+ * @return this request
+ * @throws IOException
*/
- public int intHeader(final String name) throws HttpRequestException {
- return intHeader(name, -1);
+ protected HttpRequest copy(final Reader input, final Writer output)
+ throws IOException {
+ return new CloseOperation(input, ignoreCloseExceptions) {
+
+ @Override
+ public HttpRequest run() throws IOException {
+ final char[] buffer = new char[bufferSize];
+ int read;
+ while ((read = input.read(buffer)) != -1) {
+ output.write(buffer, 0, read);
+ totalWritten += read;
+ progress.onUpload(totalWritten, -1);
+ }
+ return HttpRequest.this;
+ }
+ }.call();
}
/**
- * Get an integer header value from the response falling back to the given
- * default value if the header is missing or if parsing fails
+ * Set the UploadProgress callback for this request
*
- * @param name
- * @param defaultValue
- * @return header value as an integer, default value when missing or parsing
- * fails
- * @throws HttpRequestException
+ * @param callback
+ * @return this request
*/
- public int intHeader(final String name, final int defaultValue)
- throws HttpRequestException {
- closeOutputQuietly();
- return getConnection().getHeaderFieldInt(name, defaultValue);
+ public HttpRequest progress(final UploadProgress callback) {
+ if (callback == null)
+ progress = UploadProgress.DEFAULT;
+ else
+ progress = callback;
+ return this;
+ }
+
+ private HttpRequest incrementTotalSize(final long size) {
+ if (totalSize == -1)
+ totalSize = 0;
+ totalSize += size;
+ return this;
}
+
+
+
/**
- * Get all values of the given header from the response
+ * Open output stream
*
- * @param name
- * @return non-null but possibly empty array of {@link String} header values
+ * @return this request
+ * @throws IOException
*/
- public String[] headers(final String name) {
- final Map> headers = headers();
- if (headers == null || headers.isEmpty())
- return EMPTY_STRINGS;
-
- final List values = headers.get(name);
- if (values != null && !values.isEmpty())
- return values.toArray(new String[values.size()]);
- else
- return EMPTY_STRINGS;
+ protected HttpRequest openOutput() throws IOException {
+ if (output != null)
+ return this;
+ getConnection().setDoOutput(true);
+ final String charset = getParam(
+ getConnection().getRequestProperty(HEADER_CONTENT_TYPE), PARAM_CHARSET);
+ output = new RequestOutputStream(getConnection().getOutputStream(), charset,
+ bufferSize);
+ return this;
}
/**
- * Get parameter with given name from header value in response
+ * Start part of a multipart
*
- * @param headerName
- * @param paramName
- * @return parameter value or null if missing
+ * @return this request
+ * @throws IOException
*/
- public String parameter(final String headerName, final String paramName) {
- return getParam(header(headerName), paramName);
+ protected HttpRequest startPart() throws IOException {
+ if (!multipart) {
+ multipart = true;
+ contentType(CONTENT_TYPE_MULTIPART).openOutput();
+ output.write("--" + BOUNDARY + CRLF);
+ } else
+ output.write(CRLF + "--" + BOUNDARY + CRLF);
+ return this;
}
/**
- * Get all parameters from header value in response
- *
- * This will be all key=value pairs after the first ';' that are separated by
- * a ';'
+ * Write part header
*
- * @param headerName
- * @return non-null but possibly empty map of parameter headers
+ * @param name
+ * @param filename
+ * @return this request
+ * @throws IOException
*/
- public Map parameters(final String headerName) {
- return getParams(header(headerName));
+ protected HttpRequest writePartHeader(final String name, final String filename)
+ throws IOException {
+ return writePartHeader(name, filename, null);
}
/**
- * Get parameter values from header value
+ * Write part header
*
- * @param header
- * @return parameter value or null if none
- */
- protected Map getParams(final String header) {
- if (header == null || header.length() == 0)
- return Collections.emptyMap();
-
- final int headerLength = header.length();
- int start = header.indexOf(';') + 1;
- if (start == 0 || start == headerLength)
- return Collections.emptyMap();
-
- int end = header.indexOf(';', start);
- if (end == -1)
- end = headerLength;
-
- Map params = new LinkedHashMap();
- while (start < end) {
- int nameEnd = header.indexOf('=', start);
- if (nameEnd != -1 && nameEnd < end) {
- String name = header.substring(start, nameEnd).trim();
- if (name.length() > 0) {
- String value = header.substring(nameEnd + 1, end).trim();
- int length = value.length();
- if (length != 0)
- if (length > 2 && '"' == value.charAt(0)
- && '"' == value.charAt(length - 1))
- params.put(name, value.substring(1, length - 1));
- else
- params.put(name, value);
- }
- }
-
- start = end + 1;
- end = header.indexOf(';', start);
- if (end == -1)
- end = headerLength;
- }
-
- return params;
- }
-
- /**
- * Get parameter value from header value
- *
- * @param value
- * @param paramName
- * @return parameter value or null if none
- */
- protected String getParam(final String value, final String paramName) {
- if (value == null || value.length() == 0)
- return null;
-
- final int length = value.length();
- int start = value.indexOf(';') + 1;
- if (start == 0 || start == length)
- return null;
-
- int end = value.indexOf(';', start);
- if (end == -1)
- end = length;
-
- while (start < end) {
- int nameEnd = value.indexOf('=', start);
- if (nameEnd != -1 && nameEnd < end
- && paramName.equals(value.substring(start, nameEnd).trim())) {
- String paramValue = value.substring(nameEnd + 1, end).trim();
- int valueLength = paramValue.length();
- if (valueLength != 0)
- if (valueLength > 2 && '"' == paramValue.charAt(0)
- && '"' == paramValue.charAt(valueLength - 1))
- return paramValue.substring(1, valueLength - 1);
- else
- return paramValue;
- }
-
- start = end + 1;
- end = value.indexOf(';', start);
- if (end == -1)
- end = length;
- }
-
- return null;
- }
-
- /**
- * Get 'charset' parameter from 'Content-Type' response header
- *
- * @return charset or null if none
+ * @param name
+ * @param filename
+ * @param contentType
+ * @return this request
+ * @throws IOException
*/
- public String charset() {
- return parameter(HEADER_CONTENT_TYPE, PARAM_CHARSET);
+ protected HttpRequest writePartHeader(final String name,
+ final String filename, final String contentType) throws IOException {
+ final StringBuilder partBuffer = new StringBuilder();
+ partBuffer.append("form-data; name=\"").append(name);
+ if (filename != null)
+ partBuffer.append("\"; filename=\"").append(filename);
+ partBuffer.append('"');
+ partHeader("Content-Disposition", partBuffer.toString());
+ if (contentType != null)
+ partHeader(HEADER_CONTENT_TYPE, contentType);
+ return send(CRLF);
}
/**
- * Set the 'User-Agent' header to given value
+ * Write part of a multipart request to the request body
*
- * @param userAgent
+ * @param name
+ * @param part
* @return this request
*/
- public HttpRequest userAgent(final String userAgent) {
- return header(HEADER_USER_AGENT, userAgent);
+ public HttpRequest part(final String name, final String part) {
+ return part(name, null, part);
}
/**
- * Set the 'Referer' header to given value
+ * Write part of a multipart request to the request body
*
- * @param referer
+ * @param name
+ * @param filename
+ * @param part
* @return this request
+ * @throws HttpRequestException
*/
- public HttpRequest referer(final String referer) {
- return header(HEADER_REFERER, referer);
+ public HttpRequest part(final String name, final String filename,
+ final String part) throws HttpRequestException {
+ return part(name, filename, null, part);
}
/**
- * Set value of {@link HttpURLConnection#setUseCaches(boolean)}
+ * Write part of a multipart request to the request body
*
- * @param useCaches
+ * @param name
+ * @param filename
+ * @param contentType
+ * value of the Content-Type part header
+ * @param part
* @return this request
+ * @throws HttpRequestException
*/
- public HttpRequest useCaches(final boolean useCaches) {
- getConnection().setUseCaches(useCaches);
+ public HttpRequest part(final String name, final String filename,
+ final String contentType, final String part) throws HttpRequestException {
+ try {
+ startPart();
+ writePartHeader(name, filename, contentType);
+ output.write(part);
+ } catch (IOException e) {
+ throw new HttpRequestException(e);
+ }
return this;
}
/**
- * Set the 'Accept-Encoding' header to given value
+ * Write part of a multipart request to the request body
*
- * @param acceptEncoding
+ * @param name
+ * @param part
* @return this request
+ * @throws HttpRequestException
*/
- public HttpRequest acceptEncoding(final String acceptEncoding) {
- return header(HEADER_ACCEPT_ENCODING, acceptEncoding);
+ public HttpRequest part(final String name, final Number part)
+ throws HttpRequestException {
+ return part(name, null, part);
}
/**
- * Set the 'Accept-Encoding' header to 'gzip'
+ * Write part of a multipart request to the request body
*
- * @see #uncompress(boolean)
+ * @param name
+ * @param filename
+ * @param part
* @return this request
+ * @throws HttpRequestException
*/
- public HttpRequest acceptGzipEncoding() {
- return acceptEncoding(ENCODING_GZIP);
+ public HttpRequest part(final String name, final String filename,
+ final Number part) throws HttpRequestException {
+ return part(name, filename, part != null ? part.toString() : null);
}
/**
- * Set the 'Accept-Charset' header to given value
+ * Write part of a multipart request to the request body
*
- * @param acceptCharset
+ * @param name
+ * @param part
* @return this request
+ * @throws HttpRequestException
*/
- public HttpRequest acceptCharset(final String acceptCharset) {
- return header(HEADER_ACCEPT_CHARSET, acceptCharset);
+ public HttpRequest part(final String name, final File part)
+ throws HttpRequestException {
+ return part(name, null, part);
}
/**
- * Get the 'Content-Encoding' header from the response
+ * Write part of a multipart request to the request body
*
+ * @param name
+ * @param filename
+ * @param part
* @return this request
+ * @throws HttpRequestException
*/
- public String contentEncoding() {
- return header(HEADER_CONTENT_ENCODING);
+ public HttpRequest part(final String name, final String filename,
+ final File part) throws HttpRequestException {
+ return part(name, filename, null, part);
}
/**
- * Get the 'Server' header from the response
+ * Write part of a multipart request to the request body
*
- * @return server
+ * @param name
+ * @param filename
+ * @param contentType
+ * value of the Content-Type part header
+ * @param part
+ * @return this request
+ * @throws HttpRequestException
*/
- public String server() {
- return header(HEADER_SERVER);
+ public HttpRequest part(final String name, final String filename,
+ final String contentType, final File part) throws HttpRequestException {
+ final InputStream stream;
+ try {
+ stream = new BufferedInputStream(new FileInputStream(part));
+ incrementTotalSize(part.length());
+ } catch (IOException e) {
+ throw new HttpRequestException(e);
+ }
+ return part(name, filename, contentType, stream);
}
/**
- * Get the 'Date' header from the response
+ * Write part of a multipart request to the request body
*
- * @return date value, -1 on failures
+ * @param name
+ * @param part
+ * @return this request
+ * @throws HttpRequestException
*/
- public long date() {
- return dateHeader(HEADER_DATE);
+ public HttpRequest part(final String name, final InputStream part)
+ throws HttpRequestException {
+ return part(name, null, null, part);
}
/**
- * Get the 'Cache-Control' header from the response
+ * Write part of a multipart request to the request body
*
- * @return cache control
+ * @param name
+ * @param filename
+ * @param contentType
+ * value of the Content-Type part header
+ * @param part
+ * @return this request
+ * @throws HttpRequestException
*/
- public String cacheControl() {
- return header(HEADER_CACHE_CONTROL);
+ public HttpRequest part(final String name, final String filename,
+ final String contentType, final InputStream part)
+ throws HttpRequestException {
+ try {
+ startPart();
+ writePartHeader(name, filename, contentType);
+ copy(part, output);
+ } catch (IOException e) {
+ throw new HttpRequestException(e);
+ }
+ return this;
}
/**
- * Get the 'ETag' header from the response
+ * Write a multipart header to the response body
*
- * @return entity tag
+ * @param name
+ * @param value
+ * @return this request
+ * @throws HttpRequestException
*/
- public String eTag() {
- return header(HEADER_ETAG);
+ public HttpRequest partHeader(final String name, final String value)
+ throws HttpRequestException {
+ return send(name).send(": ").send(value).send(CRLF);
}
/**
- * Get the 'Expires' header from the response
+ * Write contents of file to request body
*
- * @return expires value, -1 on failures
+ * @param input
+ * @return this request
+ * @throws HttpRequestException
*/
- public long expires() {
- return dateHeader(HEADER_EXPIRES);
+ public HttpRequest send(final File input) throws HttpRequestException {
+ final InputStream stream;
+ try {
+ stream = new BufferedInputStream(new FileInputStream(input));
+ incrementTotalSize(input.length());
+ } catch (FileNotFoundException e) {
+ throw new HttpRequestException(e);
+ }
+ return send(stream);
}
/**
- * Get the 'Last-Modified' header from the response
+ * Write byte array to request body
*
- * @return last modified value, -1 on failures
+ * @param input
+ * @return this request
+ * @throws HttpRequestException
*/
- public long lastModified() {
- return dateHeader(HEADER_LAST_MODIFIED);
+ public HttpRequest send(final byte[] input) throws HttpRequestException {
+ if (input != null)
+ incrementTotalSize(input.length);
+ return send(new ByteArrayInputStream(input));
}
/**
- * Get the 'Location' header from the response
- *
- * @return location
- */
- public String location() {
- return header(HEADER_LOCATION);
- }
-
- /**
- * Set the 'Authorization' header to given value
+ * Write stream to request body
+ *
+ * The given stream will be closed once sending completes
*
- * @param authorization
+ * @param input
* @return this request
+ * @throws HttpRequestException
*/
- public HttpRequest authorization(final String authorization) {
- return header(HEADER_AUTHORIZATION, authorization);
+ public HttpRequest send(final InputStream input) throws HttpRequestException {
+ try {
+ openOutput();
+ copy(input, output);
+ } catch (IOException e) {
+ throw new HttpRequestException(e);
+ }
+ return this;
}
/**
- * Set the 'Proxy-Authorization' header to given value
+ * Write reader to request body
+ *
+ * The given reader will be closed once sending completes
*
- * @param proxyAuthorization
+ * @param input
* @return this request
+ * @throws HttpRequestException
*/
- public HttpRequest proxyAuthorization(final String proxyAuthorization) {
- return header(HEADER_PROXY_AUTHORIZATION, proxyAuthorization);
+ public HttpRequest send(final Reader input) throws HttpRequestException {
+ try {
+ openOutput();
+ } catch (IOException e) {
+ throw new HttpRequestException(e);
+ }
+ final Writer writer = new OutputStreamWriter(output,
+ output.encoder.charset());
+ return new FlushOperation(writer) {
+
+ @Override
+ protected HttpRequest run() throws IOException {
+ return copy(input, writer);
+ }
+ }.call();
}
/**
- * Set the 'Authorization' header to given values in Basic authentication
- * format
+ * Write char sequence to request body
+ *
+ * The charset configured via {@link #contentType(String)} will be used and
+ * UTF-8 will be used if it is unset.
*
- * @param name
- * @param password
+ * @param value
* @return this request
+ * @throws HttpRequestException
*/
- public HttpRequest basic(final String name, final String password) {
- return authorization("Basic " + Base64.encode(name + ':' + password));
+ public HttpRequest send(final CharSequence value) throws HttpRequestException {
+ try {
+ openOutput();
+ output.write(value.toString());
+ } catch (IOException e) {
+ throw new HttpRequestException(e);
+ }
+ return this;
}
/**
- * Set the 'Proxy-Authorization' header to given values in Basic authentication
- * format
+ * Create writer to request output stream
*
- * @param name
- * @param password
- * @return this request
+ * @return writer
+ * @throws HttpRequestException
*/
- public HttpRequest proxyBasic(final String name, final String password) {
- return proxyAuthorization("Basic " + Base64.encode(name + ':' + password));
+ public OutputStreamWriter writer() throws HttpRequestException {
+ try {
+ openOutput();
+ return new OutputStreamWriter(output, output.encoder.charset());
+ } catch (IOException e) {
+ throw new HttpRequestException(e);
+ }
}
/**
- * Set the 'If-Modified-Since' request header to the given value
+ * Write the values in the map as form data to the request body
+ *
+ * The pairs specified will be URL-encoded in UTF-8 and sent with the
+ * 'application/x-www-form-urlencoded' content-type
*
- * @param ifModifiedSince
+ * @param values
* @return this request
+ * @throws HttpRequestException
*/
- public HttpRequest ifModifiedSince(final long ifModifiedSince) {
- getConnection().setIfModifiedSince(ifModifiedSince);
- return this;
+ public HttpRequest form(final Map, ?> values) throws HttpRequestException {
+ return form(values, CHARSET_UTF8);
}
/**
- * Set the 'If-None-Match' request header to the given value
+ * Write the key and value in the entry as form data to the request body
+ *
+ * The pair specified will be URL-encoded in UTF-8 and sent with the
+ * 'application/x-www-form-urlencoded' content-type
*
- * @param ifNoneMatch
+ * @param entry
* @return this request
+ * @throws HttpRequestException
*/
- public HttpRequest ifNoneMatch(final String ifNoneMatch) {
- return header(HEADER_IF_NONE_MATCH, ifNoneMatch);
+ public HttpRequest form(final Entry, ?> entry) throws HttpRequestException {
+ return form(entry, CHARSET_UTF8);
}
/**
- * Set the 'Content-Type' request header to the given value
+ * Write the key and value in the entry as form data to the request body
+ *
+ * The pair specified will be URL-encoded and sent with the
+ * 'application/x-www-form-urlencoded' content-type
*
- * @param contentType
+ * @param entry
+ * @param charset
* @return this request
+ * @throws HttpRequestException
*/
- public HttpRequest contentType(final String contentType) {
- return contentType(contentType, null);
+ public HttpRequest form(final Entry, ?> entry, final String charset)
+ throws HttpRequestException {
+ return form(entry.getKey(), entry.getValue(), charset);
}
/**
- * Set the 'Content-Type' request header to the given value and charset
+ * Write the name/value pair as form data to the request body
+ *
+ * The pair specified will be URL-encoded in UTF-8 and sent with the
+ * 'application/x-www-form-urlencoded' content-type
*
- * @param contentType
- * @param charset
+ * @param name
+ * @param value
* @return this request
+ * @throws HttpRequestException
*/
- public HttpRequest contentType(final String contentType, final String charset) {
- if (charset != null && charset.length() > 0) {
- final String separator = "; " + PARAM_CHARSET + '=';
- return header(HEADER_CONTENT_TYPE, contentType + separator + charset);
- } else
- return header(HEADER_CONTENT_TYPE, contentType);
+ public HttpRequest form(final Object name, final Object value)
+ throws HttpRequestException {
+ return form(name, value, CHARSET_UTF8);
}
/**
- * Get the 'Content-Type' header from the response
+ * Write the name/value pair as form data to the request body
+ *
+ * The values specified will be URL-encoded and sent with the
+ * 'application/x-www-form-urlencoded' content-type
*
- * @return response header value
+ * @param name
+ * @param value
+ * @param charset
+ * @return this request
+ * @throws HttpRequestException
*/
- public String contentType() {
- return header(HEADER_CONTENT_TYPE);
+ public HttpRequest form(final Object name, final Object value, String charset)
+ throws HttpRequestException {
+ final boolean first = !form;
+ if (first) {
+ contentType(CONTENT_TYPE_FORM, charset);
+ form = true;
+ }
+ charset = getValidCharset(charset);
+ try {
+ openOutput();
+ if (!first)
+ output.write('&');
+ output.write(URLEncoder.encode(name.toString(), charset));
+ output.write('=');
+ if (value != null)
+ output.write(URLEncoder.encode(value.toString(), charset));
+ } catch (IOException e) {
+ throw new HttpRequestException(e);
+ }
+ return this;
}
/**
- * Get the 'Content-Length' header from the response
+ * Write the values in the map as encoded form data to the request body
*
- * @return response header value
+ * @param values
+ * @param charset
+ * @return this request
+ * @throws HttpRequestException
*/
- public int contentLength() {
- return intHeader(HEADER_CONTENT_LENGTH);
+ public HttpRequest form(final Map, ?> values, final String charset)
+ throws HttpRequestException {
+ if (!values.isEmpty())
+ for (Entry, ?> entry : values.entrySet())
+ form(entry, charset);
+ return this;
}
/**
- * Set the 'Content-Length' request header to the given value
+ * Configure HTTPS connection to trust all certificates
+ *
+ * This method does nothing if the current request is not a HTTPS request
*
- * @param contentLength
* @return this request
+ * @throws HttpRequestException
*/
- public HttpRequest contentLength(final String contentLength) {
- return contentLength(Integer.parseInt(contentLength));
+ public HttpRequest trustAllCerts() throws HttpRequestException {
+ final HttpURLConnection connection = getConnection();
+ if (connection instanceof HttpsURLConnection)
+ ((HttpsURLConnection) connection)
+ .setSSLSocketFactory(getTrustedFactory());
+ return this;
}
/**
- * Set the 'Content-Length' request header to the given value
+ * Configure HTTPS connection to trust all hosts using a custom
+ * {@link HostnameVerifier} that always returns true
for each
+ * host verified
+ *
+ * This method does nothing if the current request is not a HTTPS request
*
- * @param contentLength
* @return this request
*/
- public HttpRequest contentLength(final int contentLength) {
- getConnection().setFixedLengthStreamingMode(contentLength);
+ public HttpRequest trustAllHosts() {
+ final HttpURLConnection connection = getConnection();
+ if (connection instanceof HttpsURLConnection)
+ ((HttpsURLConnection) connection)
+ .setHostnameVerifier(getTrustedVerifier());
return this;
}
/**
- * Set the 'Accept' header to given value
+ * Get the {@link URL} of this request's connection
*
- * @param accept
- * @return this request
+ * @return request URL
*/
- public HttpRequest accept(final String accept) {
- return header(HEADER_ACCEPT, accept);
+ public URL url() {
+ return getConnection().getURL();
}
/**
- * Set the 'Accept' header to 'application/json'
+ * Get the HTTP method of this request
*
- * @return this request
+ * @return method
*/
- public HttpRequest acceptJson() {
- return accept(CONTENT_TYPE_JSON);
+ public String method() {
+ return getConnection().getRequestMethod();
}
/**
- * Copy from input stream to output stream
+ * Configure an HTTP proxy on this connection. Use {{@link #proxyBasic(String, String)} if
+ * this proxy requires basic authentication.
*
- * @param input
- * @param output
+ * @param proxyHost
+ * @param proxyPort
* @return this request
- * @throws IOException
*/
- protected HttpRequest copy(final InputStream input, final OutputStream output)
- throws IOException {
- return new CloseOperation(input, ignoreCloseExceptions) {
+ public HttpRequest useProxy(final String proxyHost, final int proxyPort) {
+ if (connection != null)
+ throw new IllegalStateException("The connection has already been created. This method must be called before reading or writing to the request.");
- @Override
- public HttpRequest run() throws IOException {
- final byte[] buffer = new byte[bufferSize];
- int read;
- while ((read = input.read(buffer)) != -1) {
- output.write(buffer, 0, read);
- totalWritten += read;
- progress.onUpload(totalWritten, totalSize);
- }
- return HttpRequest.this;
- }
- }.call();
+ this.httpProxyHost = proxyHost;
+ this.httpProxyPort = proxyPort;
+ return this;
}
/**
- * Copy from reader to writer
+ * Set whether or not the underlying connection should follow redirects in
+ * the response.
*
- * @param input
- * @param output
+ * @param followRedirects - true fo follow redirects, false to not.
* @return this request
- * @throws IOException
*/
- protected HttpRequest copy(final Reader input, final Writer output)
- throws IOException {
- return new CloseOperation(input, ignoreCloseExceptions) {
-
- @Override
- public HttpRequest run() throws IOException {
- final char[] buffer = new char[bufferSize];
- int read;
- while ((read = input.read(buffer)) != -1) {
- output.write(buffer, 0, read);
- totalWritten += read;
- progress.onUpload(totalWritten, -1);
- }
- return HttpRequest.this;
- }
- }.call();
+ public HttpRequest followRedirects(final boolean followRedirects) {
+ getConnection().setInstanceFollowRedirects(followRedirects);
+ return this;
}
- /**
- * Set the UploadProgress callback for this request
- *
- * @param callback
- * @return this request
- */
- public HttpRequest progress(final UploadProgress callback) {
- if (callback == null)
- progress = UploadProgress.DEFAULT;
- else
- progress = callback;
- return this;
+ private void setDefaultTimeOut() {
+ getConnection().setConnectTimeout(DEFAULT_CONNECT_TIMEOUT);
+ getConnection().setReadTimeout(DEFAULT_READ_TIMEOUT);
}
- private HttpRequest incrementTotalSize(final long size) {
- if (totalSize == -1)
- totalSize = 0;
- totalSize += size;
+ public HttpRequest defaultTimeOut() {
+ this.defaultTimeOutFlag = true;
return this;
}
-
/**
- * Close output stream
*
- * @return this request
- * @throws HttpRequestException
- * @throws IOException
+ * HttpResponse collects the http response info and make the responsibility clearly(HttpRequest for request,HttpResponse for response)
+ *
*/
- protected HttpRequest closeOutput() throws IOException {
- progress(null);
- if (output == null)
- return this;
- if (multipart)
- output.write(CRLF + "--" + BOUNDARY + "--" + CRLF);
- if (ignoreCloseExceptions)
+ public class HttpResponse{
+
+ /**
+ * Get the status code of the response
+ *
+ * @return the response code
+ * @throws HttpRequestException
+ */
+ public int code() throws HttpRequestException {
try {
- output.close();
- } catch (IOException ignored) {
- // Ignored
+ closeOutput();
+ return getConnection().getResponseCode();
+ } catch (IOException e) {
+ throw new HttpRequestException(e);
}
- else
- output.close();
- output = null;
- return this;
- }
+ }
- /**
- * Call {@link #closeOutput()} and re-throw a caught {@link IOException}s as
- * an {@link HttpRequestException}
- *
- * @return this request
- * @throws HttpRequestException
- */
- protected HttpRequest closeOutputQuietly() throws HttpRequestException {
- try {
- return closeOutput();
- } catch (IOException e) {
- throw new HttpRequestException(e);
+ /**
+ * Close output stream
+ *
+ * @return this response
+ * @throws HttpRequestException
+ * @throws IOException
+ */
+ protected HttpResponse closeOutput() throws IOException {
+ progress(null);
+ if (output == null)
+ return this;
+ if (multipart)
+ output.write(CRLF + "--" + BOUNDARY + "--" + CRLF);
+ if (ignoreCloseExceptions)
+ try {
+ output.close();
+ } catch (IOException ignored) {
+ // Ignored
+ }
+ else
+ output.close();
+ output = null;
+ return this;
}
- }
- /**
- * Open output stream
- *
- * @return this request
- * @throws IOException
- */
- protected HttpRequest openOutput() throws IOException {
- if (output != null)
+ /**
+ * Set the value of the given {@link AtomicInteger} to the status code of the
+ * response
+ *
+ * @param output
+ * @return this response
+ * @throws HttpRequestException
+ */
+ public HttpResponse code(final AtomicInteger output)
+ throws HttpRequestException {
+ output.set(code());
return this;
- getConnection().setDoOutput(true);
- final String charset = getParam(
- getConnection().getRequestProperty(HEADER_CONTENT_TYPE), PARAM_CHARSET);
- output = new RequestOutputStream(getConnection().getOutputStream(), charset,
- bufferSize);
- return this;
- }
+ }
- /**
- * Start part of a multipart
- *
- * @return this request
- * @throws IOException
- */
- protected HttpRequest startPart() throws IOException {
- if (!multipart) {
- multipart = true;
- contentType(CONTENT_TYPE_MULTIPART).openOutput();
- output.write("--" + BOUNDARY + CRLF);
- } else
- output.write(CRLF + "--" + BOUNDARY + CRLF);
- return this;
- }
+ /**
+ * Call {@link #closeOutput()} and re-throw a caught {@link IOException}s as
+ * an {@link HttpRequestException}
+ *
+ * @return this response
+ * @throws HttpRequestException
+ */
+ protected HttpResponse closeOutputQuietly() throws HttpRequestException {
+ try {
+ return closeOutput();
+ } catch (IOException e) {
+ throw new HttpRequestException(e);
+ }
+ }
- /**
- * Write part header
- *
- * @param name
- * @param filename
- * @return this request
- * @throws IOException
- */
- protected HttpRequest writePartHeader(final String name, final String filename)
- throws IOException {
- return writePartHeader(name, filename, null);
- }
+ /**
+ * Is the response code a 200 OK?
+ *
+ * @return true if 200, false otherwise
+ * @throws HttpRequestException
+ */
+ public boolean ok() throws HttpRequestException {
+ return HTTP_OK == code();
+ }
- /**
- * Write part header
- *
- * @param name
- * @param filename
- * @param contentType
- * @return this request
- * @throws IOException
- */
- protected HttpRequest writePartHeader(final String name,
- final String filename, final String contentType) throws IOException {
- final StringBuilder partBuffer = new StringBuilder();
- partBuffer.append("form-data; name=\"").append(name);
- if (filename != null)
- partBuffer.append("\"; filename=\"").append(filename);
- partBuffer.append('"');
- partHeader("Content-Disposition", partBuffer.toString());
- if (contentType != null)
- partHeader(HEADER_CONTENT_TYPE, contentType);
- return send(CRLF);
- }
- /**
- * Write part of a multipart request to the request body
- *
- * @param name
- * @param part
- * @return this request
- */
- public HttpRequest part(final String name, final String part) {
- return part(name, null, part);
- }
+ /**
+ * Is the response code a 201 Created?
+ *
+ * @return true if 201, false otherwise
+ * @throws HttpRequestException
+ */
+ public boolean created() throws HttpRequestException {
+ return HTTP_CREATED == code();
+ }
- /**
- * Write part of a multipart request to the request body
- *
- * @param name
- * @param filename
- * @param part
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest part(final String name, final String filename,
- final String part) throws HttpRequestException {
- return part(name, filename, null, part);
- }
+ /**
+ * Is the response code a 204 No Content?
+ *
+ * @return true if 204, false otherwise
+ * @throws HttpRequestException
+ */
+ public boolean noContent() throws HttpRequestException {
+ return HTTP_NO_CONTENT == code();
+ }
- /**
- * Write part of a multipart request to the request body
- *
- * @param name
- * @param filename
- * @param contentType
- * value of the Content-Type part header
- * @param part
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest part(final String name, final String filename,
- final String contentType, final String part) throws HttpRequestException {
- try {
- startPart();
- writePartHeader(name, filename, contentType);
- output.write(part);
- } catch (IOException e) {
- throw new HttpRequestException(e);
+ /**
+ * Is the response code a 500 Internal Server Error?
+ *
+ * @return true if 500, false otherwise
+ * @throws HttpRequestException
+ */
+ public boolean serverError() throws HttpRequestException {
+ return HTTP_INTERNAL_ERROR == code();
}
- return this;
- }
- /**
- * Write part of a multipart request to the request body
- *
- * @param name
- * @param part
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest part(final String name, final Number part)
- throws HttpRequestException {
- return part(name, null, part);
- }
+ /**
+ * Is the response code a 400 Bad Request?
+ *
+ * @return true if 400, false otherwise
+ * @throws HttpRequestException
+ */
+ public boolean badRequest() throws HttpRequestException {
+ return HTTP_BAD_REQUEST == code();
+ }
- /**
- * Write part of a multipart request to the request body
- *
- * @param name
- * @param filename
- * @param part
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest part(final String name, final String filename,
- final Number part) throws HttpRequestException {
- return part(name, filename, part != null ? part.toString() : null);
- }
+ /**
+ * Is the response code a 404 Not Found?
+ *
+ * @return true if 404, false otherwise
+ * @throws HttpRequestException
+ */
+ public boolean notFound() throws HttpRequestException {
+ return HTTP_NOT_FOUND == code();
+ }
- /**
- * Write part of a multipart request to the request body
- *
- * @param name
- * @param part
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest part(final String name, final File part)
- throws HttpRequestException {
- return part(name, null, part);
- }
+ /**
+ * Is the response code a 304 Not Modified?
+ *
+ * @return true if 304, false otherwise
+ * @throws HttpRequestException
+ */
+ public boolean notModified() throws HttpRequestException {
+ return HTTP_NOT_MODIFIED == code();
+ }
- /**
- * Write part of a multipart request to the request body
- *
- * @param name
- * @param filename
- * @param part
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest part(final String name, final String filename,
- final File part) throws HttpRequestException {
- return part(name, filename, null, part);
- }
+ /**
+ * Get status message of the response
+ *
+ * @return message
+ * @throws HttpRequestException
+ */
+ public String message() throws HttpRequestException {
+ try {
+ closeOutput();
+ return getConnection().getResponseMessage();
+ } catch (IOException e) {
+ throw new HttpRequestException(e);
+ }
+ }
- /**
- * Write part of a multipart request to the request body
- *
- * @param name
- * @param filename
- * @param contentType
- * value of the Content-Type part header
- * @param part
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest part(final String name, final String filename,
- final String contentType, final File part) throws HttpRequestException {
- final InputStream stream;
- try {
- stream = new BufferedInputStream(new FileInputStream(part));
- incrementTotalSize(part.length());
- } catch (IOException e) {
- throw new HttpRequestException(e);
+
+ /**
+ * Get response as {@link String} in given character set
+ *
+ * This will fall back to using the UTF-8 character set if the given charset
+ * is null
+ *
+ * @param charset
+ * @return string
+ * @throws HttpRequestException
+ */
+ public String body(final String charset) throws HttpRequestException {
+ final ByteArrayOutputStream output = byteStream();
+ try {
+ copy(buffer(), output);
+ return output.toString(getValidCharset(charset));
+ } catch (IOException e) {
+ throw new HttpRequestException(e);
+ }
}
- return part(name, filename, contentType, stream);
- }
- /**
- * Write part of a multipart request to the request body
- *
- * @param name
- * @param part
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest part(final String name, final InputStream part)
- throws HttpRequestException {
- return part(name, null, null, part);
- }
+ /**
+ * Get response as {@link String} using character set returned from
+ * {@link #charset()}
+ *
+ * @return string
+ * @throws HttpRequestException
+ */
+ public String body() throws HttpRequestException {
+ return body(charset());
+ }
- /**
- * Write part of a multipart request to the request body
- *
- * @param name
- * @param filename
- * @param contentType
- * value of the Content-Type part header
- * @param part
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest part(final String name, final String filename,
- final String contentType, final InputStream part)
- throws HttpRequestException {
- try {
- startPart();
- writePartHeader(name, filename, contentType);
- copy(part, output);
- } catch (IOException e) {
- throw new HttpRequestException(e);
+ /**
+ * Get the response body as a {@link String} and set it as the value of the
+ * given reference.
+ *
+ * @param output
+ * @return this response
+ * @throws HttpRequestException
+ */
+ public HttpResponse body(final AtomicReference output) throws HttpRequestException {
+ output.set(body());
+ return this;
}
- return this;
- }
- /**
- * Write a multipart header to the response body
- *
- * @param name
- * @param value
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest partHeader(final String name, final String value)
- throws HttpRequestException {
- return send(name).send(": ").send(value).send(CRLF);
- }
+ /**
+ * Get the response body as a {@link String} and set it as the value of the
+ * given reference.
+ *
+ * @param output
+ * @param charset
+ * @return this response
+ * @throws HttpRequestException
+ */
+ public HttpResponse body(final AtomicReference output, final String charset) throws HttpRequestException {
+ output.set(body(charset));
+ return this;
+ }
- /**
- * Write contents of file to request body
- *
- * @param input
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest send(final File input) throws HttpRequestException {
- final InputStream stream;
- try {
- stream = new BufferedInputStream(new FileInputStream(input));
- incrementTotalSize(input.length());
- } catch (FileNotFoundException e) {
- throw new HttpRequestException(e);
+
+ /**
+ * Is the response body empty?
+ *
+ * @return true if the Content-Length response header is 0, false otherwise
+ * @throws HttpRequestException
+ */
+ public boolean isBodyEmpty() throws HttpRequestException {
+ return contentLength() == 0;
}
- return send(stream);
- }
- /**
- * Write byte array to request body
- *
- * @param input
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest send(final byte[] input) throws HttpRequestException {
- if (input != null)
- incrementTotalSize(input.length);
- return send(new ByteArrayInputStream(input));
- }
+ /**
+ * Get response as byte array
+ *
+ * @return byte array
+ * @throws HttpRequestException
+ */
+ public byte[] bytes() throws HttpRequestException {
+ final ByteArrayOutputStream output = byteStream();
+ try {
+ copy(buffer(), output);
+ } catch (IOException e) {
+ throw new HttpRequestException(e);
+ }
+ return output.toByteArray();
+ }
- /**
- * Write stream to request body
- *
- * The given stream will be closed once sending completes
- *
- * @param input
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest send(final InputStream input) throws HttpRequestException {
- try {
- openOutput();
- copy(input, output);
- } catch (IOException e) {
- throw new HttpRequestException(e);
+ /**
+ * Get response in a buffered stream
+ *
+ * @see #bufferSize(int)
+ * @return stream
+ * @throws HttpRequestException
+ */
+ public BufferedInputStream buffer() throws HttpRequestException {
+ return new BufferedInputStream(stream(), bufferSize);
+ }
+ /**
+ * Get a response header
+ *
+ * @param name
+ * @return response header
+ * @throws HttpRequestException
+ */
+ public String header(final String name) throws HttpRequestException {
+ closeOutputQuietly();
+ return getConnection().getHeaderField(name);
}
- return this;
- }
- /**
- * Write reader to request body
- *
- * The given reader will be closed once sending completes
- *
- * @param input
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest send(final Reader input) throws HttpRequestException {
- try {
- openOutput();
- } catch (IOException e) {
- throw new HttpRequestException(e);
+ /**
+ * Get all the response headers
+ *
+ * @return map of response header names to their value(s)
+ * @throws HttpRequestException
+ */
+ public Map> headers() throws HttpRequestException {
+ closeOutputQuietly();
+ return getConnection().getHeaderFields();
}
- final Writer writer = new OutputStreamWriter(output,
- output.encoder.charset());
- return new FlushOperation(writer) {
- @Override
- protected HttpRequest run() throws IOException {
- return copy(input, writer);
- }
- }.call();
- }
+ /**
+ * Get a date header from the response falling back to returning -1 if the
+ * header is missing or parsing fails
+ *
+ * @param name
+ * @return date, -1 on failures
+ * @throws HttpRequestException
+ */
+ public long dateHeader(final String name) throws HttpRequestException {
+ return dateHeader(name, -1L);
+ }
- /**
- * Write char sequence to request body
- *
- * The charset configured via {@link #contentType(String)} will be used and
- * UTF-8 will be used if it is unset.
- *
- * @param value
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest send(final CharSequence value) throws HttpRequestException {
- try {
- openOutput();
- output.write(value.toString());
- } catch (IOException e) {
- throw new HttpRequestException(e);
+ /**
+ * Get a date header from the response falling back to returning the given
+ * default value if the header is missing or parsing fails
+ *
+ * @param name
+ * @param defaultValue
+ * @return date, default value on failures
+ * @throws HttpRequestException
+ */
+ public long dateHeader(final String name, final long defaultValue)
+ throws HttpRequestException {
+ closeOutputQuietly();
+ return getConnection().getHeaderFieldDate(name, defaultValue);
}
- return this;
- }
- /**
- * Create writer to request output stream
- *
- * @return writer
- * @throws HttpRequestException
- */
- public OutputStreamWriter writer() throws HttpRequestException {
- try {
- openOutput();
- return new OutputStreamWriter(output, output.encoder.charset());
- } catch (IOException e) {
- throw new HttpRequestException(e);
+
+ /**
+ * Get the 'Content-Encoding' header from the response
+ *
+ * @return this request
+ */
+ public String contentEncoding() {
+ return header(HEADER_CONTENT_ENCODING);
+ }
+
+ /**
+ * Get the 'Server' header from the response
+ *
+ * @return server
+ */
+ public String server() {
+ return header(HEADER_SERVER);
+ }
+
+ /**
+ * Get the 'Date' header from the response
+ *
+ * @return date value, -1 on failures
+ */
+ public long date() {
+ return dateHeader(HEADER_DATE);
+ }
+
+ /**
+ * Get the 'Cache-Control' header from the response
+ *
+ * @return cache control
+ */
+ public String cacheControl() {
+ return header(HEADER_CACHE_CONTROL);
+ }
+
+ /**
+ * Get the 'ETag' header from the response
+ *
+ * @return entity tag
+ */
+ public String eTag() {
+ return header(HEADER_ETAG);
+ }
+
+ /**
+ * Get the 'Expires' header from the response
+ *
+ * @return expires value, -1 on failures
+ */
+ public long expires() {
+ return dateHeader(HEADER_EXPIRES);
+ }
+
+ /**
+ * Get the 'Last-Modified' header from the response
+ *
+ * @return last modified value, -1 on failures
+ */
+ public long lastModified() {
+ return dateHeader(HEADER_LAST_MODIFIED);
+ }
+
+ /**
+ * Get the 'Location' header from the response
+ *
+ * @return location
+ */
+ public String location() {
+ return header(HEADER_LOCATION);
+ }
+
+ /**
+ * Get parameter with given name from header value in response
+ *
+ * @param headerName
+ * @param paramName
+ * @return parameter value or null if missing
+ */
+ public String parameter(final String headerName, final String paramName) {
+ return getParam(header(headerName), paramName);
+ }
+
+ /**
+ * Get all parameters from header value in response
+ *
+ * This will be all key=value pairs after the first ';' that are separated by
+ * a ';'
+ *
+ * @param headerName
+ * @return non-null but possibly empty map of parameter headers
+ */
+ public Map parameters(final String headerName) {
+ return getParams(header(headerName));
+ }
+
+ /**
+ * Get 'charset' parameter from 'Content-Type' response header
+ *
+ * @return charset or null if none
+ */
+ public String charset() {
+ return parameter(HEADER_CONTENT_TYPE, PARAM_CHARSET);
+ }
+
+ /**
+ * Get all values of the given header from the response
+ *
+ * @param name
+ * @return non-null but possibly empty array of {@link String} header values
+ */
+ public String[] headers(final String name) {
+ final Map> headers = headers();
+ if (headers == null || headers.isEmpty())
+ return EMPTY_STRINGS;
+
+ final List values = headers.get(name);
+ if (values != null && !values.isEmpty())
+ return values.toArray(new String[values.size()]);
+ else
+ return EMPTY_STRINGS;
+ }
+
+
+ /**
+ * Create byte array output stream
+ *
+ * @return stream
+ */
+ protected ByteArrayOutputStream byteStream() {
+ final int size = contentLength();
+ if (size > 0)
+ return new ByteArrayOutputStream(size);
+ else
+ return new ByteArrayOutputStream();
+ }
+
+ /**
+ * Get the 'Content-Length' header from the response
+ *
+ * @return response header value
+ */
+ public int contentLength() {
+ return intHeader(HEADER_CONTENT_LENGTH);
+ }
+
+ /**
+ * Get an integer header from the response falling back to returning -1 if the
+ * header is missing or parsing fails
+ *
+ * @param name
+ * @return header value as an integer, -1 when missing or parsing fails
+ * @throws HttpRequestException
+ */
+ public int intHeader(final String name) throws HttpRequestException {
+ return intHeader(name, -1);
}
- }
- /**
- * Write the values in the map as form data to the request body
- *
- * The pairs specified will be URL-encoded in UTF-8 and sent with the
- * 'application/x-www-form-urlencoded' content-type
- *
- * @param values
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest form(final Map, ?> values) throws HttpRequestException {
- return form(values, CHARSET_UTF8);
- }
+ /**
+ * Get an integer header value from the response falling back to the given
+ * default value if the header is missing or if parsing fails
+ *
+ * @param name
+ * @param defaultValue
+ * @return header value as an integer, default value when missing or parsing
+ * fails
+ * @throws HttpRequestException
+ */
+ public int intHeader(final String name, final int defaultValue)
+ throws HttpRequestException {
+ closeOutputQuietly();
+ return getConnection().getHeaderFieldInt(name, defaultValue);
+ }
- /**
- * Write the key and value in the entry as form data to the request body
- *
- * The pair specified will be URL-encoded in UTF-8 and sent with the
- * 'application/x-www-form-urlencoded' content-type
- *
- * @param entry
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest form(final Entry, ?> entry) throws HttpRequestException {
- return form(entry, CHARSET_UTF8);
- }
+ /**
+ * Get stream to response body
+ *
+ * @return stream
+ * @throws HttpRequestException
+ */
+ public InputStream stream() throws HttpRequestException {
+ if (defaultTimeOutFlag) {
+ setDefaultTimeOut();
+ }
+ InputStream stream;
+ if (code() < HTTP_BAD_REQUEST)
+ try {
+ stream = getConnection().getInputStream();
+ } catch (IOException e) {
+ throw new HttpRequestException(e);
+ }
+ else {
+ stream = getConnection().getErrorStream();
+ if (stream == null)
+ try {
+ stream = getConnection().getInputStream();
+ } catch (IOException e) {
+ if (contentLength() > 0)
+ throw new HttpRequestException(e);
+ else
+ stream = new ByteArrayInputStream(new byte[0]);
+ }
+ }
- /**
- * Write the key and value in the entry as form data to the request body
- *
- * The pair specified will be URL-encoded and sent with the
- * 'application/x-www-form-urlencoded' content-type
- *
- * @param entry
- * @param charset
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest form(final Entry, ?> entry, final String charset)
- throws HttpRequestException {
- return form(entry.getKey(), entry.getValue(), charset);
- }
+ if (!uncompress || !ENCODING_GZIP.equals(contentEncoding()))
+ return stream;
+ else
+ try {
+ return new GZIPInputStream(stream);
+ } catch (IOException e) {
+ throw new HttpRequestException(e);
+ }
+ }
- /**
- * Write the name/value pair as form data to the request body
- *
- * The pair specified will be URL-encoded in UTF-8 and sent with the
- * 'application/x-www-form-urlencoded' content-type
- *
- * @param name
- * @param value
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest form(final Object name, final Object value)
- throws HttpRequestException {
- return form(name, value, CHARSET_UTF8);
- }
- /**
- * Write the name/value pair as form data to the request body
- *
- * The values specified will be URL-encoded and sent with the
- * 'application/x-www-form-urlencoded' content-type
- *
- * @param name
- * @param value
- * @param charset
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest form(final Object name, final Object value, String charset)
- throws HttpRequestException {
- final boolean first = !form;
- if (first) {
- contentType(CONTENT_TYPE_FORM, charset);
- form = true;
+ /**
+ * Get reader to response body using given character set.
+ *
+ * This will fall back to using the UTF-8 character set if the given charset
+ * is null
+ *
+ * @param charset
+ * @return reader
+ * @throws HttpRequestException
+ */
+ public InputStreamReader reader(final String charset)
+ throws HttpRequestException {
+ try {
+ return new InputStreamReader(stream(), getValidCharset(charset));
+ } catch (UnsupportedEncodingException e) {
+ throw new HttpRequestException(e);
+ }
}
- charset = getValidCharset(charset);
- try {
- openOutput();
- if (!first)
- output.write('&');
- output.write(URLEncoder.encode(name.toString(), charset));
- output.write('=');
- if (value != null)
- output.write(URLEncoder.encode(value.toString(), charset));
- } catch (IOException e) {
- throw new HttpRequestException(e);
+
+ /**
+ * Get reader to response body using the character set returned from
+ * {@link #charset()}
+ *
+ * @return reader
+ * @throws HttpRequestException
+ */
+ public InputStreamReader reader() throws HttpRequestException {
+ return reader(charset());
}
- return this;
- }
- /**
- * Write the values in the map as encoded form data to the request body
- *
- * @param values
- * @param charset
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest form(final Map, ?> values, final String charset)
- throws HttpRequestException {
- if (!values.isEmpty())
- for (Entry, ?> entry : values.entrySet())
- form(entry, charset);
- return this;
- }
- /**
- * Configure HTTPS connection to trust all certificates
- *
- * This method does nothing if the current request is not a HTTPS request
- *
- * @return this request
- * @throws HttpRequestException
- */
- public HttpRequest trustAllCerts() throws HttpRequestException {
- final HttpURLConnection connection = getConnection();
- if (connection instanceof HttpsURLConnection)
- ((HttpsURLConnection) connection)
- .setSSLSocketFactory(getTrustedFactory());
- return this;
- }
+ /**
+ * Get buffered reader to response body using the given character set r and
+ * the configured buffer size
+ *
+ *
+ * @see #bufferSize(int)
+ * @param charset
+ * @return reader
+ * @throws HttpRequestException
+ */
+ public BufferedReader bufferedReader(final String charset)
+ throws HttpRequestException {
+ return new BufferedReader(reader(charset), bufferSize);
+ }
- /**
- * Configure HTTPS connection to trust all hosts using a custom
- * {@link HostnameVerifier} that always returns true
for each
- * host verified
- *
- * This method does nothing if the current request is not a HTTPS request
- *
- * @return this request
- */
- public HttpRequest trustAllHosts() {
- final HttpURLConnection connection = getConnection();
- if (connection instanceof HttpsURLConnection)
- ((HttpsURLConnection) connection)
- .setHostnameVerifier(getTrustedVerifier());
- return this;
- }
+ /**
+ * Get buffered reader to response body using the character set returned from
+ * {@link #charset()} and the configured buffer size
+ *
+ * @see #bufferSize(int)
+ * @return reader
+ * @throws HttpRequestException
+ */
+ public BufferedReader bufferedReader() throws HttpRequestException {
+ return bufferedReader(charset());
+ }
- /**
- * Get the {@link URL} of this request's connection
- *
- * @return request URL
- */
- public URL url() {
- return getConnection().getURL();
- }
+ /**
+ * Stream response body to file
+ *
+ * @param file
+ * @return this request
+ * @throws HttpRequestException
+ */
+ public HttpResponse receive(final File file) throws HttpRequestException {
+ final OutputStream output;
+ try {
+ output = new BufferedOutputStream(new FileOutputStream(file), bufferSize);
+ } catch (FileNotFoundException e) {
+ throw new HttpRequestException(e);
+ }
+ return new CloseOperation(output, ignoreCloseExceptions) {
- /**
- * Get the HTTP method of this request
- *
- * @return method
- */
- public String method() {
- return getConnection().getRequestMethod();
- }
+ @Override
+ protected HttpResponse run() throws HttpRequestException, IOException {
+ return receive(output);
+ }
+ }.call();
+ }
- /**
- * Configure an HTTP proxy on this connection. Use {{@link #proxyBasic(String, String)} if
- * this proxy requires basic authentication.
- *
- * @param proxyHost
- * @param proxyPort
- * @return this request
- */
- public HttpRequest useProxy(final String proxyHost, final int proxyPort) {
- if (connection != null)
- throw new IllegalStateException("The connection has already been created. This method must be called before reading or writing to the request.");
+ /**
+ * Stream response to given output stream
+ *
+ * @param output
+ * @return this request
+ * @throws HttpRequestException
+ */
+ public HttpResponse receive(final OutputStream output)
+ throws HttpRequestException {
+ try {
+ return copy(buffer(), output);
+ } catch (IOException e) {
+ throw new HttpRequestException(e);
+ }
+ }
- this.httpProxyHost = proxyHost;
- this.httpProxyPort = proxyPort;
- return this;
- }
+ /**
+ * Stream response to given print stream
+ *
+ * @param output
+ * @return this request
+ * @throws HttpRequestException
+ */
+ public HttpResponse receive(final PrintStream output)
+ throws HttpRequestException {
+ return receive((OutputStream) output);
+ }
+ /**
+ * Receive response into the given appendable
+ *
+ * @param appendable
+ * @return this request
+ * @throws HttpRequestException
+ */
+ public HttpResponse receive(final Appendable appendable)
+ throws HttpRequestException {
+ final BufferedReader reader = bufferedReader();
+ return new CloseOperation(reader, ignoreCloseExceptions) {
+
+ @Override
+ public HttpResponse run() throws IOException {
+ final CharBuffer buffer = CharBuffer.allocate(bufferSize);
+ int read;
+ while ((read = reader.read(buffer)) != -1) {
+ buffer.rewind();
+ appendable.append(buffer, 0, read);
+ buffer.rewind();
+ }
+ return HttpRequest.this.httpResponse;
+ }
+ }.call();
+ }
+ }
/**
- * Set whether or not the underlying connection should follow redirects in
- * the response.
- *
- * @param followRedirects - true fo follow redirects, false to not.
- * @return this request
+ * this method is used to execute a http request and get a HttpResponse
+ * @return
*/
- public HttpRequest followRedirects(final boolean followRedirects) {
- getConnection().setInstanceFollowRedirects(followRedirects);
- return this;
+ public HttpResponse executeHttpRequest(){
+ if (httpResponse ==null) {
+ httpResponse = new HttpResponse();
+ }
+ return httpResponse;
}
+
}