com.twelvemonkeys.net.NetUtil Maven / Gradle / Ivy
package com.twelvemonkeys.net;
import com.twelvemonkeys.io.FileUtil;
import com.twelvemonkeys.lang.StringUtil;
import com.twelvemonkeys.lang.DateUtil;
import com.twelvemonkeys.util.BASE64;
import com.twelvemonkeys.util.CollectionUtil;
import java.io.*;
import java.net.*;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Utility class with network related methods.
*
* @author Harald Kuhr
* @author last modified by $Author: haku $
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/net/NetUtil.java#2 $
*/
public final class NetUtil {
private final static String VERSION_ID = "NetUtil/2.1";
private static Authenticator sAuthenticator = null;
private final static int BUF_SIZE = 8192;
private final static String HTTP = "http://";
private final static String HTTPS = "https://";
/**
* Field HTTP_PROTOCOL
*/
public final static String HTTP_PROTOCOL = "http";
/**
* Field HTTPS_PROTOCOL
*/
public final static String HTTPS_PROTOCOL = "https";
/**
* Field HTTP_GET
*/
public final static String HTTP_GET = "GET";
/**
* Field HTTP_POST
*/
public final static String HTTP_POST = "POST";
/**
* Field HTTP_HEAD
*/
public final static String HTTP_HEAD = "HEAD";
/**
* Field HTTP_OPTIONS
*/
public final static String HTTP_OPTIONS = "OPTIONS";
/**
* Field HTTP_PUT
*/
public final static String HTTP_PUT = "PUT";
/**
* Field HTTP_DELETE
*/
public final static String HTTP_DELETE = "DELETE";
/**
* Field HTTP_TRACE
*/
public final static String HTTP_TRACE = "TRACE";
/**
* RFC 1123 date format, as reccomended by RFC 2616 (HTTP/1.1), sec 3.3
* NOTE: All date formats are private, to ensure synchronized access.
*/
private static final SimpleDateFormat HTTP_RFC1123_FORMAT = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
static {
HTTP_RFC1123_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
}
/**
* RFC 850 date format, (allmost) as described in RFC 2616 (HTTP/1.1), sec 3.3
* USE FOR PARSING ONLY (format is not 100% correct, to be more robust).
*/
private static final SimpleDateFormat HTTP_RFC850_FORMAT = new SimpleDateFormat("EEE, dd-MMM-yy HH:mm:ss z", Locale.US);
/**
* ANSI C asctime() date format, (allmost) as described in RFC 2616 (HTTP/1.1), sec 3.3.
* USE FOR PARSING ONLY (format is not 100% correct, to be more robust).
*/
private static final SimpleDateFormat HTTP_ASCTIME_FORMAT = new SimpleDateFormat("EEE MMM d HH:mm:ss yy", Locale.US);
private static long sNext50YearWindowChange = DateUtil.currentTimeDay();
static {
HTTP_RFC850_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
HTTP_ASCTIME_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.3:
// - HTTP/1.1 clients and caches SHOULD assume that an RFC-850 date
// which appears to be more than 50 years in the future is in fact
// in the past (this helps solve the "year 2000" problem).
update50YearWindowIfNeeded();
}
private static void update50YearWindowIfNeeded() {
// Avoid class synchronization
long next = sNext50YearWindowChange;
if (next < System.currentTimeMillis()) {
// Next check in one day
next += DateUtil.DAY;
sNext50YearWindowChange = next;
Date startDate = new Date(next - (50l * DateUtil.CALENDAR_YEAR));
//System.out.println("next test: " + new Date(next) + ", 50 year start: " + startDate);
synchronized (HTTP_RFC850_FORMAT) {
HTTP_RFC850_FORMAT.set2DigitYearStart(startDate);
}
synchronized (HTTP_ASCTIME_FORMAT) {
HTTP_ASCTIME_FORMAT.set2DigitYearStart(startDate);
}
}
}
/**
* Creates a NetUtil.
* This class has only static methods and members, and should not be
* instantiated.
*/
private NetUtil() {
}
public static void main1(String[] args) {
String timeStr = (args.length > 0 && !StringUtil.isNumber(args[0])) ? args[0] : null;
long time = args.length > 0 ?
(timeStr != null ? parseHTTPDate(timeStr) : Long.parseLong(args[0]))
: System.currentTimeMillis();
System.out.println(timeStr + " --> " + time + " --> " + formatHTTPDate(time));
}
/**
* Main method, reads data from a URL and, optionally, writes it to stdout or a file.
* @param pArgs command line arguemnts
* @throws java.io.IOException if an I/O exception occurs
*/
public static void main(String[] pArgs) throws IOException {
// params:
int timeout = 0;
boolean followRedirects = true;
boolean debugHeaders = false;
String requestPropertiesFile = null;
String requestHeaders = null;
String postData = null;
File putData = null;
int argIdx = 0;
boolean errArgs = false;
boolean writeToFile = false;
boolean writeToStdOut = false;
String outFileName = null;
while ((argIdx < pArgs.length) && (pArgs[argIdx].charAt(0) == '-') && (pArgs[argIdx].length() >= 2)) {
if ((pArgs[argIdx].charAt(1) == 't') || pArgs[argIdx].equals("--timeout")) {
argIdx++;
try {
timeout = Integer.parseInt(pArgs[argIdx++]);
}
catch (NumberFormatException nfe) {
errArgs = true;
break;
}
}
else if ((pArgs[argIdx].charAt(1) == 'd') || pArgs[argIdx].equals("--debugheaders")) {
debugHeaders = true;
argIdx++;
}
else if ((pArgs[argIdx].charAt(1) == 'n') || pArgs[argIdx].equals("--nofollowredirects")) {
followRedirects = false;
argIdx++;
}
else if ((pArgs[argIdx].charAt(1) == 'r') || pArgs[argIdx].equals("--requestproperties")) {
argIdx++;
requestPropertiesFile = pArgs[argIdx++];
}
else if ((pArgs[argIdx].charAt(1) == 'p') || pArgs[argIdx].equals("--postdata")) {
argIdx++;
postData = pArgs[argIdx++];
}
else if ((pArgs[argIdx].charAt(1) == 'u') || pArgs[argIdx].equals("--putdata")) {
argIdx++;
putData = new File(pArgs[argIdx++]);
if (!putData.exists()) {
errArgs = true;
break;
}
}
else if ((pArgs[argIdx].charAt(1) == 'h') || pArgs[argIdx].equals("--header")) {
argIdx++;
requestHeaders = pArgs[argIdx++];
}
else if ((pArgs[argIdx].charAt(1) == 'f') || pArgs[argIdx].equals("--file")) {
argIdx++;
writeToFile = true;
// Get optional file name
if (!((argIdx >= (pArgs.length - 1)) || (pArgs[argIdx].charAt(0) == '-'))) {
outFileName = pArgs[argIdx++];
}
}
else if ((pArgs[argIdx].charAt(1) == 'o') || pArgs[argIdx].equals("--output")) {
argIdx++;
writeToStdOut = true;
}
else {
System.err.println("Unknown option \"" + pArgs[argIdx++] + "\"");
}
}
if (errArgs || (pArgs.length < (argIdx + 1))) {
System.err.println("Usage: java NetUtil [-f|--file []] [-d|--debugheaders] [-h|--header ] [-p|--postdata ] [-u|--putdata ] [-r|--requestProperties ] [-t|--timeout ] [-n|--nofollowredirects] fromUrl");
System.exit(5);
}
String url = pArgs[argIdx/*++*/];
// DONE ARGS
// Get request properties
Properties requestProperties = new Properties();
if (requestPropertiesFile != null) {
// Just read, no exception handling...
requestProperties.load(new FileInputStream(new File(requestPropertiesFile)));
}
if (requestHeaders != null) {
// Get request headers
String[] headerPairs = StringUtil.toStringArray(requestHeaders, ",");
for (String headerPair : headerPairs) {
String[] pair = StringUtil.toStringArray(headerPair, ":");
String key = (pair.length > 0)
? pair[0].trim()
: null;
String value = (pair.length > 1)
? pair[1].trim()
: "";
if (key != null) {
requestProperties.setProperty(key, value);
}
}
}
java.net.HttpURLConnection conn;
// Create connection
URL reqURL = getURLAndSetAuthorization(url, requestProperties);
conn = createHttpURLConnection(reqURL, requestProperties, followRedirects, timeout);
// POST
if (postData != null) {
// HTTP POST method
conn.setRequestMethod(HTTP_POST);
// Set entity headers
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(postData.length()));
conn.setRequestProperty("Content-Encoding", "ISO-8859-1");
// Get outputstream (this is where the connect actually happens)
OutputStream os = conn.getOutputStream();
System.err.println("OutputStream: " + os.getClass().getName() + "@" + System.identityHashCode(os));
OutputStreamWriter writer = new OutputStreamWriter(os, "ISO-8859-1");
// Write post data to the stream
writer.write(postData);
writer.write("\r\n");
//writer.flush();
writer.close(); // Does this close the underlying stream?
}
// PUT
else if (putData != null) {
// HTTP PUT method
conn.setRequestMethod(HTTP_PUT);
// Set entity headers
//conn.setRequestProperty("Content-Type", "???");
// TODO: Set Content-Type to correct type?
// TODO: Set content-encoding? Or can binary data be sent directly?
conn.setRequestProperty("Content-Length", String.valueOf(putData.length()));
// Get outputstream (this is where the connect actually happens)
OutputStream os = conn.getOutputStream();
System.err.println("OutputStream: " + os.getClass().getName() + "@" + System.identityHashCode(os));
// Write put data to the stream
FileUtil.copy(new FileInputStream(putData), os);
os.close();
}
//
InputStream is;
if (conn.getResponseCode() == 200) {
// Connect and get stream
is = conn.getInputStream();
}
else {
is = conn.getErrorStream();
}
//
if (debugHeaders) {
System.err.println("Request (debug):");
System.err.println(conn.getClass());
System.err.println("Response (debug):");
// Headerfield 0 is response code
System.err.println(conn.getHeaderField(0));
// Loop from 1, as headerFieldKey(0) == null...
for (int i = 1; ; i++) {
String key = conn.getHeaderFieldKey(i);
// Seems to be the way to loop through them all...
if (key == null) {
break;
}
System.err.println(key + ": " + conn.getHeaderField(key));
}
}
// Create output file if specified
OutputStream os;
if (writeToFile) {
if (outFileName == null) {
outFileName = reqURL.getFile();
if (StringUtil.isEmpty(outFileName)) {
outFileName = conn.getHeaderField("Location");
if (StringUtil.isEmpty(outFileName)) {
outFileName = "index";
// Find a suitable extension
// TODO: Replace with MIME-type util with MIME/file ext mapping
String ext = conn.getContentType();
if (!StringUtil.isEmpty(ext)) {
int idx = ext.lastIndexOf('/');
if (idx >= 0) {
ext = ext.substring(idx + 1);
}
idx = ext.indexOf(';');
if (idx >= 0) {
ext = ext.substring(0, idx);
}
outFileName += "." + ext;
}
}
}
int idx = outFileName.lastIndexOf('/');
if (idx >= 0) {
outFileName = outFileName.substring(idx + 1);
}
idx = outFileName.indexOf('?');
if (idx >= 0) {
outFileName = outFileName.substring(0, idx);
}
}
File outFile = new File(outFileName);
if (!outFile.createNewFile()) {
if (outFile.exists()) {
System.err.println("Cannot write to file " + outFile.getAbsolutePath() + ", file allready exists.");
}
else {
System.err.println("Cannot write to file " + outFile.getAbsolutePath() + ", check write permissions.");
}
System.exit(5);
}
os = new FileOutputStream(outFile);
}
else if (writeToStdOut) {
os = System.out;
}
else {
os = null;
}
// Get data.
if ((writeToFile || writeToStdOut) && is != null) {
FileUtil.copy(is, os);
}
/*
Hashtable postData = new Hashtable();
postData.put("SearchText", "condition");
try {
InputStream in = getInputStreamHttpPost(pArgs[argIdx], postData,
props, true, 0);
out = new FileOutputStream(file);
FileUtil.copy(in, out);
}
catch (Exception e) {
System.err.println("Error: " + e);
e.printStackTrace(System.err);
continue;
}
*/
}
/*
public static class Cookie {
String mName = null;
String mValue = null;
public Cookie(String pName, String pValue) {
mName = pName;
mValue = pValue;
}
public String toString() {
return mName + "=" + mValue;
}
*/
/*
// Just a way to set cookies..
if (pCookies != null) {
String cookieStr = "";
for (int i = 0; i < pCookies.length; i++)
cookieStr += ((i == pCookies.length) ? pCookies[i].toString()
: pCookies[i].toString() + ";");
// System.out.println("Cookie: " + cookieStr);
conn.setRequestProperty("Cookie", cookieStr);
}
*/
/*
}
*/
/**
* Test if the given URL is using HTTP protocol.
*
* @param pURL the url to condition
* @return true if the protocol is HTTP.
*/
public static boolean isHttpURL(String pURL) {
return ((pURL != null) && pURL.startsWith(HTTP));
}
/**
* Test if the given URL is using HTTP protocol.
*
* @param pURL the url to condition
* @return true if the protocol is HTTP.
*/
public static boolean isHttpURL(URL pURL) {
return ((pURL != null) && pURL.getProtocol().equals("http"));
}
/**
* Gets the content from a given URL, and returns it as a byte array.
* Supports basic HTTP
* authentication, using a URL string similar to most browsers.
*
* NOTE: If you supply a username and password for HTTP
* authentication, this method uses the java.net.Authenticator's static
* {@code setDefault()} method, that can only be set ONCE. This
* means that if the default Authenticator is allready set, this method
* will fail.
* It also means if any other piece of code tries to register a new default
* Authenticator within the current VM, it will fail.
*
* @param pURL A String containing the URL, on the form
* [http://][:@]servername[/file.ext]
* where everything in brackets are optional.
* @return a byte array with the URL contents. If an error occurs, the
* returned array may be zero-length, but not null.
* @throws MalformedURLException if the urlName parameter is not a valid
* URL. Note that the protocol cannot be anything but HTTP.
* @throws FileNotFoundException if there is no file at the given URL.
* @throws IOException if an error occurs during transfer.
* @see java.net.Authenticator
* @see SimpleAuthenticator
*/
public static byte[] getBytesHttp(String pURL) throws IOException {
return getBytesHttp(pURL, 0);
}
/**
* Gets the content from a given URL, and returns it as a byte array.
*
* @param pURL the URL to get.
* @return a byte array with the URL contents. If an error occurs, the
* returned array may be zero-length, but not null.
* @throws FileNotFoundException if there is no file at the given URL.
* @throws IOException if an error occurs during transfer.
* @see #getBytesHttp(String)
*/
public static byte[] getBytesHttp(URL pURL) throws IOException {
return getBytesHttp(pURL, 0);
}
/**
* Gets the InputStream from a given URL. Supports basic HTTP
* authentication, using a URL string similar to most browsers.
*
* NOTE: If you supply a username and password for HTTP
* authentication, this method uses the java.net.Authenticator's static
* {@code setDefault()} method, that can only be set ONCE. This
* means that if the default Authenticator is allready set, this method
* will fail.
* It also means if any other piece of code tries to register a new default
* Authenticator within the current VM, it will fail.
*
* @param pURL A String containing the URL, on the form
* [http://][:@]servername[/file.ext]
* where everything in brackets are optional.
* @return an input stream that reads from the connection created by the
* given URL.
* @throws MalformedURLException if the urlName parameter specifies an
* unknown protocol, or does not form a valid URL.
* Note that the protocol cannot be anything but HTTP.
* @throws FileNotFoundException if there is no file at the given URL.
* @throws IOException if an error occurs during transfer.
* @see java.net.Authenticator
* @see SimpleAuthenticator
*/
public static InputStream getInputStreamHttp(String pURL) throws IOException {
return getInputStreamHttp(pURL, 0);
}
/**
* Gets the InputStream from a given URL.
*
* @param pURL the URL to get.
* @return an input stream that reads from the connection created by the
* given URL.
* @throws FileNotFoundException if there is no file at the given URL.
* @throws IOException if an error occurs during transfer.
* @see #getInputStreamHttp(String)
*/
public static InputStream getInputStreamHttp(URL pURL) throws IOException {
return getInputStreamHttp(pURL, 0);
}
/**
* Gets the InputStream from a given URL, with the given timeout.
* The timeout must be > 0. A timeout of zero is interpreted as an
* infinite timeout. Supports basic HTTP
* authentication, using a URL string similar to most browsers.
*
* Implementation note: If the timeout parameter is greater than 0,
* this method uses my own implementation of
* java.net.HttpURLConnection, that uses plain sockets, to create an
* HTTP connection to the given URL. The {@code read} methods called
* on the returned InputStream, will block only for the specified timeout.
* If the timeout expires, a java.io.InterruptedIOException is raised. This
* might happen BEFORE OR AFTER this method returns, as the HTTP headers
* will be read and parsed from the InputStream before this method returns,
* while further read operations on the returned InputStream might be
* performed at a later stage.
*
*
*
* @param pURL the URL to get.
* @param pTimeout the specified timeout, in milliseconds.
* @return an input stream that reads from the socket connection, created
* from the given URL.
* @throws MalformedURLException if the url parameter specifies an
* unknown protocol, or does not form a valid URL.
* @throws UnknownHostException if the IP address for the given URL cannot
* be resolved.
* @throws FileNotFoundException if there is no file at the given URL.
* @throws IOException if an error occurs during transfer.
* @see #getInputStreamHttp(URL,int)
* @see java.net.Socket
* @see java.net.Socket#setSoTimeout(int) setSoTimeout
* @see java.io.InterruptedIOException
* @see RFC 2616
*/
public static InputStream getInputStreamHttp(String pURL, int pTimeout) throws IOException {
return getInputStreamHttp(pURL, null, true, pTimeout);
}
/**
* Gets the InputStream from a given URL, with the given timeout.
* The timeout must be > 0. A timeout of zero is interpreted as an
* infinite timeout. Supports basic HTTP
* authentication, using a URL string similar to most browsers.
*
* Implementation note: If the timeout parameter is greater than 0,
* this method uses my own implementation of
* java.net.HttpURLConnection, that uses plain sockets, to create an
* HTTP connection to the given URL. The {@code read} methods called
* on the returned InputStream, will block only for the specified timeout.
* If the timeout expires, a java.io.InterruptedIOException is raised. This
* might happen BEFORE OR AFTER this method returns, as the HTTP headers
* will be read and parsed from the InputStream before this method returns,
* while further read operations on the returned InputStream might be
* performed at a later stage.
*
*
*
* @param pURL the URL to get.
* @param pProperties the request header properties.
* @param pFollowRedirects specifying wether redirects should be followed.
* @param pTimeout the specified timeout, in milliseconds.
* @return an input stream that reads from the socket connection, created
* from the given URL.
* @throws MalformedURLException if the url parameter specifies an
* unknown protocol, or does not form a valid URL.
* @throws UnknownHostException if the IP address for the given URL cannot
* be resolved.
* @throws FileNotFoundException if there is no file at the given URL.
* @throws IOException if an error occurs during transfer.
* @see #getInputStreamHttp(URL,int)
* @see java.net.Socket
* @see java.net.Socket#setSoTimeout(int) setSoTimeout
* @see java.io.InterruptedIOException
* @see RFC 2616
*/
public static InputStream getInputStreamHttp(final String pURL, final Properties pProperties, final boolean pFollowRedirects, final int pTimeout)
throws IOException {
// Make sure we have properties
Properties properties = pProperties != null ? pProperties : new Properties();
//URL url = getURLAndRegisterPassword(pURL);
URL url = getURLAndSetAuthorization(pURL, properties);
//unregisterPassword(url);
return getInputStreamHttp(url, properties, pFollowRedirects, pTimeout);
}
/**
* Registers the password from the URL string, and returns the URL object.
*
* @param pURL the string representation of the URL, possibly including authorization part
* @param pProperties the
* @return the URL created from {@code pURL}.
* @throws java.net.MalformedURLException if there's a syntax error in {@code pURL}
*/
private static URL getURLAndSetAuthorization(final String pURL, final Properties pProperties) throws MalformedURLException {
String url = pURL;
// Split user/password away from url
String userPass = null;
String protocolPrefix = HTTP;
int httpIdx = url.indexOf(HTTPS);
if (httpIdx >= 0) {
protocolPrefix = HTTPS;
url = url.substring(httpIdx + HTTPS.length());
}
else {
httpIdx = url.indexOf(HTTP);
if (httpIdx >= 0) {
url = url.substring(httpIdx + HTTP.length());
}
}
// Get authorization part
int atIdx = url.indexOf("@");
if (atIdx >= 0) {
userPass = url.substring(0, atIdx);
url = url.substring(atIdx + 1);
}
// Set authorization if user/password is present
if (userPass != null) {
// System.out.println("Setting password ("+ userPass + ")!");
pProperties.setProperty("Authorization", "Basic " + BASE64.encode(userPass.getBytes()));
}
// Return URL
return new URL(protocolPrefix + url);
}
/**
* Gets the InputStream from a given URL, with the given timeout.
* The timeout must be > 0. A timeout of zero is interpreted as an
* infinite timeout.
*
* Implementation note: If the timeout parameter is greater than 0,
* this method uses my own implementation of
* java.net.HttpURLConnection, that uses plain sockets, to create an
* HTTP connection to the given URL. The {@code read} methods called
* on the returned InputStream, will block only for the specified timeout.
* If the timeout expires, a java.io.InterruptedIOException is raised. This
* might happen BEFORE OR AFTER this method returns, as the HTTP headers
* will be read and parsed from the InputStream before this method returns,
* while further read operations on the returned InputStream might be
* performed at a later stage.
*
*
*
* @param pURL the URL to get.
* @param pTimeout the specified timeout, in milliseconds.
* @return an input stream that reads from the socket connection, created
* from the given URL.
* @throws UnknownHostException if the IP address for the given URL cannot
* be resolved.
* @throws FileNotFoundException if there is no file at the given URL.
* @throws IOException if an error occurs during transfer.
* @see com.twelvemonkeys.net.HttpURLConnection
* @see java.net.Socket
* @see java.net.Socket#setSoTimeout(int) setSoTimeout
* @see java.net.HttpURLConnection
* @see java.io.InterruptedIOException
* @see RFC 2616
*/
public static InputStream getInputStreamHttp(URL pURL, int pTimeout) throws IOException {
return getInputStreamHttp(pURL, null, true, pTimeout);
}
/**
* Gets the InputStream from a given URL, with the given timeout.
* The timeout must be > 0. A timeout of zero is interpreted as an
* infinite timeout. Supports basic HTTP
* authentication, using a URL string similar to most browsers.
*
* Implementation note: If the timeout parameter is greater than 0,
* this method uses my own implementation of
* java.net.HttpURLConnection, that uses plain sockets, to create an
* HTTP connection to the given URL. The {@code read} methods called
* on the returned InputStream, will block only for the specified timeout.
* If the timeout expires, a java.io.InterruptedIOException is raised. This
* might happen BEFORE OR AFTER this method returns, as the HTTP headers
* will be read and parsed from the InputStream before this method returns,
* while further read operations on the returned InputStream might be
* performed at a later stage.
*
*
*
* @param pURL the URL to get.
* @param pProperties the request header properties.
* @param pFollowRedirects specifying wether redirects should be followed.
* @param pTimeout the specified timeout, in milliseconds.
* @return an input stream that reads from the socket connection, created
* from the given URL.
* @throws UnknownHostException if the IP address for the given URL cannot
* be resolved.
* @throws FileNotFoundException if there is no file at the given URL.
* @throws IOException if an error occurs during transfer.
* @see #getInputStreamHttp(URL,int)
* @see java.net.Socket
* @see java.net.Socket#setSoTimeout(int) setSoTimeout
* @see java.io.InterruptedIOException
* @see RFC 2616
*/
public static InputStream getInputStreamHttp(URL pURL, Properties pProperties, boolean pFollowRedirects, int pTimeout)
throws IOException {
// Open the connection, and get the stream
java.net.HttpURLConnection conn = createHttpURLConnection(pURL, pProperties, pFollowRedirects, pTimeout);
// HTTP GET method
conn.setRequestMethod(HTTP_GET);
// This is where the connect happens
InputStream is = conn.getInputStream();
// We only accept the 200 OK message
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("The request gave the response: " + conn.getResponseCode() + ": " + conn.getResponseMessage());
}
return is;
}
/**
* Gets the InputStream from a given URL, with the given timeout.
* The timeout must be > 0. A timeout of zero is interpreted as an
* infinite timeout. Supports basic HTTP
* authentication, using a URL string similar to most browsers.
*
* Implementation note: If the timeout parameter is greater than 0,
* this method uses my own implementation of
* java.net.HttpURLConnection, that uses plain sockets, to create an
* HTTP connection to the given URL. The {@code read} methods called
* on the returned InputStream, will block only for the specified timeout.
* If the timeout expires, a java.io.InterruptedIOException is raised. This
* might happen BEFORE OR AFTER this method returns, as the HTTP headers
* will be read and parsed from the InputStream before this method returns,
* while further read operations on the returned InputStream might be
* performed at a later stage.
*
*
*
* @param pURL the URL to get.
* @param pPostData the post data.
* @param pProperties the request header properties.
* @param pFollowRedirects specifying wether redirects should be followed.
* @param pTimeout the specified timeout, in milliseconds.
* @return an input stream that reads from the socket connection, created
* from the given URL.
* @throws MalformedURLException if the url parameter specifies an
* unknown protocol, or does not form a valid URL.
* @throws UnknownHostException if the IP address for the given URL cannot
* be resolved.
* @throws FileNotFoundException if there is no file at the given URL.
* @throws IOException if an error occurs during transfer.
*/
public static InputStream getInputStreamHttpPost(String pURL, Map pPostData, Properties pProperties, boolean pFollowRedirects, int pTimeout)
throws IOException {
pProperties = pProperties != null ? pProperties : new Properties();
//URL url = getURLAndRegisterPassword(pURL);
URL url = getURLAndSetAuthorization(pURL, pProperties);
//unregisterPassword(url);
return getInputStreamHttpPost(url, pPostData, pProperties, pFollowRedirects, pTimeout);
}
/**
* Gets the InputStream from a given URL, with the given timeout.
* The timeout must be > 0. A timeout of zero is interpreted as an
* infinite timeout. Supports basic HTTP
* authentication, using a URL string similar to most browsers.
*
* Implementation note: If the timeout parameter is greater than 0,
* this method uses my own implementation of
* java.net.HttpURLConnection, that uses plain sockets, to create an
* HTTP connection to the given URL. The {@code read} methods called
* on the returned InputStream, will block only for the specified timeout.
* If the timeout expires, a java.io.InterruptedIOException is raised. This
* might happen BEFORE OR AFTER this method returns, as the HTTP headers
* will be read and parsed from the InputStream before this method returns,
* while further read operations on the returned InputStream might be
* performed at a later stage.
*
*
*
* @param pURL the URL to get.
* @param pPostData the post data.
* @param pProperties the request header properties.
* @param pFollowRedirects specifying wether redirects should be followed.
* @param pTimeout the specified timeout, in milliseconds.
* @return an input stream that reads from the socket connection, created
* from the given URL.
* @throws UnknownHostException if the IP address for the given URL cannot
* be resolved.
* @throws FileNotFoundException if there is no file at the given URL.
* @throws IOException if an error occurs during transfer.
*/
public static InputStream getInputStreamHttpPost(URL pURL, Map pPostData, Properties pProperties, boolean pFollowRedirects, int pTimeout)
throws IOException {
// Open the connection, and get the stream
java.net.HttpURLConnection conn = createHttpURLConnection(pURL, pProperties, pFollowRedirects, pTimeout);
// HTTP POST method
conn.setRequestMethod(HTTP_POST);
// Iterate over and create post data string
StringBuilder postStr = new StringBuilder();
if (pPostData != null) {
Iterator data = pPostData.entrySet().iterator();
while (data.hasNext()) {
Map.Entry entry = (Map.Entry) data.next();
// Properties key/values can be safely cast to strings
// Encode the string
postStr.append(URLEncoder.encode((String) entry.getKey(), "UTF-8"));
postStr.append('=');
postStr.append(URLEncoder.encode(entry.getValue().toString(), "UTF-8"));
if (data.hasNext()) {
postStr.append('&');
}
}
}
// Set entity headers
String encoding = conn.getRequestProperty("Content-Encoding");
if (StringUtil.isEmpty(encoding)) {
encoding = "UTF-8";
}
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(postStr.length()));
conn.setRequestProperty("Content-Encoding", encoding);
// Get outputstream (this is where the connect actually happens)
OutputStream os = conn.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(os, encoding);
// Write post data to the stream
writer.write(postStr.toString());
writer.write("\r\n");
writer.close(); // Does this close the underlying stream?
// Get the inputstream
InputStream is = conn.getInputStream();
// We only accept the 200 OK message
// TODO: Accept all 200 messages, like ACCEPTED, CREATED or NO_CONTENT?
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("The request gave the response: " + conn.getResponseCode() + ": " + conn.getResponseMessage());
}
return is;
}
/**
* Creates a HTTP connection to the given URL.
*
* @param pURL the URL to get.
* @param pProperties connection properties.
* @param pFollowRedirects specifies whether we should follow redirects.
* @param pTimeout the specified timeout, in milliseconds.
* @return a HttpURLConnection
* @throws UnknownHostException if the hostname in the URL cannot be found.
* @throws IOException if an I/O exception occurs.
*/
public static java.net.HttpURLConnection createHttpURLConnection(URL pURL, Properties pProperties, boolean pFollowRedirects, int pTimeout)
throws IOException {
// Open the connection, and get the stream
java.net.HttpURLConnection conn;
if (pTimeout > 0) {
// Supports timeout
conn = new com.twelvemonkeys.net.HttpURLConnection(pURL, pTimeout);
}
else {
// Faster, more compatible
conn = (java.net.HttpURLConnection) pURL.openConnection();
}
// Set user agent
if ((pProperties == null) || !pProperties.containsKey("User-Agent")) {
conn.setRequestProperty("User-Agent",
VERSION_ID
+ " (" + System.getProperty("os.name") + "/" + System.getProperty("os.version") + "; "
+ System.getProperty("os.arch") + "; "
+ System.getProperty("java.vm.name") + "/" + System.getProperty("java.vm.version") + ")");
}
// Set request properties
if (pProperties != null) {
for (Map.Entry
© 2015 - 2025 Weber Informatics LLC | Privacy Policy