Home | History | Annotate | Download | only in support
      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 
     18 package tests.support;
     19 
     20 import java.io.ByteArrayOutputStream;
     21 import java.io.IOException;
     22 import java.io.InputStream;
     23 import java.io.OutputStream;
     24 import junit.framework.Assert;
     25 
     26 /**
     27  * Performs some basic testing of either HttpConnection or HttpURLConnection
     28  * depending on the Support_ServerSocket and Support_HttpConnector passed to the
     29  * constructor.
     30  *
     31  */
     32 public class Support_HttpTests {
     33 
     34 	private Support_ServerSocket serversocket;
     35 
     36 	private Support_HttpConnector connector;
     37 
     38 	public Support_HttpTests(Support_ServerSocket serversocket,
     39 			Support_HttpConnector client) {
     40 		this.serversocket = serversocket;
     41 		this.connector = client;
     42 	}
     43 
     44 	public void runTests(junit.framework.TestCase test) {
     45 
     46 		// get a port to use for the test
     47 		int portNumber = Support_PortManager.getNextPort();
     48 
     49 		// url's for the various tests
     50 		final String chunkedTestUrl = "http://localhost:" + portNumber
     51 				+ Support_HttpServer.CHUNKEDTEST;
     52 		final String contentTestUrl = "http://localhost:" + portNumber
     53 				+ Support_HttpServer.CONTENTTEST;
     54 		final String redirectTestUrl = "http://localhost:" + portNumber
     55 				+ Support_HttpServer.REDIRECTTEST;
     56 		final String postTestUrl = "http://localhost:" + portNumber
     57 				+ Support_HttpServer.POSTTEST;
     58 		final String headersTestUrl = "http://localhost:" + portNumber
     59 				+ Support_HttpServer.HEADERSTEST;
     60 
     61 		// start the test server. It will timeout and shut down after
     62 		// 5 seconds of inactivity
     63 		Support_HttpServer server = new Support_HttpServer(serversocket, test);
     64 		server.startServer(portNumber);
     65 
     66 		ByteArrayOutputStream bout = new ByteArrayOutputStream();
     67 		InputStream is;
     68 		int c;
     69 
     70 		// Chunked HTTP Transfer Coding Test
     71 		try {
     72 			// access the url and open a stream
     73 			connector.open(chunkedTestUrl);
     74 			is = connector.getInputStream();
     75 
     76 			// receive the data, and then read again after EOF
     77 			c = is.read();
     78 			while (c > 0) {
     79                 c = is.read();
     80             }
     81 			c = is.read();
     82 			is.close();
     83 			connector.close();
     84 			Assert.assertEquals("Error receiving chunked transfer coded data",
     85 					-1, c);
     86 		} catch (Exception e) {
     87 			e.printStackTrace();
     88 			Assert.fail("Exception during test a: " + e);
     89 		}
     90 
     91 		// Content-Length Test
     92 		try {
     93 			connector.open(contentTestUrl);
     94 			is = connector.getInputStream();
     95 			bout.reset();
     96 			do {
     97 				c = is.read();
     98 				if (c != -1) {
     99                     bout.write(c);
    100                 }
    101 			} while (c != -1);
    102 			is.close();
    103 			connector.close();
    104 			String result = new String(bout.toByteArray(), "ISO8859_1");
    105 			Assert.assertTrue("Error receiving content coded data: " + result,
    106 					"ABCDE".equals(result));
    107 		} catch (Exception e) {
    108 			e.printStackTrace();
    109 			Assert.fail("Exception during test b: " + e);
    110 		}
    111 
    112 		// Headers Test
    113 		try {
    114 			connector.open(headersTestUrl);
    115 			connector.setRequestProperty("header1", "value1");
    116 			connector.setRequestProperty("header1", "value2");
    117 			int i = 0, found = 0;
    118 			String[] expected = new String[] { "no-cache=\"set-cookie\"",
    119 					"private", "no-transform" };
    120 			while (true) {
    121 				String key = connector.getHeaderFieldKey(i);
    122 				if (key == null && i > 0) {
    123                     break;
    124                 }
    125 				if ("Cache-Control".equals(key)) {
    126 					Assert.assertTrue("Too many headers at: " + i, found <= 2);
    127 					String value = connector.getHeaderField(i);
    128 					Assert.assertTrue("Invalid header value: " + found + ": "
    129 							+ value, expected[found].equals(value));
    130 					found++;
    131 				}
    132 				i++;
    133 			}
    134 			Assert.assertTrue("Invalid headers: " + found, found == 3);
    135 			connector.close();
    136 		} catch (Exception e) {
    137 			e.printStackTrace();
    138 			Assert.fail("Exception during test c: " + e);
    139 		}
    140 
    141 		// Post Test
    142 		// Same as "Basic post" test below, but uses read() instead
    143 		// of read(buf, offset, length) to read the results
    144 		try {
    145 			String toWrite = "abcdef";
    146 			connector.open(postTestUrl);
    147 			OutputStream out = connector.getOutputStream();
    148 			out.write(toWrite.getBytes("ISO8859_1"));
    149 			out.close();
    150 			is = connector.getInputStream();
    151 			bout.reset();
    152 			do {
    153 				c = is.read();
    154 				if (c != -1) {
    155                     bout.write(c);
    156                 }
    157 			} while (c != -1);
    158 			is.close();
    159 			connector.close();
    160 			String result = new String(bout.toByteArray(), "ISO8859_1");
    161 			Assert.assertTrue("Error sending data 1: " + result, toWrite
    162 					.equals(result));
    163 		} catch (Exception e) {
    164 			e.printStackTrace();
    165 			Assert.fail("Exception during test d: " + e);
    166 		}
    167 
    168 		// Post Test chunked
    169 		try {
    170 			String toWrite = "zyxwvuts";
    171 			connector.open(postTestUrl);
    172 			connector.setRequestProperty("Transfer-encoding", "chunked");
    173 			OutputStream out = connector.getOutputStream();
    174 			out.write(toWrite.getBytes("ISO8859_1"));
    175 			out.close();
    176 			is = connector.getInputStream();
    177 			bout.reset();
    178 			do {
    179 				c = is.read();
    180 				if (c != -1) {
    181                     bout.write(c);
    182                 }
    183 			} while (c != -1);
    184 			is.close();
    185 			connector.close();
    186 			String result = new String(bout.toByteArray(), "ISO8859_1");
    187             Assert.assertEquals(toWrite, result);
    188 		} catch (Exception e) {
    189 			e.printStackTrace();
    190 			Assert.fail("Exception during test e: " + e);
    191 		}
    192 
    193 		OutputStream os = null;
    194 
    195 		byte[] data = new byte[1024];
    196 		int len = 0;
    197 
    198 		// Basic post
    199 		try {
    200 			String message = "test";
    201 			connector.open(postTestUrl);
    202 			os = connector.getOutputStream();
    203 			os.write(message.getBytes("ISO8859_1"));
    204 			os.close();
    205 			is = connector.getInputStream();
    206 			len = 0;
    207 			do {
    208 				int r = is.read(data, len, data.length - len);
    209 				if (r == -1) {
    210                     break;
    211                 }
    212 				len += r;
    213 			} while (true);
    214 			is.close();
    215 			connector.close();
    216 			String result = new String(data, 0, len, "ISO8859_1");
    217 			Assert.assertTrue("Basic port error: " + result, message
    218 					.equals(result));
    219 		} catch (IOException e) {
    220 			e.printStackTrace();
    221 			Assert.fail("Exception during basic post test: " + e);
    222 		}
    223 
    224 		String chunkChar = connector.isChunkedOnFlush() ? "C" : "";
    225 
    226 		// Flushing with post
    227 		try {
    228 			String message1 = "test2", message2 = "test3";
    229 			connector.open(postTestUrl);
    230 			os = connector.getOutputStream();
    231 			os.write(message1.getBytes("ISO8859_1"));
    232 			os.flush();
    233 			os.write(message2.getBytes("ISO8859_1"));
    234 			os.close();
    235 			is = connector.getInputStream();
    236 			len = 0;
    237 			do {
    238 				int r = is.read(data, len, data.length - len);
    239 				if (r == -1) {
    240                     break;
    241                 }
    242 				len += r;
    243 			} while (true);
    244 			is.close();
    245 			connector.close();
    246 			String result = new String(data, 0, len, "ISO8859_1");
    247 			Assert.assertTrue("Flushing with post: " + result, (chunkChar
    248 					+ message1 + chunkChar + message2).equals(result));
    249 		} catch (IOException e) {
    250 			e.printStackTrace();
    251 			Assert.fail("Exception during flushing post test: " + e);
    252 		}
    253 
    254 		// Flushing with post and setting content-length
    255 		try {
    256 			String message1 = "test4", message2 = "test5";
    257 			connector.open(postTestUrl);
    258 			connector.setRequestProperty("Content-Length", "10");
    259 			os = connector.getOutputStream();
    260 			os.write(message1.getBytes("ISO8859_1"));
    261 			os.flush();
    262 			os.write(message2.getBytes("ISO8859_1"));
    263 			os.close();
    264 			is = connector.getInputStream();
    265 			len = 0;
    266 			do {
    267 				int r = is.read(data, len, data.length - len);
    268 				if (r == -1) {
    269                     break;
    270                 }
    271 				len += r;
    272 			} while (true);
    273 			is.close();
    274 			connector.close();
    275 			String result = new String(data, 0, len, "ISO8859_1");
    276 			Assert.assertTrue("Flushing with post and setting content-length: "
    277 					+ result, (chunkChar + message1 + chunkChar + message2)
    278 					.equals(result));
    279 		} catch (IOException e) {
    280 			e.printStackTrace();
    281 			Assert.fail("Exception during flushing with content-length post test: "
    282 							+ e);
    283 		}
    284 
    285 		// Flushing followed immediately by a close()
    286 		try {
    287 			String message = "test6";
    288 			connector.open(postTestUrl);
    289 			os = connector.getOutputStream();
    290 			os.write(message.getBytes("ISO8859_1"));
    291 			os.flush();
    292 			os.close();
    293 			is = connector.getInputStream();
    294 			len = 0;
    295 			do {
    296 				int r = is.read(data, len, data.length - len);
    297 				if (r == -1) {
    298                     break;
    299                 }
    300 				len += r;
    301 			} while (true);
    302 			is.close();
    303 			connector.close();
    304 			String result = new String(data, 0, len, "ISO8859_1");
    305 			Assert.assertTrue("Flushing followed immediately by a close(): "
    306 					+ result, (chunkChar + message).equals(result));
    307 		} catch (IOException e) {
    308 			e.printStackTrace();
    309 			Assert.fail("Exception during flush followed by close post test: "
    310 					+ e);
    311 		}
    312 
    313 		// Redirection Tests
    314 		final int[] testCodes = { Support_HttpServer.MULT_CHOICE,
    315 				Support_HttpServer.MOVED_PERM, Support_HttpServer.FOUND,
    316 				Support_HttpServer.SEE_OTHER, Support_HttpServer.NOT_MODIFIED,
    317 				Support_HttpServer.UNUSED, Support_HttpServer.TEMP_REDIRECT, };
    318 
    319 		final int[] results = { 'A', 'A', 'A', 'A', 'P', 'P', 'P' };
    320 		// see Support_HTTPServer for the source of this data
    321 
    322 		final String fullLocalLocation = contentTestUrl;
    323 		final String partLocalLocation = Support_HttpServer.CONTENTTEST;
    324 
    325 		for (int i = 0; i < testCodes.length; i++) {
    326 
    327 			// test each of the redirection response codes
    328 			try {
    329 				// append the response code for the server to return
    330 				// and the location to redirect to
    331 				connector.open(redirectTestUrl + "/" + testCodes[i] + "-"
    332 						+ fullLocalLocation);
    333 				is = connector.getInputStream();
    334 				connector.close();
    335 
    336 				c = is.read();
    337 
    338 				if (testCodes[i] == Support_HttpServer.NOT_MODIFIED) {
    339 					// accept either the message-body or nothing, since the spec
    340 					// says there MUST NOT be a message body on 304 responses.
    341 					// But Java returns the message-body
    342 					if (!(c == results[i] || c == -1)) {
    343 						Assert.fail("Incorrect data returned on test of HTTP response "
    344 										+ testCodes[i]);
    345 					}
    346 				} else if (c != results[i]) {
    347 					Assert.fail("Incorrect data returned on test of HTTP response "
    348 									+ testCodes[i]);
    349 				}
    350 				while (c > 0) {
    351                     c = is.read();
    352                 }
    353 				c = is.read();
    354 				is.close();
    355 			} catch (Exception e) {
    356 				e.printStackTrace();
    357 				Assert.fail("Error during redirection test " + i + ": " + e);
    358 			}
    359 		}
    360 
    361 		// Test redirecting to a location on a different port
    362 		Class<?> serversocketclass = serversocket.getClass();
    363 		try {
    364 			Support_ServerSocket serversocket2 = (Support_ServerSocket) serversocketclass
    365 					.newInstance();
    366 
    367 			Support_HttpServer server2 = new Support_HttpServer(serversocket2,
    368 					test);
    369 			int newport = Support_PortManager.getNextPort();
    370 			server2.startServer(newport);
    371 			server2.setPortRedirectTestEnable(true);
    372 
    373 			// Test if redirection to a different port works
    374 			final String otherPortLocation = "http://localhost:" + newport
    375 					+ Support_HttpServer.PORTREDIRTEST;
    376 
    377 			try {
    378 				// append the response code for the server to return
    379 				// and the location to redirect to
    380 
    381 				connector.open(redirectTestUrl + "/"
    382 						+ Support_HttpServer.MOVED_PERM + "-"
    383 						+ otherPortLocation);
    384 				is = connector.getInputStream();
    385 				connector.close();
    386 
    387 				c = is.read();
    388 				Assert.assertEquals("Incorrect data returned on redirection to a different port.",
    389 								'A', c);
    390 				while (c > 0) {
    391                     c = is.read();
    392                 }
    393 				c = is.read();
    394 				is.close();
    395 			} catch (Exception e) {
    396 				e.printStackTrace();
    397 				Assert.fail("Exception during test f: " + e);
    398 			}
    399 			server2.stopServer();
    400 		} catch (IllegalAccessException e) {
    401 			Assert.fail("Exception during redirection to a different port:" + e);
    402 		} catch (InstantiationException e) {
    403 			Assert.fail("Exception during redirection to a different port:" + e);
    404 		}
    405 
    406 		// test redirecting to a relative URL on the same host
    407 		try {
    408 			// append the response code for the server to return
    409 			connector.open(redirectTestUrl + "/"
    410 					+ Support_HttpServer.MOVED_PERM + "-" + partLocalLocation);
    411 			is = connector.getInputStream();
    412 			connector.close();
    413 
    414 			c = is.read();
    415 			Assert.assertEquals("Incorrect data returned on redirect to relative URI.",
    416 					'A', c);
    417 			while (c > 0) {
    418                 c = is.read();
    419             }
    420 			c = is.read();
    421 			is.close();
    422 		} catch (Exception e) {
    423 			e.printStackTrace();
    424 			Assert.fail("Exception during redirection test to a relative URL: " + e);
    425 		}
    426 		server.stopServer();
    427 	}
    428 
    429 }
    430