Permalink
Browse files

Add middleware to fix bad IIS7 bad behaviour.

https://rt.cpan.org/Ticket/Display.html?id=78377

Only applies to IIS version 7, with keepalives enabled.

IIS will happily read a 3XX response, and do the redirect,
sending it's own body to the client. The body of your redirect is
never read, meaning that the next client connection gets this
prepended to the HTTP header, which results in it getting
something insane looking, and generating a 500 page.

Apply with something like:

$psgi_app = Plack::Middleware::Conditional->wrap(
    $psgi_app,
    builder => sub { Plack::Middleware::IIS7KeepAliveFix->wrap($_[0]) },
    condition => sub {
        my ($env) = @_;
        return unless $env->{SERVER_SOFTWARE} && $env->{SERVER_SOFTWARE} =~ m!IIS\/7\.[0-9]!; 1; }, );
    },
);
  • Loading branch information...
1 parent ac05d09 commit a3e1bde6e92466ce0fb0e6b712db4a4150437bac @bobtfish bobtfish committed Jul 18, 2012
Showing with 95 additions and 0 deletions.
  1. +54 −0 lib/Plack/Middleware/IIS7KeepAliveFix.pm
  2. +41 −0 t/Plack-Middleware/iis7_keep_alive_fix.t
@@ -0,0 +1,54 @@
+package Plack::Middleware::IIS7KeepAliveFix;
+
+use strict;
+use parent 'Plack::Middleware';
+use Plack::Util;
+
+sub call {
+ my($self, $env) = @_;
+ # Fixes buffer being cut off on redirect when keep-alive is active
+ my $res = $self->app->($env);
+
+ Plack::Util::response_cb($res, sub {
+ my $res = shift;
+ if ($res->[0] =~ m!^30[123]$! ) {
+ Plack::Util::header_remove($res->[1], 'Content-Length');
+ Plack::Util::header_remove($res->[1], 'Content-Type');
+ return sub{ my $chunk; return unless defined $chunk; return ''; };
+ }
+
+ return;
+ });
+
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Plack::Middleware::IIS7KeepAliveFix - fixes buffer being cut off on redirect when keep-alive is active on IIS.
+
+=head1 SYNOPSIS
+
+ # in your app.psgi
+ use Plack::Builder;
+
+ builder {
+ enable "IIS7KeepAliveFix";
+ $app;
+ };
+
+ # Or from the command line
+ plackup -s FCGI -e 'enable "IIS7KeepAliveFix"' /path/to/app.psgi
+
+=head1 DESCRIPTION
+
+This middleware fixes buffer being cut off on redirect when keep-alive is active on IIS7.
+
+=head1 AUTHORS
+
+KnowZeroX
+
+=cut
+
@@ -0,0 +1,41 @@
+use strict;
+use Test::More;
+use Plack::Test;
+use HTTP::Request::Common;
+use Plack::Middleware::IIS7KeepAliveFix;
+
+
+my $app=Plack::Middleware::IIS7KeepAliveFix->wrap(
+sub {
+ my $env = shift;
+
+
+ my $location='/go/?'.join('|', (0..1000));
+ return [ 302, [
+ 'Content-Type' => 'text/html',
+ 'Content-Length' => 285,
+ 'Location' => $location,
+ ],[qq~<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Moved</title>
+ </head>
+ <body>
+ <p>This item has moved <a href="$location">here</a>.</p>
+ </body>
+</html>~] ];
+});
+
+
+test_psgi(app=>$app,client=> sub {
+ my $cb = shift;
+
+ my $res = $cb->(GET "/");
+
+ ok(!$res->content);
+ ok(!$res->content_length);
+ ok(!$res->content_type);
+});
+
+done_testing;
+

0 comments on commit a3e1bde

Please sign in to comment.