You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bugs@httpd.apache.org by bu...@apache.org on 2005/08/23 07:17:49 UTC

DO NOT REPLY [Bug 36313] New: - Server hangs when mod_perl and proxy_connect are used together

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG�
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=36313>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND�
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=36313

           Summary: Server hangs when mod_perl and proxy_connect are used
                    together
           Product: Apache httpd-2.0
           Version: 2.0.54
          Platform: Other
        OS/Version: Windows XP
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Other Modules
        AssignedTo: bugs@httpd.apache.org
        ReportedBy: mikael.forslund@gmail.com


I have developed a simple perl filer (FilterConnectionHandler) that replaces the
URI and host part on the fly when issuing a HTTP 1.1 CONNECT request to the
server. (This did not work with the rewrite module as it seems that the
proxy_connect module is invoked before the rewrite module so the perl script was
the only way I could do this easily.) 

The effect of applying this filter to a connection url is this:

    http://localhost/test     =>     http://localhost:2098

For a mapping file (see the script below) that contains the mapping(s):

    /test localhost:2098
    /yahoo www.yahoo.com:80


This all works fine for up to 5 connections but for the 6'th connection the
apache webserver hangs indefinetely until I close one of the previous
connections. This means that the server is completely blocked and does not even
serve standard GET and POST requests. 

I have concluded that is definetly has something to do with mod_perl.so because
when I comment the perl stuff out from the httpd.conf file and specifying the
full internal host:port with the CONNECT command it all works very well.

So the basic modules needed for the CONNECT feature is this:
mod_proxy.so
mod_proxy_connect.so

And to do perl filtering I need:
mod_perl.so

Here is my script that does the filtering:

package TEST::CONNECTRewriter;
  
use strict;
use warnings;
use diagnostics;
  
use constant MAPPINGS    => "c:\\mappings.txt";
  
use base qw(Apache2::Filter);
use vars qw(@mappings $initialized);  
     
use Apache2::Log;  
use Apache2::ServerUtil;  
  
use APR::Brigade ();
use APR::Bucket ();
  
use Apache2::Const -compile => qw(OK DECLINED);
use APR::Const     -compile => ':common';
    
sub loadMappings {  	  	
    open(MAPPINGSFILE, "<" . MAPPINGS);  	
	
    my @mappinglist = <MAPPINGSFILE>;
    @mappinglist = sort(@mappinglist);
    my $mapping;

    foreach $mapping (@mappinglist)
    {	   
        my @targets = split('\s', $mapping);
	push(@mappings, [$targets[0],$targets[1]]);	   	   	   	   
    }
    close(MAPPINGSFILE);
}
  
sub handler : FilterConnectionHandler {
    $| = 1;

    my($filter, $bb, $mode, $block, $readbytes) = @_;
                      
    return Apache2::Const::DECLINED if $filter->ctx;

    Apache2::ServerUtil->server->log->info(">>>>>>>HANDLER ENTERED\n");
                      
    if($initialized == 0) {          
        &loadMappings;
        $initialized = 1;
    }
            
    Apache2::ServerUtil->server->log->info("before next_brigade\n");
      
    my $rv = $filter->next->get_brigade($bb, $mode, $block, $readbytes);
      
    Apache2::ServerUtil->server->log->info("after next_brigade\n");
      
    return $rv unless $rv == APR::Const::SUCCESS;     
  
    for (my $b = $bb->first; $b; $b = $bb->next($b)) 
    {     	  
        $b->read(my $data);
          
        Apache2::ServerUtil->server->log->info("data: $data\n");

        my $mapping;
	foreach $mapping (@mappings)
	{	   	      
  	    my $src = "CONNECT " . @{$mapping}[0] . " HTTP/1.1";	  	      
  	    my $rep = "CONNECT " . @{$mapping}[1] . " HTTP/1.1";	
  	        	      	  	      
            if ($data and $data =~ s|^($src)$|$rep|) 
            {
                my $nb = APR::Bucket->new($bb->bucket_alloc, $data);
                $b->insert_after($nb);
                $b->remove; # no longer needed
                $filter->ctx(1); # flag that that we have done the job
                last;
            }
        }  
    }      
    Apache2::ServerUtil->server->log->info("======= DONE =======\n");
  
    Apache2::Const::OK;
}
1;


I am using ActivePerl and the mod_perl.so associated with it. I can unfortunally
not provide with my test environment but the bug can be reproduced by doing
something simular to the following. Just startup one apache instance running the
PERL script found above and start 6 instances of telnet and connect to to the
server like so:

$ telnet localhost 80
Trying ###.###.###.###...
Connected to localhost
Escape character is '^]'.
CONNECT /yahoo HTTP/1.1
Host: /yahoo

The 6'th time the server is hanging and doesn't serve any request what so ever. 


I would be extremely happy if this "bug" was fixed... 
Happy hunting :) 
Cheers 
/Mikael Forslund

-- 
Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org