001/* 002 * nimbus-jose-jwt 003 * 004 * Copyright 2012-2016, Connect2id Ltd. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.jose.util; 019 020 021import java.io.IOException; 022import java.io.InputStream; 023import java.net.HttpURLConnection; 024import java.net.URL; 025import java.nio.charset.Charset; 026 027import net.jcip.annotations.ThreadSafe; 028 029 030/** 031 * The default retriever of resources specified by URL. Provides setting of 032 * HTTP connect and read timeouts as well as a size limit of the retrieved 033 * entity. Caching header directives are not honoured. 034 * 035 * @author Vladimir Dzhuvinov 036 * @version 2016-11-28 037 */ 038@ThreadSafe 039public class DefaultResourceRetriever extends AbstractRestrictedResourceRetriever implements RestrictedResourceRetriever { 040 041 042 /** 043 * Creates a new resource retriever. The HTTP timeouts and entity size 044 * limit are set to zero (infinite). 045 */ 046 public DefaultResourceRetriever() { 047 048 this(0, 0); 049 } 050 051 052 /** 053 * Creates a new resource retriever. The HTTP entity size limit is set 054 * to zero (infinite). 055 * 056 * @param connectTimeout The HTTP connects timeout, in milliseconds, 057 * zero for infinite. Must not be negative. 058 * @param readTimeout The HTTP read timeout, in milliseconds, zero 059 * for infinite. Must not be negative. 060 */ 061 public DefaultResourceRetriever(final int connectTimeout, final int readTimeout) { 062 063 this(connectTimeout, readTimeout, 0); 064 } 065 066 067 /** 068 * Creates a new resource retriever. 069 * 070 * @param connectTimeout The HTTP connects timeout, in milliseconds, 071 * zero for infinite. Must not be negative. 072 * @param readTimeout The HTTP read timeout, in milliseconds, zero 073 * for infinite. Must not be negative. 074 * @param sizeLimit The HTTP entity size limit, in bytes, zero for 075 * infinite. Must not be negative. 076 */ 077 public DefaultResourceRetriever(final int connectTimeout, final int readTimeout, final int sizeLimit) { 078 079 super(connectTimeout, readTimeout, sizeLimit); 080 } 081 082 083 @Override 084 public Resource retrieveResource(final URL url) 085 throws IOException { 086 087 HttpURLConnection con; 088 try { 089 con = (HttpURLConnection)url.openConnection(); 090 } catch (ClassCastException e) { 091 throw new IOException("Couldn't open HTTP(S) connection: " + e.getMessage(), e); 092 } 093 094 con.setConnectTimeout(getConnectTimeout()); 095 con.setReadTimeout(getReadTimeout()); 096 097 InputStream inputStream = con.getInputStream(); 098 099 if (getSizeLimit() > 0) { 100 inputStream = new BoundedInputStream(inputStream, getSizeLimit()); 101 } 102 103 final String content; 104 try { 105 content = IOUtils.readInputStreamToString(inputStream, Charset.forName("UTF-8")); 106 } finally { 107 inputStream.close(); 108 } 109 110 // Check HTTP code + message 111 final int statusCode = con.getResponseCode(); 112 final String statusMessage = con.getResponseMessage(); 113 114 // Ensure 2xx status code 115 if (statusCode > 299 || statusCode < 200) { 116 throw new IOException("HTTP " + statusCode + ": " + statusMessage); 117 } 118 119 return new Resource(content, con.getContentType()); 120 } 121}