Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
1 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /**
8 * Tests that the scheme, host, and port of the server are correctly recorded
9 * and used in HTTP requests and responses.
10 */
12 const PORT = 4444;
13 const FAKE_PORT_ONE = 8888;
14 const FAKE_PORT_TWO = 8889;
16 var srv, id;
18 function run_test()
19 {
20 dumpn("*** run_test");
22 srv = createServer();
24 srv.registerPathHandler("/http/1.0-request", http10Request);
25 srv.registerPathHandler("/http/1.1-good-host", http11goodHost);
26 srv.registerPathHandler("/http/1.1-good-host-wacky-port",
27 http11goodHostWackyPort);
28 srv.registerPathHandler("/http/1.1-ip-host", http11ipHost);
30 srv.start(FAKE_PORT_ONE);
32 id = srv.identity;
34 // The default location is http://localhost:PORT, where PORT is whatever you
35 // provided when you started the server. http://127.0.0.1:PORT is also part
36 // of the default set of locations.
37 do_check_eq(id.primaryScheme, "http");
38 do_check_eq(id.primaryHost, "localhost");
39 do_check_eq(id.primaryPort, FAKE_PORT_ONE);
40 do_check_true(id.has("http", "localhost", FAKE_PORT_ONE));
41 do_check_true(id.has("http", "127.0.0.1", FAKE_PORT_ONE));
43 // This should be a nop.
44 id.add("http", "localhost", FAKE_PORT_ONE);
45 do_check_eq(id.primaryScheme, "http");
46 do_check_eq(id.primaryHost, "localhost");
47 do_check_eq(id.primaryPort, FAKE_PORT_ONE);
48 do_check_true(id.has("http", "localhost", FAKE_PORT_ONE));
49 do_check_true(id.has("http", "127.0.0.1", FAKE_PORT_ONE));
51 // Change the primary location and make sure all the getters work correctly.
52 id.setPrimary("http", "127.0.0.1", FAKE_PORT_ONE);
53 do_check_eq(id.primaryScheme, "http");
54 do_check_eq(id.primaryHost, "127.0.0.1");
55 do_check_eq(id.primaryPort, FAKE_PORT_ONE);
56 do_check_true(id.has("http", "localhost", FAKE_PORT_ONE));
57 do_check_true(id.has("http", "127.0.0.1", FAKE_PORT_ONE));
59 // Okay, now remove the primary location -- we fall back to the original
60 // location.
61 id.remove("http", "127.0.0.1", FAKE_PORT_ONE);
62 do_check_eq(id.primaryScheme, "http");
63 do_check_eq(id.primaryHost, "localhost");
64 do_check_eq(id.primaryPort, FAKE_PORT_ONE);
65 do_check_true(id.has("http", "localhost", FAKE_PORT_ONE));
66 do_check_false(id.has("http", "127.0.0.1", FAKE_PORT_ONE));
68 // You can't remove every location -- try this and the original default
69 // location will be silently readded.
70 id.remove("http", "localhost", FAKE_PORT_ONE);
71 do_check_eq(id.primaryScheme, "http");
72 do_check_eq(id.primaryHost, "localhost");
73 do_check_eq(id.primaryPort, FAKE_PORT_ONE);
74 do_check_true(id.has("http", "localhost", FAKE_PORT_ONE));
75 do_check_false(id.has("http", "127.0.0.1", FAKE_PORT_ONE));
77 // Okay, now that we've exercised that behavior, shut down the server and
78 // restart it on the correct port, to exercise port-changing behaviors at
79 // server start and stop.
80 do_test_pending();
81 srv.stop(function()
82 {
83 try
84 {
85 do_test_pending();
86 run_test_2();
87 }
88 finally
89 {
90 do_test_finished();
91 }
92 });
93 }
95 function run_test_2()
96 {
97 dumpn("*** run_test_2");
99 do_test_finished();
101 // Our primary location is gone because it was dependent on the port on which
102 // the server was running.
103 checkPrimariesThrow(id);
104 do_check_false(id.has("http", "127.0.0.1", FAKE_PORT_ONE));
105 do_check_false(id.has("http", "localhost", FAKE_PORT_ONE));
107 srv.start(FAKE_PORT_TWO);
109 // We should have picked up http://localhost:8889 as our primary location now
110 // that we've restarted.
111 do_check_eq(id.primaryScheme, "http");
112 do_check_eq(id.primaryHost, "localhost", FAKE_PORT_TWO);
113 do_check_eq(id.primaryPort, FAKE_PORT_TWO);
114 do_check_false(id.has("http", "localhost", FAKE_PORT_ONE));
115 do_check_false(id.has("http", "127.0.0.1", FAKE_PORT_ONE));
116 do_check_true(id.has("http", "localhost", FAKE_PORT_TWO));
117 do_check_true(id.has("http", "127.0.0.1", FAKE_PORT_TWO));
119 // Now we're going to see what happens when we shut down with a primary
120 // location that wasn't a default. That location should persist, and the
121 // default we remove should still not be present.
122 id.setPrimary("http", "example.com", FAKE_PORT_TWO);
123 do_check_true(id.has("http", "example.com", FAKE_PORT_TWO));
124 do_check_true(id.has("http", "127.0.0.1", FAKE_PORT_TWO));
125 do_check_true(id.has("http", "localhost", FAKE_PORT_TWO));
126 do_check_false(id.has("http", "127.0.0.1", FAKE_PORT_ONE));
127 do_check_false(id.has("http", "localhost", FAKE_PORT_ONE));
129 id.remove("http", "localhost", FAKE_PORT_TWO);
130 do_check_true(id.has("http", "example.com", FAKE_PORT_TWO));
131 do_check_false(id.has("http", "localhost", FAKE_PORT_TWO));
132 do_check_true(id.has("http", "127.0.0.1", FAKE_PORT_TWO));
133 do_check_false(id.has("http", "localhost", FAKE_PORT_ONE));
134 do_check_false(id.has("http", "127.0.0.1", FAKE_PORT_ONE));
136 id.remove("http", "127.0.0.1", FAKE_PORT_TWO);
137 do_check_true(id.has("http", "example.com", FAKE_PORT_TWO));
138 do_check_false(id.has("http", "localhost", FAKE_PORT_TWO));
139 do_check_false(id.has("http", "127.0.0.1", FAKE_PORT_TWO));
140 do_check_false(id.has("http", "localhost", FAKE_PORT_ONE));
141 do_check_false(id.has("http", "127.0.0.1", FAKE_PORT_ONE));
143 do_test_pending();
144 srv.stop(function()
145 {
146 try
147 {
148 do_test_pending();
149 run_test_3();
150 }
151 finally
152 {
153 do_test_finished();
154 }
155 });
156 }
158 function run_test_3()
159 {
160 dumpn("*** run_test_3");
162 do_test_finished();
164 // Only the default added location disappears; any others stay around,
165 // possibly as the primary location. We may have removed the default primary
166 // location, but the one we set manually should persist here.
167 do_check_eq(id.primaryScheme, "http");
168 do_check_eq(id.primaryHost, "example.com");
169 do_check_eq(id.primaryPort, FAKE_PORT_TWO);
170 do_check_true(id.has("http", "example.com", FAKE_PORT_TWO));
171 do_check_false(id.has("http", "localhost", FAKE_PORT_TWO));
172 do_check_false(id.has("http", "127.0.0.1", FAKE_PORT_TWO));
173 do_check_false(id.has("http", "localhost", FAKE_PORT_ONE));
174 do_check_false(id.has("http", "127.0.0.1", FAKE_PORT_ONE));
176 srv.start(PORT);
178 // Starting always adds HTTP entries for 127.0.0.1:port and localhost:port.
179 do_check_true(id.has("http", "example.com", FAKE_PORT_TWO));
180 do_check_false(id.has("http", "localhost", FAKE_PORT_TWO));
181 do_check_false(id.has("http", "127.0.0.1", FAKE_PORT_TWO));
182 do_check_false(id.has("http", "localhost", FAKE_PORT_ONE));
183 do_check_false(id.has("http", "127.0.0.1", FAKE_PORT_ONE));
184 do_check_true(id.has("http", "localhost", PORT));
185 do_check_true(id.has("http", "127.0.0.1", PORT));
187 // Remove the primary location we'd left set from last time.
188 id.remove("http", "example.com", FAKE_PORT_TWO);
190 // Default-port behavior testing requires the server responds to requests
191 // claiming to be on one such port.
192 id.add("http", "localhost", 80);
194 // Make sure we don't have anything lying around from running on either the
195 // first or the second port -- all we should have is our generated default,
196 // plus the additional port to test "portless" hostport variants.
197 do_check_true(id.has("http", "localhost", 80));
198 do_check_eq(id.primaryScheme, "http");
199 do_check_eq(id.primaryHost, "localhost");
200 do_check_eq(id.primaryPort, PORT);
201 do_check_true(id.has("http", "localhost", PORT));
202 do_check_true(id.has("http", "127.0.0.1", PORT));
203 do_check_false(id.has("http", "localhost", FAKE_PORT_ONE));
204 do_check_false(id.has("http", "127.0.0.1", FAKE_PORT_ONE));
205 do_check_false(id.has("http", "example.com", FAKE_PORT_TWO));
206 do_check_false(id.has("http", "localhost", FAKE_PORT_TWO));
207 do_check_false(id.has("http", "127.0.0.1", FAKE_PORT_TWO));
209 // Okay, finally done with identity testing. Our primary location is the one
210 // we want it to be, so we're off!
211 runRawTests(tests, testComplete(srv));
212 }
215 /*********************
216 * UTILITY FUNCTIONS *
217 *********************/
219 /**
220 * Verifies that all .primary* getters on a server identity correctly throw
221 * NS_ERROR_NOT_INITIALIZED.
222 *
223 * @param id : nsIHttpServerIdentity
224 * the server identity to test
225 */
226 function checkPrimariesThrow(id)
227 {
228 var threw = false;
229 try
230 {
231 id.primaryScheme;
232 }
233 catch (e)
234 {
235 threw = e === Cr.NS_ERROR_NOT_INITIALIZED;
236 }
237 do_check_true(threw);
239 threw = false;
240 try
241 {
242 id.primaryHost;
243 }
244 catch (e)
245 {
246 threw = e === Cr.NS_ERROR_NOT_INITIALIZED;
247 }
248 do_check_true(threw);
250 threw = false;
251 try
252 {
253 id.primaryPort;
254 }
255 catch (e)
256 {
257 threw = e === Cr.NS_ERROR_NOT_INITIALIZED;
258 }
259 do_check_true(threw);
260 }
262 /**
263 * Utility function to check for a 400 response.
264 */
265 function check400(data)
266 {
267 var iter = LineIterator(data);
269 // Status-Line
270 var firstLine = iter.next();
271 do_check_eq(firstLine.substring(0, HTTP_400_LEADER_LENGTH), HTTP_400_LEADER);
272 }
275 /***************
276 * BEGIN TESTS *
277 ***************/
279 const HTTP_400_LEADER = "HTTP/1.1 400 ";
280 const HTTP_400_LEADER_LENGTH = HTTP_400_LEADER.length;
282 var test, data;
283 var tests = [];
285 // HTTP/1.0 request, to ensure we see our default scheme/host/port
287 function http10Request(request, response)
288 {
289 writeDetails(request, response);
290 response.setStatusLine("1.0", 200, "TEST PASSED");
291 }
292 data = "GET /http/1.0-request HTTP/1.0\r\n" +
293 "\r\n";
294 function check10(data)
295 {
296 var iter = LineIterator(data);
298 // Status-Line
299 do_check_eq(iter.next(), "HTTP/1.0 200 TEST PASSED");
301 skipHeaders(iter);
303 // Okay, next line must be the data we expected to be written
304 var body =
305 [
306 "Method: GET",
307 "Path: /http/1.0-request",
308 "Query: ",
309 "Version: 1.0",
310 "Scheme: http",
311 "Host: localhost",
312 "Port: 4444",
313 ];
315 expectLines(iter, body);
316 }
317 test = new RawTest("localhost", PORT, data, check10),
318 tests.push(test);
321 // HTTP/1.1 request, no Host header, expect a 400 response
323 data = "GET /http/1.1-request HTTP/1.1\r\n" +
324 "\r\n";
325 test = new RawTest("localhost", PORT, data, check400),
326 tests.push(test);
329 // HTTP/1.1 request, wrong host, expect a 400 response
331 data = "GET /http/1.1-request HTTP/1.1\r\n" +
332 "Host: not-localhost\r\n" +
333 "\r\n";
334 test = new RawTest("localhost", PORT, data, check400),
335 tests.push(test);
338 // HTTP/1.1 request, wrong host/right port, expect a 400 response
340 data = "GET /http/1.1-request HTTP/1.1\r\n" +
341 "Host: not-localhost:4444\r\n" +
342 "\r\n";
343 test = new RawTest("localhost", PORT, data, check400),
344 tests.push(test);
347 // HTTP/1.1 request, Host header has host but no port, expect a 400 response
349 data = "GET /http/1.1-request HTTP/1.1\r\n" +
350 "Host: 127.0.0.1\r\n" +
351 "\r\n";
352 test = new RawTest("localhost", PORT, data, check400),
353 tests.push(test);
356 // HTTP/1.1 request, Request-URI has wrong port, expect a 400 response
358 data = "GET http://127.0.0.1/http/1.1-request HTTP/1.1\r\n" +
359 "Host: 127.0.0.1\r\n" +
360 "\r\n";
361 test = new RawTest("localhost", PORT, data, check400),
362 tests.push(test);
365 // HTTP/1.1 request, Request-URI has wrong port, expect a 400 response
367 data = "GET http://localhost:31337/http/1.1-request HTTP/1.1\r\n" +
368 "Host: localhost:31337\r\n" +
369 "\r\n";
370 test = new RawTest("localhost", PORT, data, check400),
371 tests.push(test);
374 // HTTP/1.1 request, Request-URI has wrong scheme, expect a 400 response
376 data = "GET https://localhost:4444/http/1.1-request HTTP/1.1\r\n" +
377 "Host: localhost:4444\r\n" +
378 "\r\n";
379 test = new RawTest("localhost", PORT, data, check400),
380 tests.push(test);
383 // HTTP/1.1 request, correct Host header, expect handler's response
385 function http11goodHost(request, response)
386 {
387 writeDetails(request, response);
388 response.setStatusLine("1.1", 200, "TEST PASSED");
389 }
390 data = "GET /http/1.1-good-host HTTP/1.1\r\n" +
391 "Host: localhost:4444\r\n" +
392 "\r\n";
393 function check11goodHost(data)
394 {
395 var iter = LineIterator(data);
397 // Status-Line
398 do_check_eq(iter.next(), "HTTP/1.1 200 TEST PASSED");
400 skipHeaders(iter);
402 // Okay, next line must be the data we expected to be written
403 var body =
404 [
405 "Method: GET",
406 "Path: /http/1.1-good-host",
407 "Query: ",
408 "Version: 1.1",
409 "Scheme: http",
410 "Host: localhost",
411 "Port: 4444",
412 ];
414 expectLines(iter, body);
415 }
416 test = new RawTest("localhost", PORT, data, check11goodHost),
417 tests.push(test);
420 // HTTP/1.1 request, Host header is secondary identity
422 function http11ipHost(request, response)
423 {
424 writeDetails(request, response);
425 response.setStatusLine("1.1", 200, "TEST PASSED");
426 }
427 data = "GET /http/1.1-ip-host HTTP/1.1\r\n" +
428 "Host: 127.0.0.1:4444\r\n" +
429 "\r\n";
430 function check11ipHost(data)
431 {
432 var iter = LineIterator(data);
434 // Status-Line
435 do_check_eq(iter.next(), "HTTP/1.1 200 TEST PASSED");
437 skipHeaders(iter);
439 // Okay, next line must be the data we expected to be written
440 var body =
441 [
442 "Method: GET",
443 "Path: /http/1.1-ip-host",
444 "Query: ",
445 "Version: 1.1",
446 "Scheme: http",
447 "Host: 127.0.0.1",
448 "Port: 4444",
449 ];
451 expectLines(iter, body);
452 }
453 test = new RawTest("localhost", PORT, data, check11ipHost),
454 tests.push(test);
457 // HTTP/1.1 request, absolute path, accurate Host header
459 // reusing previous request handler so not defining a new one
461 data = "GET http://localhost:4444/http/1.1-good-host HTTP/1.1\r\n" +
462 "Host: localhost:4444\r\n" +
463 "\r\n";
464 test = new RawTest("localhost", PORT, data, check11goodHost),
465 tests.push(test);
468 // HTTP/1.1 request, absolute path, inaccurate Host header
470 // reusing previous request handler so not defining a new one
472 data = "GET http://localhost:4444/http/1.1-good-host HTTP/1.1\r\n" +
473 "Host: localhost:1234\r\n" +
474 "\r\n";
475 test = new RawTest("localhost", PORT, data, check11goodHost),
476 tests.push(test);
479 // HTTP/1.1 request, absolute path, different inaccurate Host header
481 // reusing previous request handler so not defining a new one
483 data = "GET http://localhost:4444/http/1.1-good-host HTTP/1.1\r\n" +
484 "Host: not-localhost:4444\r\n" +
485 "\r\n";
486 test = new RawTest("localhost", PORT, data, check11goodHost),
487 tests.push(test);
490 // HTTP/1.1 request, absolute path, yet another inaccurate Host header
492 // reusing previous request handler so not defining a new one
494 data = "GET http://localhost:4444/http/1.1-good-host HTTP/1.1\r\n" +
495 "Host: yippity-skippity\r\n" +
496 "\r\n";
497 function checkInaccurate(data)
498 {
499 check11goodHost(data);
501 // dynamism setup
502 srv.identity.setPrimary("http", "127.0.0.1", 4444);
503 }
504 test = new RawTest("localhost", PORT, data, checkInaccurate),
505 tests.push(test);
508 // HTTP/1.0 request, absolute path, different inaccurate Host header
510 // reusing previous request handler so not defining a new one
512 data = "GET /http/1.0-request HTTP/1.0\r\n" +
513 "Host: not-localhost:4444\r\n" +
514 "\r\n";
515 function check10ip(data)
516 {
517 var iter = LineIterator(data);
519 // Status-Line
520 do_check_eq(iter.next(), "HTTP/1.0 200 TEST PASSED");
522 skipHeaders(iter);
524 // Okay, next line must be the data we expected to be written
525 var body =
526 [
527 "Method: GET",
528 "Path: /http/1.0-request",
529 "Query: ",
530 "Version: 1.0",
531 "Scheme: http",
532 "Host: 127.0.0.1",
533 "Port: 4444",
534 ];
536 expectLines(iter, body);
537 }
538 test = new RawTest("localhost", PORT, data, check10ip),
539 tests.push(test);
542 // HTTP/1.1 request, Host header with implied port
544 function http11goodHostWackyPort(request, response)
545 {
546 writeDetails(request, response);
547 response.setStatusLine("1.1", 200, "TEST PASSED");
548 }
549 data = "GET /http/1.1-good-host-wacky-port HTTP/1.1\r\n" +
550 "Host: localhost\r\n" +
551 "\r\n";
552 function check11goodHostWackyPort(data)
553 {
554 var iter = LineIterator(data);
556 // Status-Line
557 do_check_eq(iter.next(), "HTTP/1.1 200 TEST PASSED");
559 skipHeaders(iter);
561 // Okay, next line must be the data we expected to be written
562 var body =
563 [
564 "Method: GET",
565 "Path: /http/1.1-good-host-wacky-port",
566 "Query: ",
567 "Version: 1.1",
568 "Scheme: http",
569 "Host: localhost",
570 "Port: 80",
571 ];
573 expectLines(iter, body);
574 }
575 test = new RawTest("localhost", PORT, data, check11goodHostWackyPort),
576 tests.push(test);
579 // HTTP/1.1 request, Host header with wacky implied port
581 data = "GET /http/1.1-good-host-wacky-port HTTP/1.1\r\n" +
582 "Host: localhost:\r\n" +
583 "\r\n";
584 test = new RawTest("localhost", PORT, data, check11goodHostWackyPort),
585 tests.push(test);
588 // HTTP/1.1 request, absolute URI with implied port
590 data = "GET http://localhost/http/1.1-good-host-wacky-port HTTP/1.1\r\n" +
591 "Host: localhost\r\n" +
592 "\r\n";
593 test = new RawTest("localhost", PORT, data, check11goodHostWackyPort),
594 tests.push(test);
597 // HTTP/1.1 request, absolute URI with wacky implied port
599 data = "GET http://localhost:/http/1.1-good-host-wacky-port HTTP/1.1\r\n" +
600 "Host: localhost\r\n" +
601 "\r\n";
602 test = new RawTest("localhost", PORT, data, check11goodHostWackyPort),
603 tests.push(test);
606 // HTTP/1.1 request, absolute URI with explicit implied port, ignored Host
608 data = "GET http://localhost:80/http/1.1-good-host-wacky-port HTTP/1.1\r\n" +
609 "Host: who-cares\r\n" +
610 "\r\n";
611 test = new RawTest("localhost", PORT, data, check11goodHostWackyPort),
612 tests.push(test);
615 // HTTP/1.1 request, a malformed Request-URI
617 data = "GET is-this-the-real-life-is-this-just-fantasy HTTP/1.1\r\n" +
618 "Host: localhost:4444\r\n" +
619 "\r\n";
620 test = new RawTest("localhost", PORT, data, check400),
621 tests.push(test);
624 // HTTP/1.1 request, a malformed Host header
626 data = "GET /http/1.1-request HTTP/1.1\r\n" +
627 "Host: la la la\r\n" +
628 "\r\n";
629 test = new RawTest("localhost", PORT, data, check400),
630 tests.push(test);
633 // HTTP/1.1 request, a malformed Host header but absolute URI, 5.2 sez fine
635 data = "GET http://localhost:4444/http/1.1-good-host HTTP/1.1\r\n" +
636 "Host: la la la\r\n" +
637 "\r\n";
638 test = new RawTest("localhost", PORT, data, check11goodHost),
639 tests.push(test);
642 // HTTP/1.0 request, absolute URI, but those aren't valid in HTTP/1.0
644 data = "GET http://localhost:4444/http/1.1-request HTTP/1.0\r\n" +
645 "Host: localhost:4444\r\n" +
646 "\r\n";
647 test = new RawTest("localhost", PORT, data, check400),
648 tests.push(test);
651 // HTTP/1.1 request, absolute URI with unrecognized host
653 data = "GET http://not-localhost:4444/http/1.1-request HTTP/1.1\r\n" +
654 "Host: not-localhost:4444\r\n" +
655 "\r\n";
656 test = new RawTest("localhost", PORT, data, check400),
657 tests.push(test);
660 // HTTP/1.1 request, absolute URI with unrecognized host (but not in Host)
662 data = "GET http://not-localhost:4444/http/1.1-request HTTP/1.1\r\n" +
663 "Host: localhost:4444\r\n" +
664 "\r\n";
665 test = new RawTest("localhost", PORT, data, check400),
666 tests.push(test);