package au.org.aurin.wif.io; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; import java.net.Authenticator; import java.net.HttpURLConnection; import java.net.PasswordAuthentication; import java.net.ProtocolException; import java.net.URL; import java.net.URLConnection; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Ref: * http://www.aviransplace.com/2008/01/08/make-http-post-or-get-request-from * -java/ */ public class HttpRequestPoster { /** The logger. */ private static final Log LOGGER = LogFactory.getLog(HttpRequestPoster.class); /** * Sends an authenticated HTTP GET request to a url. * * @param username * - The username to authenticate * @param password * - The password to authenticate * @param endpoint * - The URL of the server. (Example: " http://www.yahoo.com/search") * @param requestParameters * - all the request parameters (Example: "param1=val1¶m2=val2"). * Note: This method will add the question mark (?) to the request - * DO NOT add it yourself * @return - The response from the end point */ public static String sendGetRequest(final String username, final String password, final String endpoint, final String requestParameters) throws DatasetAccessException { String result = null; if (endpoint.startsWith("http://") || endpoint.startsWith("https://")) { // Send a GET request to the servlet try { // Construct data final StringBuffer data = new StringBuffer(); // Send data String urlStr = endpoint; if (requestParameters != null && requestParameters.length() > 0) { urlStr += "?" + requestParameters; } LOGGER.debug("HTTP GET Request: " + urlStr); final URL url = new URL(urlStr); final URLConnection conn = url.openConnection(); // let's set the timeout to 90seconds conn.setConnectTimeout(90000); conn.setReadTimeout(90000); if (username != null && password != null) { Authenticator.setDefault(new HttpAuthenticator(username, password)); } // Get the response final BufferedReader rd = new BufferedReader(new InputStreamReader( conn.getInputStream())); final StringBuffer sb = new StringBuffer(); String line; while ((line = rd.readLine()) != null) { sb.append(line); } rd.close(); // TODO check mememory footprint result = sb.toString(); } catch (final Exception e) { LOGGER.error(e.getMessage(), e); throw new DatasetAccessException( "Exception was thrown while accessing the datasource", "We are unable to connect to the remote dataset. Please, try later or notify AURIN if the problem persists", e); } } return result; } /** * Sends an HTTP GET request to a url. * * @param endpoint * - The URL of the server. (Example: " http://www.yahoo.com/search") * @param requestParameters * - all the request parameters (Example: "param1=val1¶m2=val2"). * Note: This method will add the question mark (?) to the request - * DO NOT add it yourself * @return - The response from the end point */ public static String sendGetRequest(final String endpoint, final String requestParameters) throws DatasetAccessException { return sendGetRequest(null, null, endpoint, requestParameters); } /** * Reads data from the data reader and posts it to a server via POST request. * * @param username * - The username to authenticate * @param password * - The password to authenticate * @param data * - The data you want to send * @param endpoint * - The server's address * @param output * - writes the server's response to output. * * @throws DatasetAccessException */ public static void postData(final Reader data, final URL endpoint, final Writer output) throws DatasetAccessException { postData(null, null, data, endpoint, output); } /** * Reads data from the data reader and posts it to a server via POST request. * * @param data * - The data you want to send * @param endpoint * - The server's address * @param output * - writes the server's response to output. * * @throws DatasetAccessException */ public static void postData(final String username, final String password, final Reader data, final URL endpoint, final Writer output) throws DatasetAccessException { HttpURLConnection urlc = null; try { urlc = (HttpURLConnection) endpoint.openConnection(); // TODO: verify that this bit of code works... if (username != null && password != null) { Authenticator.setDefault(new HttpAuthenticator(username, password)); } try { urlc.setRequestMethod("POST"); } catch (final ProtocolException e) { throw new DatasetAccessException( "Shouldn't happen: HttpURLConnection doesn't support POST??", e); } urlc.setDoOutput(true); urlc.setDoInput(true); urlc.setUseCaches(false); urlc.setAllowUserInteraction(false); urlc.setRequestProperty("Content-type", "text/xml; charset=" + "UTF-8"); final OutputStream out = urlc.getOutputStream(); try { final Writer writer = new OutputStreamWriter(out, "UTF-8"); pipe(data, writer); writer.close(); } catch (final IOException e) { throw new DatasetAccessException("IOException while posting data", e); } finally { if (out != null) { out.close(); } } final InputStream in = urlc.getInputStream(); try { final Reader reader = new InputStreamReader(in); pipe(reader, output); reader.close(); } catch (final IOException e) { throw new DatasetAccessException("IOException while reading response", e); } finally { if (in != null) { in.close(); } } } catch (final IOException e) { throw new DatasetAccessException( "Connection error (is server running at " + endpoint + " ?): " + e); } finally { if (urlc != null) { urlc.disconnect(); } } } /** * Pipes everything from the reader to the writer via a buffer */ private static void pipe(final Reader reader, final Writer writer) throws IOException { final char[] buf = new char[1024]; int read = 0; while ((read = reader.read(buf)) >= 0) { writer.write(buf, 0, read); } writer.flush(); } protected static class HttpAuthenticator extends Authenticator { private final String username, password; public HttpAuthenticator(final String user, final String pwd) { username = user; password = pwd; } @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password.toCharArray()); } } }