001package com.nimbusds.jose.util;
002
003
004import java.io.IOException;
005import java.io.InputStream;
006import java.net.HttpURLConnection;
007import java.net.URL;
008
009import net.jcip.annotations.ThreadSafe;
010import org.apache.commons.io.IOUtils;
011import org.apache.commons.io.input.BoundedInputStream;
012
013
014/**
015 * The default retriever of resources specified by URL. Provides setting of
016 * HTTP connect and read timeouts as well as a size limit of the retrieved
017 * entity. Caching header directives are not honoured.
018 */
019@ThreadSafe
020public class DefaultResourceRetriever extends AbstractRestrictedResourceRetriever implements RestrictedResourceRetriever {
021        
022        
023        /**
024         * Creates a new resource retriever. The HTTP timeouts and entity size
025         * limit are set to zero (infinite).
026         */
027        public DefaultResourceRetriever() {
028        
029                this(0, 0);     
030        }
031        
032        
033        /**
034         * Creates a new resource retriever. The HTTP entity size limit is set
035         * to zero (infinite).
036         *
037         * @param connectTimeout The HTTP connects timeout, in milliseconds, 
038         *                       zero for infinite. Must not be negative.
039         * @param readTimeout    The HTTP read timeout, in milliseconds, zero 
040         *                       for infinite. Must not be negative.
041         */
042        public DefaultResourceRetriever(final int connectTimeout, final int readTimeout) {
043
044                this(connectTimeout, readTimeout, 0);
045        }
046
047
048        /**
049         * Creates a new resource retriever.
050         *
051         * @param connectTimeout The HTTP connects timeout, in milliseconds,
052         *                       zero for infinite. Must not be negative.
053         * @param readTimeout    The HTTP read timeout, in milliseconds, zero
054         *                       for infinite. Must not be negative.
055         * @param sizeLimit      The HTTP entity size limit, in bytes, zero for
056         *                       infinite. Must not be negative.
057         */
058        public DefaultResourceRetriever(final int connectTimeout, final int readTimeout, final int sizeLimit) {
059        
060                super(connectTimeout, readTimeout, sizeLimit);
061        }
062
063
064        @Override
065        public Resource retrieveResource(final URL url)
066                throws IOException {
067                
068                HttpURLConnection con;
069                try {
070                        con = (HttpURLConnection)url.openConnection();
071                } catch (ClassCastException e) {
072                        throw new IOException("Couldn't open HTTP(S) connection: " + e.getMessage(), e);
073                }
074
075                con.setConnectTimeout(getConnectTimeout());
076                con.setReadTimeout(getReadTimeout());
077
078                InputStream inputStream = con.getInputStream();
079
080                if (getSizeLimit() > 0) {
081                        inputStream = new BoundedInputStream(inputStream, getSizeLimit());
082                }
083
084                final String content = IOUtils.toString(inputStream);
085
086                // Check HTTP code + message
087                final int statusCode = con.getResponseCode();
088                final String statusMessage = con.getResponseMessage();
089
090                // Ensure 2xx status code
091                if (statusCode > 299 || statusCode < 200) {
092                        throw new IOException("HTTP " + statusCode + ": " + statusMessage);
093                }
094
095                return new Resource(content, con.getContentType());
096        }
097}