in reply to Cookie blues with LWP::Cookies

Hi,
just in case anyone is still reading I did it on
win32 using fork and win32::pipe (the hard way)
here is the code:
(which is also compilable as an .exe with activestate perlapp
g.
#!/usr/bin/perl ## forkin pipin stresser ## requires conf file url.txt ## creates output file out.txt use strict; use Win32::Pipe; use LWP::UserAgent; use Sys::Hostname; use Time::HiRes qw(gettimeofday tv_interval); use HTTP::Cookies; use CGI; ## these modules are required for compiling: use warnings; use File::Spec::Win32; ###### debug LWP #use LWP::Debug qw(+); ###### vars declarations my $host = hostname; my $PipeName = "\\\\$host\\pipe\\My Named Pipe"; ############### my ($totsuc,$succeeded,$quantifigli,$DEBUG,@parametro,$totaltime,$ct,$ +ct2,,$ctritorni,$idauth,$DEBUGOUT,$pwdauth,$AUTH,@urls,@params,@varia +b,$Pipe,$data,$User,$pidserver,@pid,$total_time,%errors,$nof_requests +_total); my $cookies = HTTP::Cookies->new; $totsuc=0; $ct=0; $ct2=0; ########## reads conf.txt for urls and params # overrides some vars predefined vars open CONF, "url.txt" or die "Cannot open url.txt for read :$!"; while (<CONF>) { chomp; # no newline s/#.*//; # no comments s/^\s+//; # no leading white s/\s+$//; # no trailing white if ($_=~/nof_requests_total=(.*)$/) { $nof_requests_total=$1;next ;} if ($_=~/AUTH=(.*)$/) { $AUTH=$1;next; } if ($_=~/idauth=(.*)$/) { $idauth=$1;next; } if ($_=~/pwdauth=(.*)$/) { $pwdauth=$1;next; } if ($_=~/DEBUGOUT=(.*)$/) { $DEBUGOUT=$1;next; } if ($_=~/DEBUG=(.*)$/) { $DEBUG=$1;next; } if ($_=~/quantifigli=(.*)$/) { $quantifigli=$1;next; } next unless length; # anything left? @variab=split /\t/, $_; push (@urls,$variab[0]); ## populates params array # params are <tab>name1=value1&name2=value2.... my @riga=split /&/, $variab[1]; foreach(@riga) { my @parametro=split /=/, $_; $parametro[1]="=".&URL_Encode($parametro[1])."&"; $params[$ct]=$params[$ct].$parametro[0].$parametro[1] } $ct++; } close CONF; ############# print "Golem's own FPS (Forkin Pipin Stresser)\n"; # flush STOUT $| = 1; if ($DEBUG) {print "padre: io sono pid $$ \n";} ## time before begin my $before=gettimeofday; ### forks the named pipe server######## if ( $pidserver = fork() ) { if ($DEBUG) {print "padre: $$ mio figlio pid: $pidserver \n";} } # The Child portion of the named pipe server Fork # elsif ( defined( $pidserver ) ) { # here child code (namedpipeserver) if ($DEBUG) { print "server con pid: $$ \n";} namedpipeserver("My Named Pipe"); exit(); } #################end named pipe server fork########## ###### forks the client agents foreach (1..$quantifigli) { if ( $pid[$ct] = fork() ) { if ($DEBUG) {print "padre: $$ mio figlio pid: $pid[$ct] \n";} } # The Child portion of the Fork elsif ( defined( $pid[$ct] ) ) { # child code here: if ($DEBUG) { print "figlio con pid: $$ \n";} # requests URL for data &richieste; $|=1; if ($DEBUG) {$data = $data."Server=" . Win32::NodeName() . "\nTime=" . + localtime() . "\n";} $data.="pid=$$\&succeded=$succeeded\&errors="; ### # sends this data to named pipe server connpipe($PipeName,$data); exit(); } else { die( "Could not Fork" ); } ########fine for: } #################### end clients fork########## exit; #####################end############################################## +####################### ## sub: write on named pipe ## input params: pipe name and data to write sub connpipe { my ($Pipename,$Data)=@_; if ($DEBUG) {print "Connecting to $PipeName\n";} if( $Pipe = new Win32::Pipe( $PipeName ) ) { if ($DEBUG) { print "\nPipe has been opened, writing data to it...\n" +;} $Pipe->Write( $Data ); $Pipe->Close(); } else { print "Error connecting: " . Win32::FormatMessage( $Win32::Pipe::Err +or ) . "\n"; } } ############################################## #########sub download a cicle of URLs sub download { my $ua = new LWP::UserAgent; $ua->agent("Mozilla/4.76 [en] (Windows NT 5.0; U)"); ## cookies my $cookies = HTTP::Cookies->new; $ua->cookie_jar($cookies); # url counter my $ct=0; foreach my $url (@urls) { my $request = HTTP::Request->new('POST', $url); $request->content_type('application/x-www-form-urlencoded'); $request->content($params[$ct]); $ct++; # basic auth if ($AUTH) { $request->authorization_basic($idauth, $pwdauth); } my $response = $ua->request($request); if ($response->is_success) { # successo $succeeded++; # debug output if ($DEBUGOUT) { print $response->content; } } else { ## failure print "Download of $url failed\n"; $response->message("TIMEOUT") unless $response->code(); $errors{$response->message}++; } } } # Usage : $URL_encoded = &URL_Encode("$plaintext"); sub URL_Encode { my($text) = $_[0]; # text to URL encode $text=CGI::escape($text); return $text; # return URL encoded text } ### sub requests # loops al URL requests # for each clients the given times sub richieste { foreach (1..$nof_requests_total) { &download; } } ############### ### sub create a named pipe server # param : named pipe name sub namedpipeserver { my $PipeName=shift(@_); $| = 1; my $bServerContinue = 1; if ($DEBUG) {print "Creating pipe \"$PipeName\".\n";} if( my $Pipe = new Win32::Pipe( $PipeName ) ) { while( $bServerContinue ) { if ($DEBUG) { print "Waiting for a client to connect...\n";} if( $Pipe->Connect() ) { my $In; $User = ( $Pipe->GetInfo() )[2]; if ($DEBUG) { print "Pipe opened by $User.\n";} $In = $Pipe->Read(); if ($DEBUG) {print "************Client sent us: \n$In\n************\n" +;} ####### collects data in $In parsaIn($In); ###################################################################### +###### if ($DEBUG) { print "Disconnecting...\n";} $Pipe->Disconnect(); ### controllo di uscita $ctritorni++; if ($DEBUG) { print "\n******* $ctritorni $quantifigli\n";} if ($ctritorni eq $quantifigli) { if ($DEBUG) {print "\n tornati tutti i figli\n";} $bServerContinue=0; ## stampa risultati results(); } ### } } $Pipe->Close(); } else { print "\nCould not create pipe\n"; print "Error: " . Win32::FormatMessage( $Win32::Pipe::Error ) . "\n" +; } } ####################sub print out results sub results { # total time for requests $totaltime = gettimeofday-$before; ## errors collecting (needs to be fixed) my $errors = join(',', map "$_ ($errors{$_})", keys %errors); $errors = "NONE" unless $errors; #### my @P = ( "URL(s)" => join("\n", @urls), "Total Requests Loops per agent" => "$nof_requests_total", "Number of Parallel Agents" => $quantifigli, "Total succeeded reqs" => $totsuc, "% Succeeded" => ((100*$totsuc / ($nof_requests_total*$ +quantifigli*scalar(@urls)))), "Errors" => $errors, "Total Time" => sprintf("%.2f secs\n", $totaltime), "Throughput" => sprintf("%.2f Requests/sec\n", $nof_requests_total / $totaltime), # "Latency" => sprintf("%.2f secs/Request", # ($ua->get_latency_total() || 0) / # $nof_requests_total), ); ### # Print out statistics ### if ($DEBUG) { print "\n#################### results #################\n"; foreach (@P) { print "$_ \n"; } } ### open OUT, ">out.txt" or die "Cannot open out.txt for write :$!"; foreach (@P) { print OUT "$_ \n"; } close OUT; ## } ########sub parsaIN: ## reads params passed to named pipe server and # sets global results vars sub parsaIn { my $In=shift(@_); my @riga=split /&/, $In; foreach(@riga) { if ($_=~/succeded=(.*)$/) { $totsuc=$totsuc+$1; next; } } }