proxy_noclose.t 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #!/usr/bin/perl
  2. # (C) Maxim Dounin
  3. # Test for http backend not closing connection properly after sending full
  4. # reply. This is in fact backend bug, but it seems common, and anyway
  5. # correct handling is required to support persistent connections.
  6. # There are actually 2 nginx problems here:
  7. #
  8. # 1. It doesn't send reply in-time even if got Content-Length and all the data.
  9. #
  10. # 2. If upstream times out some data may be left in input buffer and won't be
  11. # sent to downstream.
  12. ###############################################################################
  13. use warnings;
  14. use strict;
  15. use Test::More;
  16. use IO::Select;
  17. BEGIN { use FindBin; chdir($FindBin::Bin); }
  18. use lib 'lib';
  19. use Test::Nginx;
  20. ###############################################################################
  21. select STDERR; $| = 1;
  22. select STDOUT; $| = 1;
  23. my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(4);
  24. $t->write_file_expand('nginx.conf', <<'EOF');
  25. %%TEST_GLOBALS%%
  26. master_process off;
  27. daemon off;
  28. events {
  29. }
  30. http {
  31. %%TEST_GLOBALS_HTTP%%
  32. server {
  33. listen 127.0.0.1:8080;
  34. server_name localhost;
  35. location / {
  36. proxy_pass http://127.0.0.1:8081;
  37. proxy_read_timeout 1s;
  38. }
  39. location /uselen {
  40. proxy_pass http://127.0.0.1:8081;
  41. # test will wait only 2s for reply, we it will fail if
  42. # Content-Length not used as a hint
  43. proxy_read_timeout 10s;
  44. }
  45. }
  46. }
  47. EOF
  48. $t->run_daemon(\&http_noclose_daemon);
  49. $t->run();
  50. ###############################################################################
  51. TODO: {
  52. local $TODO = 'not fixed yet, patches under review';
  53. local $SIG{__WARN__} = sub {};
  54. like(http_get('/'), qr/SEE-THIS/, 'request to bad backend');
  55. like(http_get('/multi'), qr/AND-THIS/, 'bad backend - multiple packets');
  56. like(http_get('/nolen'), qr/SEE-THIS/, 'bad backend - no content length');
  57. like(http_get('/uselen'), qr/SEE-THIS/, 'content-length actually used');
  58. }
  59. ###############################################################################
  60. sub http_noclose_daemon {
  61. my $server = IO::Socket::INET->new(
  62. Proto => 'tcp',
  63. LocalAddr => '127.0.0.1:8081',
  64. Listen => 5,
  65. Reuse => 1
  66. )
  67. or die "Can't create listening socket: $!\n";
  68. while (my $client = $server->accept()) {
  69. $client->autoflush(1);
  70. my $multi = 0;
  71. my $nolen = 0;
  72. while (<$client>) {
  73. $multi = 1 if /multi/;
  74. $nolen = 1 if /nolen/;
  75. last if (/^\x0d?\x0a?$/);
  76. }
  77. if ($nolen) {
  78. print $client <<'EOF';
  79. HTTP/1.1 200 OK
  80. Connection: close
  81. TEST-OK-IF-YOU-SEE-THIS
  82. EOF
  83. } elsif ($multi) {
  84. print $client <<"EOF";
  85. HTTP/1.1 200 OK
  86. Content-Length: 32
  87. Connection: close
  88. TEST-OK-IF-YOU-SEE-THIS
  89. EOF
  90. select undef, undef, undef, 0.1;
  91. print $client 'AND-THIS';
  92. } else {
  93. print $client <<"EOF";
  94. HTTP/1.1 200 OK
  95. Content-Length: 24
  96. Connection: close
  97. TEST-OK-IF-YOU-SEE-THIS
  98. EOF
  99. }
  100. my $select = IO::Select->new($client);
  101. $select->can_read(10);
  102. close $client;
  103. }
  104. }
  105. ###############################################################################