/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 2006-2011 The OpenNMS Group, Inc.
* OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc.
*
* OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
*
* OpenNMS(R) is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* OpenNMS(R) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenNMS(R). If not, see:
* http://www.gnu.org/licenses/
*
* For more information contact:
* OpenNMS(R) Licensing <license@opennms.org>
* http://www.opennms.org/
* http://www.opennms.com/
*******************************************************************************/
package org.opennms.core.utils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.log4j.Logger;
/**
* Provides convenience methods for use the HTTP POST method.
*
* @author <A HREF="mailto:larry@opennms.org">Lawrence Karnowski </A>
*/
public abstract class HttpUtils extends Object {
/** Default buffer size for reading data. (Default is one kilobyte.) */
public final static int DEFAULT_POST_BUFFER_SIZE = 1024;
/**
* Post a given <code>InputStream</code> s data to a URL.
*
* @param url
* the <code>URL</code> to post to
* @param dataStream
* an input stream containing the data to send
* @return An <code>InputStream</a> that the programmer can read from
* to get the HTTP server's response.
* @throws java.io.IOException if any.
*/
public static InputStream post(URL url, InputStream dataStream) throws IOException {
return (post(url, dataStream, null, null, DEFAULT_POST_BUFFER_SIZE));
}
/**
* Post a given <code>InputStream</code> s data to a URL using BASIC
* authentication and the given username and password.
*
* @param url
* the <code>URL</code> to post to
* @param dataStream
* an input stream containing the data to send
* @param username
* the username to use in the BASIC authentication
* @param password
* the password to use in the BASIC authentication
* @return An <code>InputStream</a> that the programmer can read from
* to get the HTTP server's response.
* @throws java.io.IOException if any.
*/
public static InputStream post(URL url, InputStream dataStream, String username, String password) throws IOException {
return (post(url, dataStream, username, password, DEFAULT_POST_BUFFER_SIZE));
}
/**
* Post a given <code>InputStream</code> s data to a URL using BASIC
* authentication, the given username and password, and a buffer size.
*
* @param url
* the <code>URL</code> to post to
* @param dataStream
* an input stream containing the data to send
* @param username
* the username to use in the BASIC authentication
* @param password
* the password to use in the BASIC authentication
* @param bufSize
* the size of the buffer to read from <code>dataStream</code>
* and write to the HTTP server
* @return An <code>InputStream</a> that the programmer can read from
* to get the HTTP server's response.
* @throws java.io.IOException if any.
*/
public static InputStream post(URL url, InputStream dataStream, String username, String password, int bufSize) throws IOException {
if (url == null || dataStream == null) {
throw new IllegalArgumentException("Cannot take null parameters.");
}
if (bufSize < 1) {
throw new IllegalArgumentException("Cannot use zero or negative buffer size.");
}
if (!"http".equals(url.getProtocol())) {
throw new IllegalArgumentException("Cannot use non-HTTP URLs.");
}
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// in a post we both write output and read input
conn.setDoOutput(true);
conn.setDoInput(true);
try {
// the name of this method is post after all
conn.setRequestMethod("POST");
} catch (java.net.ProtocolException e) {
// this would really really really bad... when can you not use POST
// in HTTP?
throw new IllegalStateException("Could not set a HttpURLConnection's method to POST.");
}
// add the authorization header if the username and password were given
if (username != null && password != null) {
byte[] authBytes = (username + ":" + password).getBytes();
String authString = new String(Base64.encodeBase64(authBytes));
conn.setRequestProperty("Authorization", "Basic " + authString);
}
// get the out-going HTTP connection
OutputStream ostream = conn.getOutputStream();
// initialize a buffer to use to read and write
byte[] b = new byte[bufSize];
// write the given data stream over the out-going HTTP connection
int bytesRead = dataStream.read(b, 0, bufSize);
while (bytesRead > 0) {
ostream.write(b, 0, bytesRead);
bytesRead = dataStream.read(b, 0, bufSize);
}
// close the out-going HTTP connection
ostream.close();
// return the in-coming HTTP connection so the programmer can read the
// response
return (conn.getInputStream());
}
/**
* Post a given <code>Reader</code> s data to a URL using BASIC
* authentication, the given username and password, and a buffer size.
*
* @param url
* the <code>URL</code> to post to
* @param dataReader
* an input reader containing the data to send
* @param username
* the username to use in the BASIC authentication
* @param password
* the password to use in the BASIC authentication
* @param bufSize
* the size of the buffer to read from <code>dataStream</code>
* and write to the HTTP server
* @return An <code>InputStream</a> that the programmer can read from
* to get the HTTP server's response.
* @throws java.io.IOException if any.
*/
public static InputStream post(URL url, Reader dataReader, String username, String password, int bufSize) throws IOException {
if (url == null || dataReader == null) {
throw new IllegalArgumentException("Cannot take null parameters.");
}
if (bufSize < 1) {
throw new IllegalArgumentException("Cannot use zero or negative buffer size.");
}
if (!"http".equals(url.getProtocol())) {
throw new IllegalArgumentException("Cannot use non-HTTP URLs.");
}
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// in a post we both write output and read input
conn.setDoOutput(true);
conn.setDoInput(true);
try {
// the name of this method is post after all
conn.setRequestMethod("POST");
} catch (java.net.ProtocolException e) {
// this would really really really bad... when can you not use POST
// in HTTP?
throw new IllegalStateException("Could not set a HttpURLConnection's method to POST.");
}
// add the authorization header if the username and password were given
if (username != null && password != null) {
byte[] authBytes = (username + ":" + password).getBytes();
String authString = new String(Base64.encodeBase64(authBytes));
conn.setRequestProperty("Authorization", "Basic " + authString);
}
// set the mime type
conn.setRequestProperty("Content-type", "text/xml; charset=\"utf-8\"");
// get the out-going HTTP connection
OutputStreamWriter ostream = new OutputStreamWriter(conn.getOutputStream(), "US-ASCII");
// log data
Logger log = Logger.getLogger("POSTDATALOG");
if (log.isDebugEnabled()) {
String nl = System.getProperty("line.separator");
log.debug(nl + "HTTP Post: Current time: " + new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.GregorianCalendar().getTime()));
log.debug(nl + "Data posted:" + nl);
}
// initialize a buffer to use to read and write
char[] b = new char[bufSize];
// write the given data stream over the out-going HTTP connection
int bytesRead = dataReader.read(b, 0, bufSize);
if (bytesRead > 0 && log.isDebugEnabled())
log.debug(new String(b, 0, bytesRead));
while (bytesRead > 0) {
ostream.write(b, 0, bytesRead);
bytesRead = dataReader.read(b, 0, bufSize);
if (bytesRead > 0 && log.isDebugEnabled())
log.debug(new String(b, 0, bytesRead));
}
// close the out-going HTTP connection
ostream.close();
// return the in-coming HTTP connection so the programmer can read the
// response
return (conn.getInputStream());
}
}