001/* 002 * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/Util.java $ 003 * $Revision: 166 $ 004 * $Date: 2014-04-28 11:40:25 -0700 (Mon, 28 Apr 2014) $ 005 * 006 * ==================================================================== 007 * Licensed to the Apache Software Foundation (ASF) under one 008 * or more contributor license agreements. See the NOTICE file 009 * distributed with this work for additional information 010 * regarding copyright ownership. The ASF licenses this file 011 * to you under the Apache License, Version 2.0 (the 012 * "License"); you may not use this file except in compliance 013 * with the License. You may obtain a copy of the License at 014 * 015 * http://www.apache.org/licenses/LICENSE-2.0 016 * 017 * Unless required by applicable law or agreed to in writing, 018 * software distributed under the License is distributed on an 019 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 020 * KIND, either express or implied. See the License for the 021 * specific language governing permissions and limitations 022 * under the License. 023 * ==================================================================== 024 * 025 * This software consists of voluntary contributions made by many 026 * individuals on behalf of the Apache Software Foundation. For more 027 * information on the Apache Software Foundation, please see 028 * <http://www.apache.org/>. 029 * 030 */ 031 032package org.apache.commons.ssl; 033 034import org.apache.commons.ssl.util.ByteArrayReadLine; 035import org.apache.commons.ssl.util.IPAddressParser; 036 037import java.io.ByteArrayInputStream; 038import java.io.IOException; 039import java.io.InputStream; 040import java.io.OutputStream; 041import java.net.InetAddress; 042import java.net.UnknownHostException; 043import java.util.LinkedList; 044import java.util.Map; 045import java.util.StringTokenizer; 046import java.util.TreeMap; 047 048/** 049 * @author Credit Union Central of British Columbia 050 * @author <a href="http://www.cucbc.com/">www.cucbc.com</a> 051 * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a> 052 * @since 28-Feb-2006 053 */ 054public class Util { 055 public final static int SIZE_KEY = 0; 056 public final static int LAST_READ_KEY = 1; 057 058 public static boolean isYes(String yesString) { 059 if (yesString == null) { 060 return false; 061 } 062 String s = yesString.trim().toUpperCase(); 063 return "1".equals(s) || "YES".equals(s) || "TRUE".equals(s) || 064 "ENABLE".equals(s) || "ENABLED".equals(s) || "Y".equals(s) || 065 "ON".equals(s); 066 } 067 068 public static String trim(final String s) { 069 if (s == null || "".equals(s)) { 070 return s; 071 } 072 int i = 0; 073 int j = s.length() - 1; 074 while (isWhiteSpace(s.charAt(i))) { 075 i++; 076 } 077 while (isWhiteSpace(s.charAt(j))) { 078 j--; 079 } 080 return j >= i ? s.substring(i, j + 1) : ""; 081 } 082 083 public static boolean isWhiteSpace(final char c) { 084 switch (c) { 085 case 0: 086 case ' ': 087 case '\t': 088 case '\n': 089 case '\r': 090 case '\f': 091 return true; 092 default: 093 return false; 094 } 095 } 096 097 public static void pipeStream(InputStream in, OutputStream out) 098 throws IOException { 099 pipeStream(in, out, true); 100 } 101 102 public static void pipeStream(InputStream in, OutputStream out, 103 boolean autoClose) 104 throws IOException { 105 byte[] buf = new byte[8192]; 106 IOException ioe = null; 107 try { 108 int bytesRead = in.read(buf); 109 while (bytesRead >= 0) { 110 if (bytesRead > 0) { 111 out.write(buf, 0, bytesRead); 112 } 113 bytesRead = in.read(buf); 114 } 115 } 116 finally { 117 // Probably it's best to let consumer call "close", but I'm usually 118 // the consumer, and I want to be lazy. [Julius, November 20th, 2006] 119 try { in.close(); } catch (IOException e) { ioe = e; } 120 if (autoClose) { 121 try { out.close(); } catch (IOException e) { ioe = e; } 122 } 123 } 124 if (ioe != null) { 125 throw ioe; 126 } 127 } 128 129 public static byte[] streamToBytes(final ByteArrayInputStream in, 130 int maxLength) { 131 byte[] buf = new byte[maxLength]; 132 int[] status = fill(buf, 0, in); 133 int size = status[SIZE_KEY]; 134 if (buf.length != size) { 135 byte[] smallerBuf = new byte[size]; 136 System.arraycopy(buf, 0, smallerBuf, 0, size); 137 buf = smallerBuf; 138 } 139 return buf; 140 } 141 142 public static byte[] streamToBytes(final InputStream in, int maxLength) 143 throws IOException { 144 byte[] buf = new byte[maxLength]; 145 int[] status = fill(buf, 0, in); 146 int size = status[SIZE_KEY]; 147 if (buf.length != size) { 148 byte[] smallerBuf = new byte[size]; 149 System.arraycopy(buf, 0, smallerBuf, 0, size); 150 buf = smallerBuf; 151 } 152 return buf; 153 } 154 155 public static byte[] streamToBytes(final InputStream in) throws IOException { 156 byte[] buf = new byte[4096]; 157 try { 158 int[] status = fill(buf, 0, in); 159 int size = status[SIZE_KEY]; 160 int lastRead = status[LAST_READ_KEY]; 161 while (lastRead != -1) { 162 buf = resizeArray(buf); 163 status = fill(buf, size, in); 164 size = status[SIZE_KEY]; 165 lastRead = status[LAST_READ_KEY]; 166 } 167 if (buf.length != size) { 168 byte[] smallerBuf = new byte[size]; 169 System.arraycopy(buf, 0, smallerBuf, 0, size); 170 buf = smallerBuf; 171 } 172 } 173 finally { 174 in.close(); 175 } 176 return buf; 177 } 178 179 public static byte[] streamToBytes(final ByteArrayInputStream in) { 180 byte[] buf = new byte[4096]; 181 int[] status = fill(buf, 0, in); 182 int size = status[SIZE_KEY]; 183 int lastRead = status[LAST_READ_KEY]; 184 while (lastRead != -1) { 185 buf = resizeArray(buf); 186 status = fill(buf, size, in); 187 size = status[SIZE_KEY]; 188 lastRead = status[LAST_READ_KEY]; 189 } 190 if (buf.length != size) { 191 byte[] smallerBuf = new byte[size]; 192 System.arraycopy(buf, 0, smallerBuf, 0, size); 193 buf = smallerBuf; 194 } 195 // in.close(); <-- this is a no-op on ByteArrayInputStream. 196 return buf; 197 } 198 199 public static int[] fill(final byte[] buf, final int offset, 200 final InputStream in) 201 throws IOException { 202 int read = in.read(buf, offset, buf.length - offset); 203 int lastRead = read; 204 if (read == -1) { 205 read = 0; 206 } 207 while (lastRead != -1 && read + offset < buf.length) { 208 lastRead = in.read(buf, offset + read, buf.length - read - offset); 209 if (lastRead != -1) { 210 read += lastRead; 211 } 212 } 213 return new int[]{offset + read, lastRead}; 214 } 215 216 public static int[] fill(final byte[] buf, final int offset, 217 final ByteArrayInputStream in) { 218 int read = in.read(buf, offset, buf.length - offset); 219 int lastRead = read; 220 if (read == -1) { 221 read = 0; 222 } 223 while (lastRead != -1 && read + offset < buf.length) { 224 lastRead = in.read(buf, offset + read, buf.length - read - offset); 225 if (lastRead != -1) { 226 read += lastRead; 227 } 228 } 229 return new int[]{offset + read, lastRead}; 230 } 231 232 public static byte[] resizeArray(final byte[] bytes) { 233 byte[] biggerBytes = new byte[bytes.length * 2]; 234 System.arraycopy(bytes, 0, biggerBytes, 0, bytes.length); 235 return biggerBytes; 236 } 237 238 public static String pad(String s, final int length, final boolean left) { 239 if (s == null) { 240 s = ""; 241 } 242 int diff = length - s.length(); 243 if (diff == 0) { 244 return s; 245 } else if (diff > 0) { 246 StringBuffer sb = new StringBuffer(); 247 if (left) { 248 for (int i = 0; i < diff; i++) { 249 sb.append(' '); 250 } 251 } 252 sb.append(s); 253 if (!left) { 254 for (int i = 0; i < diff; i++) { 255 sb.append(' '); 256 } 257 } 258 return sb.toString(); 259 } else { 260 return s; 261 } 262 } 263 264 public static Map parseArgs(final String[] cargs) { 265 Map args = new TreeMap(); 266 Map ARGS_MATCH = Ping.ARGS_MATCH; 267 268 int l = cargs.length; 269 final String[] EMPTY_VALUES = {""}; 270 for (int i = 0; i < l; i++) { 271 String k = cargs[i]; 272 Ping.Arg a = (Ping.Arg) ARGS_MATCH.get(k); 273 if (l > i + 1) { 274 String v = cargs[++i]; 275 while (ARGS_MATCH.containsKey(v)) { 276 args.put(a, EMPTY_VALUES); 277 a = (Ping.Arg) ARGS_MATCH.get(v); 278 v = ""; 279 if (l > i + 1) { 280 v = cargs[++i]; 281 } 282 } 283 String[] values = new String[1]; 284 values[0] = v; 285 args.put(a, values); 286 if (l > i + 1 && !ARGS_MATCH.containsKey(cargs[i + 1])) { 287 LinkedList list = new LinkedList(); 288 list.add(v); 289 while (l > i + 1 && !ARGS_MATCH.containsKey(cargs[i + 1])) { 290 v = cargs[++i]; 291 list.add(v); 292 } 293 args.put(a, list.toArray(new String[list.size()])); 294 } 295 } else { 296 args.put(a, EMPTY_VALUES); 297 } 298 } 299 return args; 300 } 301 302 public static HostPort toAddress(final String target, 303 final int defaultPort) 304 throws UnknownHostException { 305 String host = target; 306 int port = defaultPort; 307 StringTokenizer st = new StringTokenizer(target, ":"); 308 if (st.hasMoreTokens()) { 309 host = st.nextToken().trim(); 310 } 311 if (st.hasMoreTokens()) { 312 port = Integer.parseInt(st.nextToken().trim()); 313 } 314 if (st.hasMoreTokens()) { 315 throw new IllegalArgumentException("Invalid host: " + target); 316 } 317 return new HostPort(host, port); 318 } 319 320 public static String cipherToAuthType(String cipher) { 321 if (cipher == null) { 322 return null; 323 } 324 325 // SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA ==> "DHE_DSS_EXPORT" 326 // SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA ==> "DHE_DSS" 327 // SSL_RSA_WITH_3DES_EDE_CBC_SHA ==> "RSA" 328 329 StringTokenizer st = new StringTokenizer(cipher.trim(), "_"); 330 if (st.hasMoreTokens()) { 331 st.nextToken(); // always skip first token 332 } 333 if (st.hasMoreTokens()) { 334 String tok = st.nextToken(); 335 StringBuffer buf = new StringBuffer(); 336 buf.append(tok); 337 if (st.hasMoreTokens()) { 338 tok = st.nextToken(); 339 while (!"WITH".equalsIgnoreCase(tok)) { 340 buf.append('_'); 341 buf.append(tok); 342 tok = st.nextToken(); 343 } 344 } 345 return buf.toString(); 346 } 347 throw new IllegalArgumentException("not a valid cipher: " + cipher); 348 } 349 350 /** 351 * Utility method to make sure IP-literals don't trigger reverse-DNS lookups. 352 */ 353 public static InetAddress toInetAddress(String s) throws UnknownHostException { 354 byte[] ip = IPAddressParser.parseIPv4Literal(s); 355 if (ip == null) { 356 ip = IPAddressParser.parseIPv6Literal(s); 357 } 358 if (ip != null) { 359 // Strangely, this prevents Java's annoying SSL reverse-DNS lookup that it 360 // normally does, even with literal IP addresses. 361 return InetAddress.getByAddress(s, ip); 362 } else { 363 return InetAddress.getByName(s); 364 } 365 } 366 367 public static void main(String[] args) throws Exception { 368 String s = "line1\n\rline2\n\rline3"; 369 ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes()); 370 ByteArrayReadLine readLine = new ByteArrayReadLine(in); 371 String line = readLine.next(); 372 while (line != null) { 373 System.out.println(line); 374 line = readLine.next(); 375 } 376 377 System.out.println("--------- test 2 ----------"); 378 379 s = "line1\n\rline2\n\rline3\n\r\n\r"; 380 in = new ByteArrayInputStream(s.getBytes()); 381 readLine = new ByteArrayReadLine(in); 382 line = readLine.next(); 383 while (line != null) { 384 System.out.println(line); 385 line = readLine.next(); 386 } 387 388 } 389 390 391}