HttpsURLConnectionTest.java revision f33eae7e84eb6d3b0f4e86b59605bb3de73009f3
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package org.apache.harmony.luni.tests.internal.net.www.protocol.https; 19 20import dalvik.annotation.AndroidOnly; 21import dalvik.annotation.BrokenTest; 22import dalvik.annotation.KnownFailure; 23import dalvik.annotation.TestLevel; 24import dalvik.annotation.TestTargetClass; 25import dalvik.annotation.TestTargetNew; 26import dalvik.annotation.TestTargets; 27import junit.framework.TestCase; 28import tests.util.TestEnvironment; 29 30import javax.net.ssl.HostnameVerifier; 31import javax.net.ssl.HttpsURLConnection; 32import javax.net.ssl.KeyManagerFactory; 33import javax.net.ssl.SSLContext; 34import javax.net.ssl.SSLServerSocket; 35import javax.net.ssl.SSLSession; 36import javax.net.ssl.SSLSocket; 37import javax.net.ssl.SSLSocketFactory; 38import javax.net.ssl.TrustManagerFactory; 39import java.io.BufferedInputStream; 40import java.io.File; 41import java.io.FileInputStream; 42import java.io.FileNotFoundException; 43import java.io.FileOutputStream; 44import java.io.IOException; 45import java.io.InputStream; 46import java.io.OutputStream; 47import java.io.PrintStream; 48import java.net.Authenticator; 49import java.net.HttpURLConnection; 50import java.net.InetSocketAddress; 51import java.net.PasswordAuthentication; 52import java.net.Proxy; 53import java.net.ServerSocket; 54import java.net.Socket; 55import java.net.URL; 56import java.security.KeyStore; 57import java.security.cert.Certificate; 58import java.util.Arrays; 59import java.util.concurrent.Callable; 60import java.util.concurrent.ExecutionException; 61import java.util.concurrent.ExecutorService; 62import java.util.concurrent.Executors; 63import java.util.concurrent.Future; 64import java.util.concurrent.TimeUnit; 65 66/** 67 * Implementation independent test for HttpsURLConnection. 68 * The test needs certstore file placed in system classpath 69 * and named as "key_store." + the type of the 70 * default KeyStore installed in the system in lower case. 71 * <br> 72 * For example: if default KeyStore type in the system is BKS 73 * (i.e. java.security file sets up the property keystore.type=BKS), 74 * thus classpath should point to the directory with "key_store.bks" 75 * file. 76 * <br> 77 * This certstore file should contain self-signed certificate 78 * generated by keytool utility in a usual way. 79 * <br> 80 * The password to the certstore should be "password" (without quotes). 81 */ 82@TestTargetClass(HttpsURLConnection.class) 83public class HttpsURLConnectionTest extends TestCase { 84 85 // the password to the store 86 private static final String KS_PASSWORD = "password"; 87 88 // turn on/off logging 89 private static final boolean DO_LOG = false; 90 91 // read/connection timeout value 92 private static final int TIMEOUT = 5000; 93 94 // OK response code 95 private static final int OK_CODE = 200; 96 97 // Not Found response code 98 private static final int NOT_FOUND_CODE = 404; 99 100 // Proxy authentication required response code 101 private static final int AUTHENTICATION_REQUIRED_CODE = 407; 102 103 private static File store; 104 105 static { 106 try { 107 store = File.createTempFile("key_store", "bks"); 108 } catch (Exception e) { 109 // ignore 110 } 111 } 112 113 /** 114 * Checks that HttpsURLConnection's default SSLSocketFactory is operable. 115 */ 116 @TestTargetNew( 117 level = TestLevel.PARTIAL_COMPLETE, 118 notes = "Verifies that HttpsURLConnection's default SSLSocketFactory is operable.", 119 method = "getDefaultSSLSocketFactory", 120 args = {} 121 ) 122 @AndroidOnly("we only have a .bks key store in the test resources") 123 public void testGetDefaultSSLSocketFactory() throws Exception { 124 // set up the properties defining the default values needed by SSL stuff 125 setUpStoreProperties(); 126 127 SSLSocketFactory defaultSSLSF = HttpsURLConnection 128 .getDefaultSSLSocketFactory(); 129 ServerSocket ss = new ServerSocket(0); 130 Socket s = defaultSSLSF 131 .createSocket("localhost", ss.getLocalPort()); 132 ss.accept(); 133 s.close(); 134 ss.close(); 135 } 136 137 /** 138 * Checks if HTTPS connection performs initial SSL handshake with the 139 * server working over SSL, sends encrypted HTTP request, 140 * and receives expected HTTP response. After HTTPS session if finished 141 * test checks connection state parameters established by 142 * HttpsURLConnection. 143 */ 144 @TestTargetNew( 145 level = TestLevel.PARTIAL_COMPLETE, 146 notes = "Verifies if HTTPS connection performs initial SSL handshake with the server working over SSL, sends encrypted HTTP request, and receives expected HTTP response.", 147 method = "setDefaultHostnameVerifier", 148 args = {javax.net.ssl.HostnameVerifier.class} 149 ) 150 public void testHttpsConnection() throws Throwable { 151 // set up the properties defining the default values needed by SSL stuff 152 setUpStoreProperties(); 153 154 // create the SSL server socket acting as a server 155 SSLContext ctx = getContext(); 156 ServerSocket ss = ctx.getServerSocketFactory() 157 .createServerSocket(0); 158 159 // create the HostnameVerifier to check hostname verification 160 TestHostnameVerifier hnv = new TestHostnameVerifier(); 161 HttpsURLConnection.setDefaultHostnameVerifier(hnv); 162 163 // create url connection to be tested 164 URL url = new URL("https://localhost:" + ss.getLocalPort()); 165 HttpsURLConnection connection = (HttpsURLConnection) url 166 .openConnection(); 167 168 // perform the interaction between the peers 169 SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss); 170 171 // check the connection state 172 checkConnectionStateParameters(connection, peerSocket); 173 174 // should silently exit 175 connection.connect(); 176 } 177 178 /** 179 * Tests the behaviour of HTTPS connection in case of unavailability 180 * of requested resource. 181 */ 182 @TestTargets({ 183 @TestTargetNew( 184 level = TestLevel.PARTIAL, 185 notes = "Verifies the behaviour of HTTPS connection in case of unavailability of requested resource.", 186 method = "setDoInput", 187 args = {boolean.class} 188 ), 189 @TestTargetNew( 190 level = TestLevel.PARTIAL, 191 notes = "Verifies the behaviour of HTTPS connection in case of unavailability of requested resource.", 192 method = "setConnectTimeout", 193 args = {int.class} 194 ), 195 @TestTargetNew( 196 level = TestLevel.PARTIAL, 197 notes = "Verifies the behaviour of HTTPS connection in case of unavailability of requested resource.", 198 method = "setReadTimeout", 199 args = {int.class} 200 ) 201 }) 202 public void testHttpsConnection_Not_Found_Response() throws Throwable { 203 // set up the properties defining the default values needed by SSL stuff 204 setUpStoreProperties(); 205 206 // create the SSL server socket acting as a server 207 SSLContext ctx = getContext(); 208 ServerSocket ss = ctx.getServerSocketFactory() 209 .createServerSocket(0); 210 211 // create the HostnameVerifier to check hostname verification 212 TestHostnameVerifier hnv = new TestHostnameVerifier(); 213 HttpsURLConnection.setDefaultHostnameVerifier(hnv); 214 215 // create url connection to be tested 216 URL url = new URL("https://localhost:" + ss.getLocalPort()); 217 HttpsURLConnection connection = (HttpsURLConnection) url 218 .openConnection(); 219 220 try { 221 doInteraction(connection, ss, NOT_FOUND_CODE); 222 fail("Expected exception was not thrown."); 223 } catch (FileNotFoundException e) { 224 if (DO_LOG) { 225 System.out.println("Expected exception was thrown: " 226 + e.getMessage()); 227 } 228 } 229 230 // should silently exit 231 connection.connect(); 232 } 233 234 /** 235 * Tests possibility to set up the default SSLSocketFactory 236 * to be used by HttpsURLConnection. 237 */ 238 @TestTargetNew( 239 level = TestLevel.PARTIAL_COMPLETE, 240 notes = "Verifies possibility to set up the default SSLSocketFactory to be used by HttpsURLConnection.", 241 method = "setDefaultSSLSocketFactory", 242 args = {javax.net.ssl.SSLSocketFactory.class} 243 ) 244 public void testSetDefaultSSLSocketFactory() throws Throwable { 245 // create the SSLServerSocket which will be used by server side 246 SSLContext ctx = getContext(); 247 SSLServerSocket ss = (SSLServerSocket) ctx.getServerSocketFactory() 248 .createServerSocket(0); 249 250 SSLSocketFactory socketFactory = (SSLSocketFactory) ctx 251 .getSocketFactory(); 252 // set up the factory as default 253 HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory); 254 // check the result 255 assertSame("Default SSLSocketFactory differs from expected", 256 socketFactory, HttpsURLConnection.getDefaultSSLSocketFactory()); 257 258 // create the HostnameVerifier to check hostname verification 259 TestHostnameVerifier hnv = new TestHostnameVerifier(); 260 HttpsURLConnection.setDefaultHostnameVerifier(hnv); 261 262 // create HttpsURLConnection to be tested 263 URL url = new URL("https://localhost:" + ss.getLocalPort()); 264 HttpsURLConnection connection = (HttpsURLConnection) url 265 .openConnection(); 266 267 TestHostnameVerifier hnv_late = new TestHostnameVerifier(); 268 // late initialization: should not be used for created connection 269 HttpsURLConnection.setDefaultHostnameVerifier(hnv_late); 270 271 // perform the interaction between the peers 272 SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss); 273 // check the connection state 274 checkConnectionStateParameters(connection, peerSocket); 275 // check the verification process 276 assertTrue("Hostname verification was not done", hnv.verified); 277 assertFalse( 278 "Hostname verification should not be done by this verifier", 279 hnv_late.verified); 280 // check the used SSLSocketFactory 281 assertSame("Default SSLSocketFactory should be used", 282 HttpsURLConnection.getDefaultSSLSocketFactory(), connection 283 .getSSLSocketFactory()); 284 285 // should silently exit 286 connection.connect(); 287 } 288 289 /** 290 * Tests possibility to set up the SSLSocketFactory 291 * to be used by HttpsURLConnection. 292 */ 293 @TestTargetNew( 294 level = TestLevel.PARTIAL_COMPLETE, 295 notes = "Verifies possibility to set up the SSLSocketFactory to be used by HttpsURLConnection.", 296 method = "setSSLSocketFactory", 297 args = {javax.net.ssl.SSLSocketFactory.class} 298 ) 299 public void testSetSSLSocketFactory() throws Throwable { 300 // create the SSLServerSocket which will be used by server side 301 SSLContext ctx = getContext(); 302 SSLServerSocket ss = (SSLServerSocket) ctx.getServerSocketFactory() 303 .createServerSocket(0); 304 305 // create the HostnameVerifier to check hostname verification 306 TestHostnameVerifier hnv = new TestHostnameVerifier(); 307 HttpsURLConnection.setDefaultHostnameVerifier(hnv); 308 309 // create HttpsURLConnection to be tested 310 URL url = new URL("https://localhost:" + ss.getLocalPort()); 311 HttpsURLConnection connection = (HttpsURLConnection) url 312 .openConnection(); 313 314 SSLSocketFactory socketFactory = (SSLSocketFactory) ctx 315 .getSocketFactory(); 316 connection.setSSLSocketFactory(socketFactory); 317 318 TestHostnameVerifier hnv_late = new TestHostnameVerifier(); 319 // late initialization: should not be used for created connection 320 HttpsURLConnection.setDefaultHostnameVerifier(hnv_late); 321 322 // perform the interaction between the peers 323 SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss); 324 // check the connection state 325 checkConnectionStateParameters(connection, peerSocket); 326 // check the verification process 327 assertTrue("Hostname verification was not done", hnv.verified); 328 assertFalse( 329 "Hostname verification should not be done by this verifier", 330 hnv_late.verified); 331 // check the used SSLSocketFactory 332 assertNotSame("Default SSLSocketFactory should not be used", 333 HttpsURLConnection.getDefaultSSLSocketFactory(), connection 334 .getSSLSocketFactory()); 335 assertSame("Result differs from expected", socketFactory, connection 336 .getSSLSocketFactory()); 337 338 // should silently exit 339 connection.connect(); 340 } 341 342 /** 343 * Tests the behaviour of HttpsURLConnection in case of retrieving 344 * of the connection state parameters before connection has been made. 345 */ 346 @TestTargets({ 347 @TestTargetNew( 348 level = TestLevel.PARTIAL_COMPLETE, 349 notes = "Verifies the behaviour of HttpsURLConnection in case of retrieving of the connection state parameters before connection has been made.", 350 method = "getCipherSuite", 351 args = {} 352 ), 353 @TestTargetNew( 354 level = TestLevel.PARTIAL_COMPLETE, 355 notes = "Verifies the behaviour of HttpsURLConnection in case of retrieving of the connection state parameters before connection has been made.", 356 method = "getPeerPrincipal", 357 args = {} 358 ), 359 @TestTargetNew( 360 level = TestLevel.PARTIAL_COMPLETE, 361 notes = "Verifies the behaviour of HttpsURLConnection in case of retrieving of the connection state parameters before connection has been made.", 362 method = "getLocalPrincipal", 363 args = {} 364 ), 365 @TestTargetNew( 366 level = TestLevel.PARTIAL_COMPLETE, 367 notes = "Verifies the behaviour of HttpsURLConnection in case of retrieving of the connection state parameters before connection has been made.", 368 method = "getServerCertificates", 369 args = {} 370 ), 371 @TestTargetNew( 372 level = TestLevel.PARTIAL_COMPLETE, 373 notes = "Verifies the behaviour of HttpsURLConnection in case of retrieving of the connection state parameters before connection has been made.", 374 method = "getLocalCertificates", 375 args = {} 376 ) 377 }) 378 @AndroidOnly("we only have a .bks key store in the test resources") 379 public void testUnconnectedStateParameters() throws Throwable { 380 // create HttpsURLConnection to be tested 381 URL url = new URL("https://localhost:55555"); 382 HttpsURLConnection connection = (HttpsURLConnection) url 383 .openConnection(); 384 385 try { 386 connection.getCipherSuite(); 387 fail("Expected IllegalStateException was not thrown"); 388 } catch (IllegalStateException e) {} 389 try { 390 connection.getPeerPrincipal(); 391 fail("Expected IllegalStateException was not thrown"); 392 } catch (IllegalStateException e) {} 393 try { 394 connection.getLocalPrincipal(); 395 fail("Expected IllegalStateException was not thrown"); 396 } catch (IllegalStateException e) {} 397 398 try { 399 connection.getServerCertificates(); 400 fail("Expected IllegalStateException was not thrown"); 401 } catch (IllegalStateException e) {} 402 try { 403 connection.getLocalCertificates(); 404 fail("Expected IllegalStateException was not thrown"); 405 } catch (IllegalStateException e) {} 406 } 407 408 /** 409 * Tests if setHostnameVerifier() method replaces default verifier. 410 */ 411 @TestTargetNew( 412 level = TestLevel.PARTIAL_COMPLETE, 413 notes = "Verifies if setHostnameVerifier() method replaces default verifier.", 414 method = "setHostnameVerifier", 415 args = {javax.net.ssl.HostnameVerifier.class} 416 ) 417 public void testSetHostnameVerifier() throws Throwable { 418 // setting up the properties pointing to the key/trust stores 419 setUpStoreProperties(); 420 421 // create the SSLServerSocket which will be used by server side 422 SSLServerSocket ss = (SSLServerSocket) getContext() 423 .getServerSocketFactory().createServerSocket(0); 424 425 // create the HostnameVerifier to check that Hostname verification 426 // is done 427 TestHostnameVerifier hnv = new TestHostnameVerifier(); 428 HttpsURLConnection.setDefaultHostnameVerifier(hnv); 429 430 // create HttpsURLConnection to be tested 431 URL url = new URL("https://localhost:" + ss.getLocalPort()); 432 HttpsURLConnection connection = (HttpsURLConnection) url 433 .openConnection(); 434 435 TestHostnameVerifier hnv_late = new TestHostnameVerifier(); 436 // replace default verifier 437 connection.setHostnameVerifier(hnv_late); 438 439 // perform the interaction between the peers and check the results 440 SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss); 441 assertTrue("Hostname verification was not done", hnv_late.verified); 442 assertFalse( 443 "Hostname verification should not be done by this verifier", 444 hnv.verified); 445 checkConnectionStateParameters(connection, peerSocket); 446 447 // should silently exit 448 connection.connect(); 449 } 450 451 /** 452 * Tests the behaviour in case of sending the data to the server. 453 */ 454 @TestTargetNew( 455 level = TestLevel.PARTIAL, 456 notes = "Verifies the behaviour in case of sending the data to the server.", 457 method = "setDoOutput", 458 args = {boolean.class} 459 ) 460 public void test_doOutput() throws Throwable { 461 // setting up the properties pointing to the key/trust stores 462 setUpStoreProperties(); 463 464 // create the SSLServerSocket which will be used by server side 465 SSLServerSocket ss = (SSLServerSocket) getContext() 466 .getServerSocketFactory().createServerSocket(0); 467 468 // create the HostnameVerifier to check that Hostname verification 469 // is done 470 TestHostnameVerifier hnv = new TestHostnameVerifier(); 471 HttpsURLConnection.setDefaultHostnameVerifier(hnv); 472 473 // create HttpsURLConnection to be tested 474 URL url = new URL("https://localhost:" + ss.getLocalPort()); 475 HttpsURLConnection connection = (HttpsURLConnection) url 476 .openConnection(); 477 connection.setDoOutput(true); 478 479 // perform the interaction between the peers and check the results 480 SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss); 481 checkConnectionStateParameters(connection, peerSocket); 482 483 // should silently exit 484 connection.connect(); 485 } 486 487 /** 488 * Tests HTTPS connection process made through the proxy server. 489 */ 490 @TestTargets({ 491 @TestTargetNew( 492 level = TestLevel.PARTIAL, 493 notes = "Verifies HTTPS connection process made through the proxy server.", 494 method = "setDoInput", 495 args = {boolean.class} 496 ), 497 @TestTargetNew( 498 level = TestLevel.PARTIAL, 499 notes = "Verifies HTTPS connection process made through the proxy server.", 500 method = "setConnectTimeout", 501 args = {int.class} 502 ), 503 @TestTargetNew( 504 level = TestLevel.PARTIAL, 505 notes = "Verifies HTTPS connection process made through the proxy server.", 506 method = "setReadTimeout", 507 args = {int.class} 508 ) 509 }) 510 public void testProxyConnection() throws Throwable { 511 // setting up the properties pointing to the key/trust stores 512 setUpStoreProperties(); 513 514 // create the SSLServerSocket which will be used by server side 515 ServerSocket ss = new ServerSocket(0); 516 517 // create the HostnameVerifier to check that Hostname verification 518 // is done 519 TestHostnameVerifier hnv = new TestHostnameVerifier(); 520 HttpsURLConnection.setDefaultHostnameVerifier(hnv); 521 522 // create HttpsURLConnection to be tested 523 URL url = new URL("https://requested.host:55556/requested.data"); 524 HttpsURLConnection connection = (HttpsURLConnection) url 525 .openConnection(new Proxy(Proxy.Type.HTTP, 526 new InetSocketAddress("localhost", ss 527 .getLocalPort()))); 528 529 // perform the interaction between the peers and check the results 530 SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss); 531 checkConnectionStateParameters(connection, peerSocket); 532 533 // should silently exit 534 connection.connect(); 535 } 536 537 /** 538 * Tests HTTPS connection process made through the proxy server. 539 * Proxy server needs authentication. 540 */ 541 @TestTargets({ 542 @TestTargetNew( 543 level = TestLevel.PARTIAL, 544 notes = "Verifies HTTPS connection process made through the proxy server. Proxy server needs authentication.", 545 method = "setDoInput", 546 args = {boolean.class} 547 ), 548 @TestTargetNew( 549 level = TestLevel.PARTIAL, 550 notes = "Verifies HTTPS connection process made through the proxy server. Proxy server needs authentication.", 551 method = "setConnectTimeout", 552 args = {int.class} 553 ), 554 @TestTargetNew( 555 level = TestLevel.PARTIAL, 556 notes = "Verifies HTTPS connection process made through the proxy server. Proxy server needs authentication.", 557 method = "setReadTimeout", 558 args = {int.class} 559 ) 560 }) 561 public void testProxyAuthConnection() throws Throwable { 562 // setting up the properties pointing to the key/trust stores 563 setUpStoreProperties(); 564 565 // create the SSLServerSocket which will be used by server side 566 ServerSocket ss = new ServerSocket(0); 567 568 // create the HostnameVerifier to check that Hostname verification 569 // is done 570 TestHostnameVerifier hnv = new TestHostnameVerifier(); 571 HttpsURLConnection.setDefaultHostnameVerifier(hnv); 572 573 Authenticator.setDefault(new Authenticator() { 574 575 protected PasswordAuthentication getPasswordAuthentication() { 576 return new PasswordAuthentication("user", "password" 577 .toCharArray()); 578 } 579 }); 580 581 // create HttpsURLConnection to be tested 582 URL url = new URL("https://requested.host:55555/requested.data"); 583 HttpsURLConnection connection = (HttpsURLConnection) url 584 .openConnection(new Proxy(Proxy.Type.HTTP, 585 new InetSocketAddress("localhost", ss 586 .getLocalPort()))); 587 588 // perform the interaction between the peers and check the results 589 SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss); 590 checkConnectionStateParameters(connection, peerSocket); 591 592 // should silently exit 593 connection.connect(); 594 } 595 596 /** 597 * Tests HTTPS connection process made through the proxy server. 598 * 2 HTTPS connections are opened for one URL. For the first time 599 * the connection is opened through one proxy, 600 * for the second time through another. 601 */ 602 @TestTargets({ 603 @TestTargetNew( 604 level = TestLevel.PARTIAL_COMPLETE, 605 notes = "Verifies HTTPS connection process made through the proxy server.", 606 method = "getCipherSuite", 607 args = {} 608 ), 609 @TestTargetNew( 610 level = TestLevel.PARTIAL_COMPLETE, 611 notes = "Verifies HTTPS connection process made through the proxy server.", 612 method = "getLocalPrincipal", 613 args = {} 614 ), 615 @TestTargetNew( 616 level = TestLevel.PARTIAL_COMPLETE, 617 notes = "Verifies HTTPS connection process made through the proxy server.", 618 method = "getPeerPrincipal", 619 args = {} 620 ) 621 }) 622 public void testConsequentProxyConnection() throws Throwable { 623 // setting up the properties pointing to the key/trust stores 624 setUpStoreProperties(); 625 626 // create the SSLServerSocket which will be used by server side 627 ServerSocket ss = new ServerSocket(0); 628 629 // create the HostnameVerifier to check that Hostname verification 630 // is done 631 TestHostnameVerifier hnv = new TestHostnameVerifier(); 632 HttpsURLConnection.setDefaultHostnameVerifier(hnv); 633 634 // create HttpsURLConnection to be tested 635 URL url = new URL("https://requested.host:55555/requested.data"); 636 HttpsURLConnection connection = (HttpsURLConnection) url 637 .openConnection(new Proxy(Proxy.Type.HTTP, 638 new InetSocketAddress("localhost", ss 639 .getLocalPort()))); 640 641 // perform the interaction between the peers and check the results 642 SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss); 643 checkConnectionStateParameters(connection, peerSocket); 644 645 // create another SSLServerSocket which will be used by server side 646 ss = new ServerSocket(0); 647 648 connection = (HttpsURLConnection) url.openConnection(new Proxy( 649 Proxy.Type.HTTP, new InetSocketAddress("localhost", ss 650 .getLocalPort()))); 651 652 // perform the interaction between the peers and check the results 653 peerSocket = (SSLSocket) doInteraction(connection, ss); 654 checkConnectionStateParameters(connection, peerSocket); 655 } 656 657 /** 658 * Tests HTTPS connection process made through the proxy server. 659 * Proxy server needs authentication. 660 * Client sends data to the server. 661 */ 662 @TestTargets({ 663 @TestTargetNew( 664 level = TestLevel.PARTIAL, 665 notes = "Verifies HTTPS connection process made through the proxy server. Proxy server needs authentication. Client sends data to the server.", 666 method = "setDoInput", 667 args = {boolean.class} 668 ), 669 @TestTargetNew( 670 level = TestLevel.PARTIAL, 671 notes = "Verifies HTTPS connection process made through the proxy server. Proxy server needs authentication. Client sends data to the server.", 672 method = "setConnectTimeout", 673 args = {int.class} 674 ), 675 @TestTargetNew( 676 level = TestLevel.PARTIAL, 677 notes = "Verifies HTTPS connection process made through the proxy server. Proxy server needs authentication. Client sends data to the server.", 678 method = "setReadTimeout", 679 args = {int.class} 680 ), 681 @TestTargetNew( 682 level = TestLevel.PARTIAL, 683 notes = "Verifies HTTPS connection process made through the proxy server. Proxy server needs authentication. Client sends data to the server.", 684 method = "setDoOutput", 685 args = {boolean.class} 686 ) 687 }) 688 public void testProxyAuthConnection_doOutput() throws Throwable { 689 // setting up the properties pointing to the key/trust stores 690 setUpStoreProperties(); 691 692 // create the SSLServerSocket which will be used by server side 693 ServerSocket ss = new ServerSocket(0); 694 695 // create the HostnameVerifier to check that Hostname verification 696 // is done 697 TestHostnameVerifier hnv = new TestHostnameVerifier(); 698 HttpsURLConnection.setDefaultHostnameVerifier(hnv); 699 700 Authenticator.setDefault(new Authenticator() { 701 702 protected PasswordAuthentication getPasswordAuthentication() { 703 return new PasswordAuthentication("user", "password" 704 .toCharArray()); 705 } 706 }); 707 708 // create HttpsURLConnection to be tested 709 URL url = new URL("https://requested.host:55554/requested.data"); 710 HttpsURLConnection connection = (HttpsURLConnection) url 711 .openConnection(new Proxy(Proxy.Type.HTTP, 712 new InetSocketAddress("localhost", ss 713 .getLocalPort()))); 714 connection.setDoOutput(true); 715 716 // perform the interaction between the peers and check the results 717 SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss, 718 OK_CODE, true); 719 checkConnectionStateParameters(connection, peerSocket); 720 } 721 722 /** 723 * Tests HTTPS connection process made through the proxy server. 724 * Proxy server needs authentication but client fails to authenticate 725 * (Authenticator was not set up in the system). 726 */ 727 @TestTargets({ 728 @TestTargetNew( 729 level = TestLevel.PARTIAL, 730 notes = "Verifies HTTPS connection process made through the proxy server. Proxy server needs authentication but client fails to authenticate (Authenticator was not set up in the system).", 731 method = "setDoInput", 732 args = {boolean.class} 733 ), 734 @TestTargetNew( 735 level = TestLevel.PARTIAL, 736 notes = "Verifies HTTPS connection process made through the proxy server. Proxy server needs authentication but client fails to authenticate (Authenticator was not set up in the system).", 737 method = "setConnectTimeout", 738 args = {int.class} 739 ), 740 @TestTargetNew( 741 level = TestLevel.PARTIAL, 742 notes = "Verifies HTTPS connection process made through the proxy server. Proxy server needs authentication but client fails to authenticate (Authenticator was not set up in the system).", 743 method = "setReadTimeout", 744 args = {int.class} 745 ) 746 }) 747 @AndroidOnly("we only have a .bks key store in the test resources") 748 public void testProxyAuthConnectionFailed() throws Throwable { 749 // setting up the properties pointing to the key/trust stores 750 setUpStoreProperties(); 751 752 // create the SSLServerSocket which will be used by server side 753 ServerSocket ss = new ServerSocket(0); 754 755 // create the HostnameVerifier to check that Hostname verification 756 // is done 757 TestHostnameVerifier hnv = new TestHostnameVerifier(); 758 HttpsURLConnection.setDefaultHostnameVerifier(hnv); 759 760 // create HttpsURLConnection to be tested 761 URL url = new URL("https://requested.host:55555/requested.data"); 762 HttpURLConnection connection = (HttpURLConnection) url 763 .openConnection(new Proxy(Proxy.Type.HTTP, 764 new InetSocketAddress("localhost", ss 765 .getLocalPort()))); 766 767 // perform the interaction between the peers and check the results 768 try { 769 doInteraction(connection, ss, AUTHENTICATION_REQUIRED_CODE, 770 true); 771 } catch (IOException e) { 772 // SSL Tunnelling failed 773 if (DO_LOG) { 774 System.out.println("Got expected IOException: " 775 + e.getMessage()); 776 } 777 } 778 } 779 780 /** 781 * Tests the behaviour of HTTPS connection in case of unavailability 782 * of requested resource. 783 */ 784 @TestTargets({ 785 @TestTargetNew( 786 level = TestLevel.PARTIAL, 787 notes = "Verifies the behaviour of HTTPS connection in case of unavailability of requested resource.", 788 method = "setDoInput", 789 args = {boolean.class} 790 ), 791 @TestTargetNew( 792 level = TestLevel.PARTIAL, 793 notes = "Verifies the behaviour of HTTPS connection in case of unavailability of requested resource.", 794 method = "setConnectTimeout", 795 args = {int.class} 796 ), 797 @TestTargetNew( 798 level = TestLevel.PARTIAL, 799 notes = "Verifies the behaviour of HTTPS connection in case of unavailability of requested resource.", 800 method = "setReadTimeout", 801 args = {int.class} 802 ) 803 }) 804 public void testProxyConnection_Not_Found_Response() throws Throwable { 805 // setting up the properties pointing to the key/trust stores 806 setUpStoreProperties(); 807 808 // create the SSLServerSocket which will be used by server side 809 ServerSocket ss = new ServerSocket(0); 810 811 // create the HostnameVerifier to check that Hostname verification 812 // is done 813 TestHostnameVerifier hnv = new TestHostnameVerifier(); 814 HttpsURLConnection.setDefaultHostnameVerifier(hnv); 815 816 // create HttpsURLConnection to be tested 817 URL url = new URL("https://localhost:" + ss.getLocalPort()); 818 HttpURLConnection connection = (HttpURLConnection) url 819 .openConnection(new Proxy(Proxy.Type.HTTP, 820 new InetSocketAddress("localhost", ss 821 .getLocalPort()))); 822 823 try { 824 doInteraction(connection, ss, NOT_FOUND_CODE); // NOT FOUND 825 fail("Expected exception was not thrown."); 826 } catch (FileNotFoundException e) { 827 if (DO_LOG) { 828 System.out.println("Expected exception was thrown: " 829 + e.getMessage()); 830 } 831 } 832 } 833 834 // --------------------------------------------------------------------- 835 // ------------------------ Staff Methods ------------------------------ 836 // --------------------------------------------------------------------- 837 838 /** 839 * Log the name of the test case to be executed. 840 */ 841 public void setUp() throws Exception { 842 super.setUp(); 843 TestEnvironment.reset(); 844 845 if (DO_LOG) { 846 System.out.println(); 847 System.out.println("------------------------"); 848 System.out.println("------ " + getName()); 849 System.out.println("------------------------"); 850 } 851 852 if (store != null) { 853 String ksFileName = "org/apache/harmony/luni/tests/key_store." 854 + KeyStore.getDefaultType().toLowerCase(); 855 InputStream in = getClass().getClassLoader() 856 .getResourceAsStream(ksFileName); 857 FileOutputStream out = new FileOutputStream(store); 858 BufferedInputStream bufIn = new BufferedInputStream(in, 8192); 859 while (bufIn.available() > 0) { 860 byte[] buf = new byte[128]; 861 int read = bufIn.read(buf); 862 out.write(buf, 0, read); 863 } 864 bufIn.close(); 865 out.close(); 866 } else { 867 fail("couldn't set up key store"); 868 } 869 } 870 871 public void tearDown() { 872 TestEnvironment.reset(); 873 if (store != null) { 874 store.delete(); 875 } 876 } 877 878 /** 879 * Checks the HttpsURLConnection getter's values and compares 880 * them with actual corresponding values of remote peer. 881 */ 882 public static void checkConnectionStateParameters( 883 HttpsURLConnection clientConnection, SSLSocket serverPeer) 884 throws Exception { 885 SSLSession session = serverPeer.getSession(); 886 887 assertEquals(session.getCipherSuite(), clientConnection 888 .getCipherSuite()); 889 890 assertEquals(session.getLocalPrincipal(), clientConnection 891 .getPeerPrincipal()); 892 893 assertEquals(session.getPeerPrincipal(), clientConnection 894 .getLocalPrincipal()); 895 896 Certificate[] serverCertificates = clientConnection 897 .getServerCertificates(); 898 Certificate[] localCertificates = session.getLocalCertificates(); 899 assertTrue("Server certificates differ from expected", Arrays.equals( 900 serverCertificates, localCertificates)); 901 902 localCertificates = clientConnection.getLocalCertificates(); 903 serverCertificates = session.getPeerCertificates(); 904 assertTrue("Local certificates differ from expected", Arrays.equals( 905 serverCertificates, localCertificates)); 906 } 907 908 /** 909 * Returns the file name of the key/trust store. The key store file 910 * (named as "key_store." + extension equals to the default KeyStore 911 * type installed in the system in lower case) is searched in classpath. 912 * @throws junit.framework.AssertionFailedError if property was not set 913 * or file does not exist. 914 */ 915 private static String getKeyStoreFileName() { 916 return store.getAbsolutePath(); 917 } 918 919 /** 920 * Builds and returns the context used for secure socket creation. 921 */ 922 private static SSLContext getContext() throws Exception { 923 String type = KeyStore.getDefaultType(); 924 SSLContext ctx; 925 926 String keyStore = getKeyStoreFileName(); 927 File keyStoreFile = new File(keyStore); 928 929 FileInputStream fis = new FileInputStream(keyStoreFile); 930 931 KeyStore ks = KeyStore.getInstance(type); 932 ks.load(fis, KS_PASSWORD.toCharArray()); 933 934 KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory 935 .getDefaultAlgorithm()); 936 kmf.init(ks, KS_PASSWORD.toCharArray()); 937 938 TrustManagerFactory tmf = TrustManagerFactory 939 .getInstance(TrustManagerFactory.getDefaultAlgorithm()); 940 tmf.init(ks); 941 942 ctx = SSLContext.getInstance("TLSv1"); 943 ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 944 945 return ctx; 946 } 947 948 /** 949 * Sets up the properties pointing to the key store and trust store 950 * and used as default values by JSSE staff. This is needed to test 951 * HTTPS behaviour in the case of default SSL Socket Factories. 952 */ 953 private static void setUpStoreProperties() throws Exception { 954 String type = KeyStore.getDefaultType(); 955 956 System.setProperty("javax.net.ssl.keyStoreType", type); 957 System.setProperty("javax.net.ssl.keyStore", getKeyStoreFileName()); 958 System.setProperty("javax.net.ssl.keyStorePassword", KS_PASSWORD); 959 960 System.setProperty("javax.net.ssl.trustStoreType", type); 961 System.setProperty("javax.net.ssl.trustStore", getKeyStoreFileName()); 962 System.setProperty("javax.net.ssl.trustStorePassword", KS_PASSWORD); 963 } 964 965 /** 966 * Performs interaction between client's HttpURLConnection and 967 * servers side (ServerSocket). 968 */ 969 public static Socket doInteraction( 970 final HttpURLConnection clientConnection, 971 final ServerSocket serverSocket) throws Throwable { 972 return doInteraction(clientConnection, serverSocket, OK_CODE, false); 973 } 974 975 /** 976 * Performs interaction between client's HttpURLConnection and 977 * servers side (ServerSocket). Server will response with specified 978 * response code. 979 */ 980 public static Socket doInteraction( 981 final HttpURLConnection clientConnection, 982 final ServerSocket serverSocket, final int responseCode) 983 throws Throwable { 984 return doInteraction(clientConnection, serverSocket, responseCode, 985 false); 986 } 987 988 /** 989 * Performs interaction between client's HttpURLConnection and 990 * servers side (ServerSocket). Server will response with specified 991 * response code. 992 * @param doAuthentication specifies 993 * if the server needs client authentication. 994 */ 995 public static Socket doInteraction( 996 final HttpURLConnection clientConnection, 997 final ServerSocket serverSocket, final int responseCode, 998 final boolean doAuthentication) throws Throwable { 999 1000 // set up the connection 1001 clientConnection.setDoInput(true); 1002 clientConnection.setConnectTimeout(TIMEOUT); 1003 clientConnection.setReadTimeout(TIMEOUT); 1004 1005 ServerWork server = new ServerWork(serverSocket, responseCode, 1006 doAuthentication); 1007 1008 ClientConnectionWork client = new ClientConnectionWork(clientConnection); 1009 1010 ExecutorService executorService = Executors.newFixedThreadPool(2); 1011 try { 1012 Future<Void> serverFuture = executorService.submit(server); 1013 Future<Void> clientFuture = executorService.submit(client); 1014 1015 serverFuture.get(30, TimeUnit.SECONDS); 1016 clientFuture.get(30, TimeUnit.SECONDS); 1017 } catch (ExecutionException e) { 1018 throw e.getCause(); 1019 } finally { 1020 executorService.shutdown(); 1021 } 1022 1023 return server.peerSocket; 1024 } 1025 1026 /** 1027 * The host name verifier used in test. 1028 */ 1029 static class TestHostnameVerifier implements HostnameVerifier { 1030 1031 boolean verified = false; 1032 1033 public boolean verify(String hostname, SSLSession session) { 1034 if (DO_LOG) { 1035 System.out.println("***> verification " + hostname + " " 1036 + session.getPeerHost()); 1037 } 1038 verified = true; 1039 return true; 1040 } 1041 } 1042 1043 /** 1044 * The base class for mock Client and Server. 1045 */ 1046 static class Work { 1047 1048 /** 1049 * The header of OK HTTP response. 1050 */ 1051 static final String responseHead = "HTTP/1.1 200 OK\n"; 1052 1053 /** 1054 * The content of the response. 1055 */ 1056 static final String plainResponseContent = "<HTML>\n" 1057 + "<HEAD><TITLE>Plain Response Content</TITLE></HEAD>\n" 1058 + "</HTML>"; 1059 1060 /** 1061 * The tail of the response. 1062 */ 1063 static final String plainResponseTail = "Content-type: text/html\n" 1064 + "Content-length: " + plainResponseContent.length() + "\n\n" 1065 + plainResponseContent; 1066 1067 /** 1068 * The response message to be sent in plain (HTTP) format. 1069 */ 1070 static final String plainResponse = responseHead + plainResponseTail; 1071 1072 /** 1073 * The content of the response to be sent during HTTPS session. 1074 */ 1075 static final String httpsResponseContent = "<HTML>\n" 1076 + "<HEAD><TITLE>HTTPS Response Content</TITLE></HEAD>\n" 1077 + "</HTML>"; 1078 1079 /** 1080 * The tail of the response to be sent during HTTPS session. 1081 */ 1082 static final String httpsResponseTail = "Content-type: text/html\n" 1083 + "Content-length: " + httpsResponseContent.length() + "\n\n" 1084 + httpsResponseContent; 1085 1086 /** 1087 * The response requiring client's proxy authentication. 1088 */ 1089 static final String respAuthenticationRequired = "HTTP/1.0 407 Proxy authentication required\n" 1090 + "Proxy-authenticate: Basic realm=\"localhost\"\n\n"; 1091 1092 /** 1093 * The data to be posted by client to the server. 1094 */ 1095 static final String clientsData = "_.-^ Client's Data ^-._"; 1096 1097 /** 1098 * The print stream used for debug log. 1099 * If it is null debug info will not be printed. 1100 */ 1101 private PrintStream out = new PrintStream(System.out); 1102 1103 /** 1104 * Prints log message. 1105 */ 1106 public synchronized void log(String message) { 1107 if (DO_LOG && (out != null)) { 1108 out.println("[" + this + "]: " + message); 1109 } 1110 } 1111 } 1112 1113 /** 1114 * The class used for server side works. 1115 */ 1116 static class ServerWork extends Work implements Callable<Void> { 1117 1118 // the server socket used for connection 1119 private ServerSocket serverSocket; 1120 1121 // the socket connected with client peer 1122 private Socket peerSocket; 1123 1124 // indicates if the server acts as proxy server 1125 private boolean actAsProxy; 1126 1127 // indicates if the server needs proxy authentication 1128 private boolean needProxyAuthentication; 1129 1130 // response code to be send to the client peer 1131 private int responseCode; 1132 1133 /** 1134 * Creates the thread acting as a server side. 1135 */ 1136 public ServerWork(ServerSocket serverSocket) { 1137 // the server does not require proxy authentication 1138 // and sends OK_CODE (OK) response code 1139 this(serverSocket, OK_CODE, false); 1140 } 1141 1142 /** 1143 * Creates the thread acting as a server side. 1144 * @param serverSocket the server socket to be used during connection 1145 * @param responseCode the response code to be sent to the client 1146 * @param needProxyAuthentication 1147 * indicates if the server needs proxy authentication 1148 */ 1149 public ServerWork(ServerSocket serverSocket, int responseCode, 1150 boolean needProxyAuthentication) { 1151 this.serverSocket = serverSocket; 1152 this.responseCode = responseCode; 1153 this.needProxyAuthentication = needProxyAuthentication; 1154 // will act as a proxy server if the specified server socket 1155 // is not a secure server socket 1156 if (serverSocket instanceof SSLServerSocket) { 1157 // demand client to send its certificate 1158 ((SSLServerSocket) serverSocket).setNeedClientAuth(true); 1159 // work as a HTTPS server, not as HTTP proxy 1160 this.actAsProxy = false; 1161 } else { 1162 this.actAsProxy = true; 1163 } 1164 this.actAsProxy = !(serverSocket instanceof SSLServerSocket); 1165 } 1166 1167 /** 1168 * Closes the connection. 1169 */ 1170 public void closeSocket(Socket socket) { 1171 try { 1172 socket.getInputStream().close(); 1173 } catch (IOException e) {} 1174 try { 1175 socket.getOutputStream().close(); 1176 } catch (IOException e) {} 1177 try { 1178 socket.close(); 1179 } catch (IOException e) {} 1180 } 1181 1182 /** 1183 * Performs the actual server work. 1184 * If some exception occurs during the work it will be 1185 * stored in the <code>thrown</code> field. 1186 */ 1187 public Void call() throws Exception { 1188 // the buffer used for reading the messages 1189 byte[] buff = new byte[2048]; 1190 // the number of bytes read into the buffer 1191 int num; 1192 try { 1193 // configure the server socket to avoid blocking 1194 serverSocket.setSoTimeout(TIMEOUT); 1195 // accept client connection 1196 peerSocket = serverSocket.accept(); 1197 // configure the client connection to avoid blocking 1198 peerSocket.setSoTimeout(TIMEOUT); 1199 log("Client connection ACCEPTED"); 1200 1201 InputStream is = peerSocket.getInputStream(); 1202 OutputStream os = peerSocket.getOutputStream(); 1203 1204 num = is.read(buff); 1205 String message = new String(buff, 0, num); 1206 log("Got request:\n" + message); 1207 log("------------------"); 1208 1209 if (!actAsProxy) { 1210 // Act as Server (not Proxy) side 1211 if (message.startsWith("POST")) { 1212 // client connection sent some data 1213 log("try to read client data"); 1214 num = is.read(buff); 1215 message = new String(buff, 0, num); 1216 log("client's data: '" + message + "'"); 1217 // check the received data 1218 assertEquals(clientsData, message); 1219 } 1220 // just send the response 1221 os.write(("HTTP/1.1 " + responseCode + "\n" + httpsResponseTail) 1222 .getBytes()); 1223 os.flush(); 1224 os.close(); 1225 // and return 1226 log("Work is DONE !actAsProxy"); 1227 return null; 1228 } 1229 1230 // Do proxy work 1231 if (needProxyAuthentication) { 1232 log("Authentication required ..."); 1233 // send Authentication Request 1234 os.write(respAuthenticationRequired.getBytes()); 1235 // read response 1236 num = is.read(buff); 1237 if (num == -1) { 1238 // this connection was closed, 1239 // do clean up and create new one: 1240 closeSocket(peerSocket); 1241 peerSocket = serverSocket.accept(); 1242 peerSocket.setSoTimeout(TIMEOUT); 1243 log("New client connection ACCEPTED"); 1244 is = peerSocket.getInputStream(); 1245 os = peerSocket.getOutputStream(); 1246 num = is.read(buff); 1247 } 1248 message = new String(buff, 0, num); 1249 log("Got authenticated request:\n" + message); 1250 log("------------------"); 1251 // check provided authorization credentials 1252 assertTrue("Received message does not contain " 1253 + "authorization credentials", message 1254 .toLowerCase().indexOf("proxy-authorization:") > 0); 1255 } 1256 1257 // The content of this response will reach proxied HTTPUC 1258 // but will not reach proxied HTTPSUC 1259 // In case of HTTP connection it will be the final message, 1260 // in case of HTTPS connection this message will just indicate 1261 // that connection with remote host has been done 1262 // (i.e. SSL tunnel has been established). 1263 os.write(plainResponse.getBytes()); 1264 log("Sent OK RESPONSE"); 1265 1266 if (message.startsWith("CONNECT")) { // request for SSL tunnel 1267 log("Perform SSL Handshake..."); 1268 // create sslSocket acting as a remote server peer 1269 SSLSocket sslSocket = (SSLSocket) getContext() 1270 .getSocketFactory().createSocket(peerSocket, 1271 "localhost", peerSocket.getPort(), true); // do autoclose 1272 sslSocket.setUseClientMode(false); 1273 // demand client authentication 1274 sslSocket.setNeedClientAuth(true); 1275 sslSocket.startHandshake(); 1276 peerSocket = sslSocket; 1277 is = peerSocket.getInputStream(); 1278 os = peerSocket.getOutputStream(); 1279 1280 // read the HTTP request sent by secure connection 1281 // (HTTPS request) 1282 num = is.read(buff); 1283 message = new String(buff, 0, num); 1284 log("[Remote Server] Request from SSL tunnel:\n" + message); 1285 log("------------------"); 1286 1287 if (message.startsWith("POST")) { 1288 // client connection sent some data 1289 log("[Remote Server] try to read client data"); 1290 num = is.read(buff); 1291 message = new String(buff, 0, num); 1292 log("[Remote Server] client's data: '" + message + "'"); 1293 // check the received data 1294 assertEquals(clientsData, message); 1295 } 1296 1297 log("[Remote Server] Sending the response by SSL tunnel.."); 1298 // send the response with specified response code 1299 os 1300 .write(("HTTP/1.1 " + responseCode + "\n" + httpsResponseTail) 1301 .getBytes()); 1302 } 1303 log("Work is DONE actAsProxy"); 1304 return null; 1305 } finally { 1306 closeSocket(peerSocket); 1307 try { 1308 serverSocket.close(); 1309 } catch (IOException e) {} 1310 } 1311 } 1312 1313 @Override public String toString() { 1314 return actAsProxy ? "Proxy Server" : "Server"; 1315 } 1316 } 1317 1318 /** 1319 * The class used for client side works. It could be used to test 1320 * both HttpURLConnection and HttpsURLConnection. 1321 */ 1322 static class ClientConnectionWork extends Work implements Callable<Void> { 1323 1324 // connection to be used to contact the server side 1325 private HttpURLConnection connection; 1326 1327 /** 1328 * Creates the thread acting as a client side. 1329 * @param connection connection to be used to contact the server side 1330 */ 1331 public ClientConnectionWork(HttpURLConnection connection) { 1332 this.connection = connection; 1333 log("Created over connection: " + connection.getClass()); 1334 } 1335 1336 /** 1337 * Performs the actual client work. 1338 * If some exception occurs during the work it will be 1339 * stored in the <code>thrown<code> field. 1340 */ 1341 public Void call() throws Exception { 1342 log("Opening the connection.."); 1343 connection.connect(); 1344 log("Connection has been ESTABLISHED, using proxy: " 1345 + connection.usingProxy()); 1346 if (connection.getDoOutput()) { 1347 // connection configured to post data, do so 1348 connection.getOutputStream().write(clientsData.getBytes()); 1349 } 1350 // read the content of HTTP(s) response 1351 InputStream is = connection.getInputStream(); 1352 log("Input Stream obtained"); 1353 byte[] buff = new byte[2048]; 1354 int num = 0; 1355 int byt = 0; 1356 while ((num < buff.length) && (is.available() > 0) 1357 && ((byt = is.read()) != -1)) { 1358 buff[num++] = (byte) byt; 1359 } 1360 String message = new String(buff, 0, num); 1361 log("Got content:\n" + message); 1362 log("------------------"); 1363 log("Response code: " + connection.getResponseCode()); 1364 1365 if (connection instanceof HttpsURLConnection) { 1366 assertEquals(httpsResponseContent, message); 1367 } else { 1368 assertEquals(plainResponseContent, message); 1369 } 1370 1371 return null; 1372 } 1373 1374 @Override public String toString() { 1375 return "Client Connection"; 1376 } 1377 } 1378} 1379