/webportal/src/main/java/au/org/emii/portal/net/HttpConnectionImpl.java
Java | 221 lines | 150 code | 28 blank | 43 comment | 14 complexity | 80b372f602053aeb66afc24c2ce38b6f MD5 | raw file
1package au.org.emii.portal.net; 2 3import au.org.emii.portal.settings.Settings; 4import java.io.ByteArrayOutputStream; 5import java.io.FilterOutputStream; 6import java.io.IOException; 7import java.io.InputStream; 8import java.io.OutputStream; 9import java.net.HttpURLConnection; 10import java.net.URL; 11import java.net.URLConnection; 12import org.apache.commons.io.IOUtils; 13import org.apache.log4j.Logger; 14 15/** 16 * Dead simple class to configure an InputStream based on a URI, this is so 17 * that consumers have things likes timeouts set correctly and consistently 18 * @author geoff 19 * 20 */ 21public class HttpConnectionImpl implements HttpConnection { 22 private Logger logger = Logger.getLogger(getClass()); 23 private Settings settings = null; 24 25 /** 26 * Return a URL connection that times out according to the 27 * net_connect_timeout and net_read_timeout entries in the 28 * config file 29 * @param uri 30 * @throws IOException 31 */ 32 public URLConnection configureURLConnection(String uri) throws IOException { 33 return configureURLConnection( 34 uri, 35 settings.getNetConnectTimeout(), 36 settings.getNetReadTimeout() 37 ); 38 } 39 40 /** 41 * Return a URL connection that times out according to the 42 * net_connect_slow_timeout and net_read_slow_timeout entries 43 * in the config file 44 * @param uri to connect to 45 * @return 46 * @throws IOException 47 */ 48 public URLConnection configureSlowURLConnection(String uri) throws IOException { 49 return configureURLConnection( 50 uri, 51 settings.getNetConnectSlowTimeout(), 52 settings.getNetReadSlowTimeout() 53 ); 54 } 55 56 /** 57 * Return a URL connection that times out after the passed in timeouts 58 * @param uri uri to connect to 59 * @param connectTimeout time to wait for a connection (ms) 60 * @param readtimeout time to wait for the uri to be fully read (ms) 61 * @return 62 * @throws IOException 63 */ 64 @Override 65 public URLConnection configureURLConnection(String uri, int connectTimeout, int readtimeout) throws IOException { 66 URL url = new URL(uri); 67 URLConnection con = url.openConnection(); 68 con.setConnectTimeout(connectTimeout); 69 con.setReadTimeout(readtimeout); 70 return con; 71 } 72 73 public URLConnection configureURLConnectionWithAuthentication(String uri, 74 String userName, String passWord) throws IOException { 75 String input = userName + ":" + passWord; 76 URL url = new URL(uri); 77 URLConnection con = url.openConnection(); 78 con.setConnectTimeout(settings.getNetConnectSlowTimeout()); 79 con.setReadTimeout(settings.getNetReadSlowTimeout()); 80 81 String encoding = base64Encode(input); 82 con.setRequestProperty("Authorization", "Basic " 83 + encoding); 84 85 return con; 86 } 87 88 /** 89 * Readback the raw data from a uri and return it 90 * @param uri 91 * @return 92 */ 93 public String readRawData(String uri) { 94 String raw; 95 InputStream in = null; 96 URLConnection con = null; 97 try { 98 con = configureURLConnection(uri); 99 in = con.getInputStream(); 100 raw = IOUtils.toString(in); 101 } 102 catch (IOException e) { 103 // for 404 errors, the message will be the requested url 104 logger.debug( 105 "IO error (" + e.getMessage() + ") reading raw " + 106 "data from URI: " + uri 107 ); 108 raw = null; 109 if (in != null) { 110 try { in.close(); } catch (IOException ex) { logger.debug(ex);} 111 } 112 113 // httpURLConnection also covers https connections 114 if (con instanceof HttpURLConnection) { 115 logger.debug("attempting to read error stream"); 116 HttpURLConnection httpCon = (HttpURLConnection) con; 117 in = httpCon.getErrorStream(); 118 try { 119 if (in != null) { 120 raw = IOUtils.toString(in); 121 } 122 } 123 catch (IOException ex) {logger.debug(ex);} 124 125 } 126 else { 127 logger.debug("leaving readRawData without getting error stream"); 128 } 129 } 130 finally { 131 IOUtils.closeQuietly(in); 132 } 133 return raw; 134 } 135 136 public Settings getSettings() { 137 return settings; 138 } 139 140 public void setSettings(Settings settings) { 141 this.settings = settings; 142 } 143 144 145 146 147 public static String base64Encode(String s) { 148 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 149 Base64OutputStream out = new Base64OutputStream(bOut); 150 try { 151 out.write(s.getBytes()); 152 out.flush(); 153 } catch (IOException exception) { 154 } 155 return bOut.toString(); 156 } 157} 158 159/* 160 * BASE64 encoding encodes 3 bytes into 4 characters. 161 * |11111122|22223333|33444444| Each set of 6 bits is encoded according to the 162 * toBase64 map. If the number of input bytes is not a multiple of 3, then the 163 * last group of 4 characters is padded with one or two = signs. Each output 164 * line is at most 76 characters. 165 */ 166 167class Base64OutputStream extends FilterOutputStream { 168 public Base64OutputStream(OutputStream out) { 169 super(out); 170 } 171 172 public void write(int c) throws IOException { 173 inbuf[i] = c; 174 i++; 175 if (i == 3) { 176 super.write(toBase64[(inbuf[0] & 0xFC) >> 2]); 177 super.write(toBase64[((inbuf[0] & 0x03) << 4) 178 | ((inbuf[1] & 0xF0) >> 4)]); 179 super.write(toBase64[((inbuf[1] & 0x0F) << 2) 180 | ((inbuf[2] & 0xC0) >> 6)]); 181 super.write(toBase64[inbuf[2] & 0x3F]); 182 col += 4; 183 i = 0; 184 if (col >= 76) { 185 super.write('\n'); 186 col = 0; 187 } 188 } 189 } 190 191 public void flush() throws IOException { 192 if (i == 1) { 193 super.write(toBase64[(inbuf[0] & 0xFC) >> 2]); 194 super.write(toBase64[(inbuf[0] & 0x03) << 4]); 195 super.write('='); 196 super.write('='); 197 } else if (i == 2) { 198 super.write(toBase64[(inbuf[0] & 0xFC) >> 2]); 199 super.write(toBase64[((inbuf[0] & 0x03) << 4) 200 | ((inbuf[1] & 0xF0) >> 4)]); 201 super.write(toBase64[(inbuf[1] & 0x0F) << 2]); 202 super.write('='); 203 } 204 } 205 206 private static char[] toBase64 = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 207 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 208 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 209 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 210 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', 211 '8', '9', '+', '/' }; 212 213 private int col = 0; 214 215 private int i = 0; 216 217 private int[] inbuf = new int[3]; 218} 219 220 221