1 19 20 package com.maverick.ssl.https; 21 22 import java.io.BufferedOutputStream ; 23 import java.io.ByteArrayOutputStream ; 24 import java.io.DataInputStream ; 25 import java.io.DataOutputStream ; 26 import java.io.IOException ; 27 import java.io.InputStream ; 28 import java.io.OutputStream ; 29 import java.io.PushbackInputStream ; 30 import java.net.HttpURLConnection ; 31 import java.net.Socket ; 32 import java.net.URL ; 33 import java.text.MessageFormat ; 34 import java.text.SimpleDateFormat ; 35 import java.util.Date ; 36 import java.util.Hashtable ; 37 import java.util.StringTokenizer ; 38 import java.util.TimeZone ; 39 import java.util.Vector ; 40 41 import com.maverick.http.AuthenticationCancelledException; 42 import com.maverick.http.ConnectMethod; 43 import com.maverick.http.HttpClient; 44 import com.maverick.http.HttpException; 45 import com.maverick.http.HttpMethod; 46 import com.maverick.http.HttpResponse; 47 import com.maverick.http.PasswordCredentials; 48 import com.maverick.http.UnsupportedAuthenticationException; 49 import com.maverick.ssl.SSLException; 50 import com.maverick.ssl.SSLIOException; 51 import com.maverick.ssl.SSLSocket; 52 53 57 public class HttpsURLConnection extends HttpURLConnection { 58 59 boolean debugging; 60 ByteArrayOutputStream output = new ByteArrayOutputStream (); 61 Vector requestKeys, requestValues; 62 Vector headers = new Vector (), headerKeys = new Vector (); 63 Hashtable headerValues = new Hashtable (); 64 Socket socket; 65 PushbackInputStream input; 66 int responseCode = -1; 67 String responseMessage; 68 69 76 77 static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(HttpsURLConnection.class); 79 81 public static final String httpProxyHostProperty = "com.maverick.ssl.https.HTTPProxyHostname"; public static final String httpProxyPortProperty = "com.maverick.ssl.https.HTTPProxyPort"; public static final String httpProxyUsernameProperty = "com.maverick.ssl.https.HTTPProxyUsername"; public static final String httpProxyPasswordProperty = "com.maverick.ssl.https.HTTPProxyPassword"; public static final String httpProxySecureProperty = "com.maverick.ssl.https.HTTPProxySecure"; public static final String httpProxyNonProxyHostsProperty = "com.maverick.ssl.https.HTTPProxyNonProxyHosts"; 88 static Vector defaultRequestKeys = new Vector (), defaultRequestValues = new Vector (); 89 90 static { 91 defaultRequestKeys.addElement("User-agent"); defaultRequestValues.addElement(HttpClient.USER_AGENT); 93 } 94 95 public HttpsURLConnection(URL url) { 96 super(url); 97 synchronized (defaultRequestKeys) { 98 requestKeys = (Vector ) defaultRequestKeys.clone(); 99 requestValues = (Vector ) defaultRequestValues.clone(); 100 } 101 } 102 103 public void addRequestProperty(String name, String value) { 104 setRequestProperty(name, value); 105 } 106 107 public static void setDefaultRequestProperty(String key, String value) { 108 synchronized (defaultRequestKeys) { 109 int i = 0; 110 while ((i < defaultRequestKeys.size()) && !(key.equalsIgnoreCase((String ) defaultRequestKeys.elementAt(i)))) { 111 ++i; 112 } 113 if (i < defaultRequestKeys.size()) { 114 defaultRequestValues.removeElementAt(i); 115 defaultRequestKeys.removeElementAt(i); 116 } 117 if (value != null) { 118 defaultRequestValues.addElement(value); 119 defaultRequestKeys.addElement(key); 120 } 121 } 122 } 123 124 public static String getDefaultRequestProperty(String key) { 125 synchronized (defaultRequestKeys) { 126 int i = 0; 127 while ((i < defaultRequestKeys.size()) && !(key.equalsIgnoreCase((String ) defaultRequestKeys.elementAt(i)))) { 128 ++i; 129 } 130 if (i < defaultRequestKeys.size()) { 131 return (String ) defaultRequestValues.elementAt(i); 132 } else { 133 return null; 134 } 135 } 136 } 137 138 public synchronized void setRequestProperty(String key, String value) { 139 if (connected) { 140 throw new IllegalStateException (Messages.getString("HttpsURLConnection.alreadyConnected")); } 142 int i = 0; 143 while ((i < requestKeys.size()) && !(key.equalsIgnoreCase((String ) requestKeys.elementAt(i)))) { 144 ++i; 145 } 146 if (i < requestKeys.size()) { 147 requestValues.removeElementAt(i); 148 requestKeys.removeElementAt(i); 149 } 150 if (value != null) { 151 requestValues.addElement(value); 152 requestKeys.addElement(key); 153 } 154 } 155 156 public String getRequestProperty(String key) { 157 int i = 0; 158 while ((i < requestKeys.size()) && !(key.equalsIgnoreCase((String ) requestKeys.elementAt(i)))) { 159 ++i; 160 } 161 if (i < requestKeys.size()) { 162 return (String ) requestValues.elementAt(i); 163 } else { 164 return null; 165 } 166 } 167 168 public OutputStream getOutputStream() throws IOException { 169 if (!doOutput) { 170 throw new IOException (Messages.getString("HttpsURLConnection.protocolOutputNotConfigured")); } 172 if (connected) { 173 throw new IOException (Messages.getString("HttpsURLConnection.alreadyConnected")); } 175 return output; 176 } 177 178 private boolean isNonProxiedHost(String host) { 179 String nonProxiedHosts = System.getProperty(httpProxyNonProxyHostsProperty); 180 if (nonProxiedHosts == null || nonProxiedHosts.equals("")) { return false; 182 } 183 StringTokenizer t = new StringTokenizer (nonProxiedHosts, "|"); while (t.hasMoreTokens()) { 186 if (host.equalsIgnoreCase(t.nextToken())) { 187 return true; 188 } 189 } 190 return false; 191 } 192 193 public synchronized void connect() throws IOException { 194 195 if (!connected) { 196 197 log.info(MessageFormat.format(Messages.getString("HttpsURLConnection.connecting"), new Object [] { url.getHost(), new Integer (url.getPort() == -1 ? 443 : url.getPort()) })); 201 String proxyHost = System.getProperty(httpProxyHostProperty); 202 if (proxyHost != null && !isNonProxiedHost(url.getHost())) { 203 204 boolean isSecure = Boolean.valueOf(System.getProperty(httpProxySecureProperty, "true")).booleanValue(); String proxyPort = System.getProperty(httpProxyPortProperty); 206 String proxyUsername = System.getProperty(httpProxyUsernameProperty); 207 String proxyPassword = System.getProperty(httpProxyPasswordProperty); 208 209 log.info(MessageFormat.format(Messages.getString("HttpsURLConnection.requiresProxyConnection"), new Object [] { isSecure ? "https" : "http://", proxyHost, new Integer (proxyPort) })); log.info(MessageFormat.format(Messages.getString("HttpsURLConnection.proxyUsername"), new Object [] { proxyUsername == null || proxyUsername.equals("") ? "not set" : proxyUsername })); if (proxyPort == null) { 214 throw new IOException (Messages.getString("HttpsURLConnection.noProxyPort")); } 216 217 try { 218 int port = Integer.parseInt(proxyPort); 219 220 HttpClient client = new HttpClient(proxyHost, port, isSecure); 221 HttpMethod method = new ConnectMethod(url.getHost(), url.getPort() == -1 ? 443 : url.getPort(), true); 222 223 PasswordCredentials credentials = new PasswordCredentials(); 224 credentials.setUsername(proxyUsername); 225 credentials.setPassword(proxyPassword); 226 227 client.setCredentials(credentials); 228 229 HttpResponse response = client.execute(method); 230 socket = response.getConnection().getSocket(); 231 } catch (HttpException ex) { 232 log.info(MessageFormat.format(Messages.getString("HttpsURLConnection.proxyConnectionFailed"), new Object [] { ex.getMessage(), new Integer (ex.getStatus()) })); throw new IOException (MessageFormat.format(Messages.getString("HttpsURLConnection.proxyConnectionFailed"), new Object [] { ex.getMessage(), new Integer (ex.getStatus()) })); } catch (UnsupportedAuthenticationException ex) { 237 log.info(Messages.getString("HttpsURLConnection.proxyAuthenticationFailed"), ex); throw new IOException (ex.getMessage()); 241 } catch (AuthenticationCancelledException ex) { 242 throw new IOException (Messages.getString("HttpsURLConnection.userCancelledAuthenitcation")); } 244 } else { 245 String host = url.getHost(); 246 if (host == null) { 247 throw new IOException (Messages.getString("HttpsURLConnection.noHost")); } 249 int port = url.getPort(); 250 try { 251 socket = new SSLSocket(host, port == -1 ? 443 : port); 252 } catch (SSLException ex1) { 253 throw new SSLIOException(ex1); 254 } 255 } 256 257 try { 258 writeRequest(socket.getOutputStream()); 259 readResponse(input = new PushbackInputStream (socket.getInputStream(), 2048)); 260 } catch (IOException ex) { 261 try { 262 socket.close(); 263 } catch (IOException ignored) { 264 } 265 throw ex; 266 } 267 connected = true; 268 } 269 } 270 271 void writeRequest(OutputStream out) throws IOException { 272 DataOutputStream data = new DataOutputStream (new BufferedOutputStream (out)); 273 if ((doOutput) && (output == null)) { 274 throw new IOException (Messages.getString("HttpsURLConnection.noPOSTData")); } 276 if (ifModifiedSince != 0) { 277 Date date = new Date (ifModifiedSince); 278 SimpleDateFormat formatter = new SimpleDateFormat ("EEE, d MMM yyyy hh:mm:ss z"); formatter.setTimeZone(TimeZone.getTimeZone("GMT")); setRequestProperty("If-Modified-Since", formatter.format(date)); } 282 if (doOutput) { 283 setRequestProperty("Content-length", "" + output.size()); } 285 286 data.writeBytes((doOutput ? "POST" : "GET") + " " + (url.getFile().equals("") ? "/" : url.getFile()) + " HTTP/1.0\r\n"); 288 for (int i = 0; i < requestKeys.size(); ++i) { 289 String key = (String ) requestKeys.elementAt(i); 290 if (!key.startsWith("Proxy-")) { data.writeBytes(key + ": " + requestValues.elementAt(i) + "\r\n"); } 293 } 294 data.writeBytes("\r\n"); data.flush(); 296 if (doOutput) { 297 output.writeTo(out); 298 } 299 out.flush(); 300 } 301 302 void readResponse(PushbackInputStream in) throws IOException { 303 DataInputStream data = new DataInputStream (in); 304 String line; 305 while (((line = data.readLine()) != null) && (line.length() > 0)) { 306 headers.addElement(line); 307 int index = line.indexOf(':'); 308 if (index >= 0) { 309 String key = line.substring(0, index); 310 String value = line.substring(index + 1).trim(); 311 headerKeys.addElement(key); 312 headerValues.put(key.toLowerCase(), value); 313 } else { 314 if (headerValues.size() == 0) { 317 318 if (line.startsWith("HTTP/")) { try { 321 int idx = line.indexOf(' '); 322 while (line.charAt(++idx) == ' ') { 323 ; 324 } 325 responseMessage = line.substring(idx + 4); 326 responseCode = Integer.parseInt(line.substring(idx, idx + 3)); 327 } catch (Throwable t) { 328 responseCode = 200; 329 } 330 } else { 331 responseCode = 200; 333 byte[] unread = line.getBytes(); 334 in.unread(unread); 335 break; 336 } 337 338 } 339 } 340 } 341 } 342 343 public int getResponseCode() { 344 if (!connected) { 345 throw new IllegalStateException (Messages.getString("HttpsURLConnection.notConnected")); } 347 return responseCode; 370 } 371 372 public String getResponseMessage() { 373 if (!connected) { 374 throw new IllegalStateException (Messages.getString("HttpsURLConnection.notConnected")); } 376 getResponseCode(); 377 return responseMessage; 378 } 379 380 public String getHeaderField(String name) { 381 if (!connected) { 382 throw new IllegalStateException (Messages.getString("HttpsURLConnection.notConnected")); } 384 return (String ) headerValues.get(name.toLowerCase()); 385 } 386 387 public String getHeaderFieldKey(int n) { 388 if (!connected) { 389 throw new IllegalStateException (Messages.getString("HttpsURLConnection.notConnected")); } 391 if (n < headerKeys.size()) { 392 return (String ) headerKeys.elementAt(n); 393 } else { 394 return null; 395 } 396 } 397 398 public String getHeaderField(int n) { 399 if (!connected) { 400 throw new IllegalStateException (Messages.getString("HttpsURLConnection.notConnected")); } 402 if (n < headers.size()) { 403 return (String ) headers.elementAt(n); 404 } else { 405 return null; 406 } 407 } 408 409 public InputStream getInputStream() throws IOException { 410 if (!doInput) { 411 throw new IOException (Messages.getString("HttpsURLConnection.protocolInputNotConfigured")); } 413 connect(); 414 return input; 415 } 416 417 public Socket getSocket() { 418 if (!connected) { 419 throw new IllegalStateException (Messages.getString("HttpsURLConnection.notConnected")); } 421 return socket; 422 } 423 424 public void disconnect() { 425 426 } 427 428 public boolean usingProxy() { 429 return System.getProperty(httpProxyHostProperty) != null; 430 } 431 } 432 | Popular Tags |