001/*
002* The contents of this file are subject to the terms of the Common Development and
003* Distribution License (the License). You may not use this file except in compliance with the
004* License.
005*
006* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007* specific language governing permission and limitations under the License.
008*
009* When distributing Covered Software, include this CDDL Header Notice in each file and include
010* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011* Header, with the fields enclosed by brackets [] replaced by your own identifying
012* information: "Portions copyright [year] [name of copyright owner]".
013*
014* Copyright 2014-2017 ForgeRock AS.
015*/
016
017package org.forgerock.util;
018
019import java.io.BufferedReader;
020import java.io.IOException;
021import java.io.InputStreamReader;
022import java.net.URL;
023import java.net.URLConnection;
024
025/**
026 * Simple helper client for connecting to URLs over HTTP
027 * and retrieving their contents via a GET request.
028 *
029 * Settable timeouts on read and connection.
030 */
031public class SimpleHTTPClient {
032
033    /**
034     * Default read timeout on HTTP requests from this client.
035     */
036    public static final int DEFAULT_READ_TIMEOUT = 5_000;
037
038    /**
039     * Default connection timeout on HTTP requests from this client.
040     */
041    public static final int DEFAULT_CONNECTION_TIMEOUT = 5_000;
042
043    private final int readTimeout;
044    private final int connTimeout;
045
046    /**
047     * Generates a new SimpleHTTPClient with the appropriate timeouts.
048     */
049    public SimpleHTTPClient() {
050        this(DEFAULT_READ_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT);
051    }
052
053    /**
054     * Generates a new SimpleHTTPClient with the appropriate timeouts.
055     *
056     * @param readTimeout read timeout value (greater than or equal to zero)
057     * @param connTimeout connection timeout value (greater than or equal to zero)
058     */
059    public SimpleHTTPClient(final int readTimeout, final int connTimeout) {
060
061        if (readTimeout < 0 || connTimeout < 0) {
062            throw new IllegalArgumentException("Unable to set the read or connection timeouts "
063                    + "to a value less than zero");
064        }
065
066        this.readTimeout = readTimeout;
067        this.connTimeout = connTimeout;
068    }
069
070    /**
071     * Utility method for gathering the contents of an HTTP page.
072     *
073     * Should ideally be in an HTTP Client utils type package, rather than here.
074     *
075     * @param url from which to attempt to retrieve the contents
076     * @return The contents of the provided url
077     * @throws java.io.IOException If there are any problems connecting to or gathering the contents of the page
078     */
079    public String get(final URL url) throws IOException {
080        final URLConnection conn = url.openConnection();
081
082        if (readTimeout >= 0) {
083            conn.setReadTimeout(readTimeout);
084        } else {
085            conn.setReadTimeout(DEFAULT_READ_TIMEOUT);
086        }
087
088        if (connTimeout >= 0) {
089            conn.setConnectTimeout(connTimeout);
090        } else {
091            conn.setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT);
092        }
093
094        final StringBuilder sb = new StringBuilder();
095
096        try (final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
097            String input;
098            while ((input = reader.readLine()) != null) {
099                sb.append(input);
100            }
101        }
102
103        return sb.toString();
104    }
105
106}