/t/32-pipelining.t

http://github.com/perlbal/Perlbal · Perl · 100 lines · 68 code · 21 blank · 11 comment · 1 complexity · 198863243dd41b0b039e0e14123baa8e MD5 · raw file

  1. #!/usr/bin/perl
  2. #
  3. # For now we don't support pipelining, so these tests verify we handle it
  4. # properly, notably not poisoning the backend by injecting two when we only
  5. # know of one, and also dealing okay with POSTs with an extra \r\n, which
  6. # happen in the real world, without disconnecting those users thinking
  7. # they're bogus-pipeline-flooding us.
  8. #
  9. use strict;
  10. use Perlbal::Test;
  11. use Perlbal::Test::WebServer;
  12. use Perlbal::Test::WebClient;
  13. use Test::More tests => 12;
  14. require HTTP::Request;
  15. my $port = new_port();
  16. my $dir = tempdir();
  17. # setup a few web servers that we can work with
  18. my $start_servers = 1; # web servers to start
  19. my @web_ports = map { start_webserver() } 1..$start_servers;
  20. @web_ports = grep { $_ > 0 } map { $_ += 0 } @web_ports;
  21. ok(scalar(@web_ports) == $start_servers, 'web servers started');
  22. my $conf = qq{
  23. CREATE POOL a
  24. CREATE SERVICE test
  25. SET test.role = reverse_proxy
  26. SET test.listen = 127.0.0.1:$port
  27. SET test.persist_client = 1
  28. SET test.persist_backend = 1
  29. SET test.pool = a
  30. SET test.connect_ahead = 0
  31. ENABLE test
  32. };
  33. my $http = "http://127.0.0.1:$port";
  34. my $msock = start_server($conf);
  35. ok($msock, "manage sock");
  36. add_all();
  37. my $sock;
  38. my $get_sock = sub {
  39. return IO::Socket::INET->new(PeerAddr => "127.0.0.1:$port")
  40. or die "Failed to connect to perlbal";
  41. };
  42. $sock = $get_sock->();
  43. print $sock "POST /sleep:0.2,status HTTP/1.0\r\nContent-Length: 10\r\n\r\nfoo=56789a";
  44. like(scalar <$sock>, qr/200 OK/, "200 OK on post w/ correct len");
  45. $sock = $get_sock->();
  46. print $sock "POST /sleep:0.2,status HTTP/1.0\r\nContent-Length: 10\r\n\r\nfoo=56789a\r\n";
  47. like(scalar <$sock>, qr/200 OK/, "200 OK on post w/ extra rn not in length");
  48. # test that signal sending works
  49. {
  50. my $gotsig = 0;
  51. local $SIG{USR1} = sub { $gotsig = 1; };
  52. $sock = $get_sock->();
  53. print $sock "GET /kill:$$:USR1,status HTTP/1.0\r\n\r\n";
  54. like(scalar <$sock>, qr/200 OK/, "single GET okay");
  55. ok($gotsig, "got signal");
  56. }
  57. # check that somebody can't sneak extra request to backend w/ both \r\n and nothing in between requests
  58. foreach my $sep ("\r\n", "") {
  59. diag("separator length " . length($sep));
  60. my $gotsig = 0;
  61. local $SIG{USR1} = sub { $gotsig = 1; };
  62. $sock = $get_sock->();
  63. print $sock "POST /sleep:0.5,status HTTP/1.0\r\nConnection: keep-alive\r\nContent-Length: 10\r\n\r\nfoo=569789a${sep}GET /kill:$$:USR1,status HTTP/1.0\r\n\r\n";
  64. like(scalar <$sock>, qr/200 OK/, "200 to POST w/ pipelined GET after");
  65. select undef, undef, undef, 0.25;
  66. ok(!$gotsig, "didn't get signal from GET after POST");
  67. }
  68. $sock = $get_sock->();
  69. print $sock "GET /status HTTP/1.0\r\n\r\n";
  70. like(scalar <$sock>, qr/200 OK/, "single GET okay");
  71. $sock = $get_sock->();
  72. print $sock "GET /status HTTP/1.0\r\n\r\nGET /status HTTP/1.0\r\n\r\n";
  73. like(scalar <$sock>, qr/\b400\b/, "pipelined when not expecting it");
  74. sub add_all {
  75. foreach (@web_ports) {
  76. manage("POOL a ADD 127.0.0.1:$_") or die;
  77. }
  78. }
  79. 1;