--- ../webinject/webinject.pl	2006-01-04 19:10:30.000000000 +0100
+++ webinject.pl	2009-07-03 08:59:17.000000000 +0200
@@ -1,6 +1,6 @@
 #!/usr/bin/perl -w
 
-#    Copyright 2004-2006 Corey Goldberg (corey@goldb.org)
+#    Copyright 2004-2009 Corey Goldberg (corey@goldb.org) & Jan Klepek (jan.klepek@brandforge.sk)
 #
 #    This file is part of WebInject.
 #
@@ -15,7 +15,8 @@
 #    GNU General Public License for more details.
 
 
-our $version="1.41";
+our $version="1.42";
+our $DEBUG=0;
 
 use strict;
 use LWP;
@@ -27,6 +28,7 @@
 use Crypt::SSLeay;  #for SSL/HTTPS (you may comment this out if you don't need it)
 use XML::Parser;  #for web services verification (you may comment this out if aren't doing XML verifications for web services)
 use Error qw(:try);  #for web services verification (you may comment this out if aren't doing XML verifications for web services)
+use File::Temp qw/ tempfile tempdir /; # for handling temporary files
 #use Data::Dumper;  #uncomment to dump hashes for debugging   
 
 
@@ -119,11 +121,13 @@
     #open file handles
     unless ($reporttype) {  #we suppress most logging when running in a plugin mode
         if ($opt_output) {  #use output location if it is passed from the command line
+	    print STDERR "output directory $opt_output\n" if ($DEBUG);
             open(HTTPLOGFILE, ">$opt_output"."http.log") or die "\nERROR: Failed to open http.log file\n\n";   
             open(RESULTS, ">$opt_output"."results.html") or die "\nERROR: Failed to open results.html file\n\n";    
             open(RESULTSXML, ">$opt_output"."results.xml") or die "\nERROR: Failed to open results.xml file\n\n";
         }
         else {
+	    print STDERR "standard output directory\n" if ($DEBUG);
             open(HTTPLOGFILE, ">$dirname"."http.log") or die "\nERROR: Failed to open http.log file\n\n";   
             open(RESULTS, ">$dirname"."results.html") or die "\nERROR: Failed to open results.html file\n\n";    
             open(RESULTSXML, ">$dirname"."results.xml") or die "\nERROR: Failed to open results.xml file\n\n";
@@ -170,16 +174,17 @@
             
         if ($gui == 1){ gui_processing_msg(); }
             
-        convtestcases();
+        my $tempfile = convtestcases();
             
-        fixsinglecase();
+        fixsinglecase($tempfile);
           
-        $xmltestcases = XMLin("$dirname"."$currentcasefile".".$$".".tmp", VarAttr => 'varname'); #slurp test case file to parse (and specify variables tag)
+        #$xmltestcases = XMLin("$dirname"."$currentcasefile".".$$".".tmp", VarAttr => 'varname'); #slurp test case file to parse (and specify variables tag)
+        $xmltestcases = XMLin($tempfile, VarAttr => 'varname');
         #print Dumper($xmltestcases);  #for debug, dump hash of xml   
-        #print keys %{$configfile};  #for debug, print keys from dereferenced hash
             
         #delete the temp file as soon as we are done reading it    
-        if (-e "$dirname"."$currentcasefile".".$$".".tmp") { unlink "$dirname"."$currentcasefile".".$$".".tmp"; }        
+        #if (-e "$dirname"."$currentcasefile".".$$".".tmp") { unlink "$dirname"."$currentcasefile".".$$".".tmp"; }        
+        if(-e $tempfile) {unlink $tempfile;}
             
             
         $repeat = $xmltestcases->{repeat};  #grab the number of times to iterate test case file
@@ -215,12 +220,12 @@
                 if ($case{verifynegativenext}) { $verifylaterneg = $case{verifynegativenext}; }  #grab $case{verifynegativenext} string from previous test case (if it exists)
                     
                 # populate variables with values from testcase file, do substitutions, and revert converted values back
-		for (qw/method description1 description2 url postbody posttype addheader
-			verifypositive verifypositive1 verifypositive2 verifypositive3
-			verifynegative verifynegative1 verifynegative2 verifynegative3
-			parseresponse parseresponse1 parseresponse2 parseresponse3 parseresponse4 parseresponse5
-			verifyresponsecode logrequest logresponse sleep errormessage
-			verifypositivenext verifynegativenext/) {
+                for (qw/method description1 description2 url postbody posttype addheader
+                        verifypositive verifypositive1 verifypositive2 verifypositive3
+                        verifynegative verifynegative1 verifynegative2 verifynegative3
+                        parseresponse parseresponse1 parseresponse2 parseresponse3 parseresponse4 parseresponse5
+                        verifyresponsecode logrequest logresponse sleep errormessage
+                        verifypositivenext verifynegativenext/) {
 		  $case{$_} = $xmltestcases->{case}->{$testnum}->{$_};
 		  if ($case{$_}) { convertbackxml($case{$_}); }
 		}
@@ -264,8 +269,8 @@
                     print RESULTS qq|<br />\n|;
                 }
 
-		for (qw/verifypositive verifypositive1 verifypositive2 verifypositive3
-			verifynegative verifynegative1 verifynegative2 verifynegative3/) {
+                for (qw/verifypositive verifypositive1 verifypositive2 verifypositive3
+                        verifynegative verifynegative1 verifynegative2 verifynegative3/) {
                     my $negative = $_ =~ /negative/ ? "Negative" : "";
                     if ($case{$_}) {
                         unless ($reporttype) {  #we suppress most logging when running in a plugin mode 
@@ -595,7 +600,7 @@
     if ($case{posttype}) {
 	if ($case{posttype} =~ m~application/x-www-form-urlencoded~) { httppost_form_urlencoded(); }
         elsif ($case{posttype} =~ m~multipart/form-data~) { httppost_form_data(); }
-        elsif (($case{posttype} =~ m~text/xml~) or ($case{posttype} =~ m~application/soap+xml~)) { httppost_xml(); }
+        elsif (($case{posttype} =~ m~text/xml~) or ($case{posttype} =~ m~application/soap\+xml~)) { httppost_xml(); }
         else { print STDERR qq|ERROR: Bad Form Encoding Type, I only accept "application/x-www-form-urlencoded", "multipart/form-data", "text/xml", "application/soap+xml" \n|; }
     }
     else {   
@@ -630,69 +635,81 @@
     $cookie_jar->extract_cookies($response);
     #print $cookie_jar->as_string; print "\n\n";
 }
-#------------------------------------------------------------------
-sub httppost_xml{  #send text/xml HTTP request and read response 
+#------------------------------------------------------------------ 
+sub httppost_xml{  #send text/xml HTTP request and read response  
     
-    #read the xml file specified in the testcase
-    $case{postbody} =~ m~file=>(.*)~i;
-    open(XMLBODY, "$dirname"."$1") or die "\nError: Failed to open text/xml file\n\n";  #open file handle   
-    my @xmlbody = <XMLBODY>;  #read the file into an array   
-    close(XMLBODY);
-        
-    $request = new HTTP::Request('POST', "$case{url}"); 
-    $request->content_type("$case{posttype}");
-    $request->content(join(" ", @xmlbody));  #load the contents of the file into the request body 
+    #read the xml file specified in the testcase 
+    $case{postbody} =~ m~file=>(.*)~i; 
+ 
+    open(XMLBODY, "$dirname"."$1") or die "\nError: Failed to open text/xml file\n\n";  #open file handle    
+    # added for variables support with XML posts  
+    my @xmlbody = (''); 
+    while ($_ = <XMLBODY> ) { 
+        if ($_ =~ /\{PARSEDRESULT.\}/) {
+            # Replace text, all instances on a line (/g) 
+            $_ =~ s/{PARSEDRESULT}/$parsedresult{parseresponse}/g; 
+            $_ =~ s/{PARSEDRESULT1}/$parsedresult{parseresponse1}/g; 
+            $_ =~ s/{PARSEDRESULT2}/$parsedresult{parseresponse2}/g; 
+            $_ =~ s/{PARSEDRESULT3}/$parsedresult{parseresponse3}/g; 
+            $_ =~ s/{PARSEDRESULT4}/$parsedresult{parseresponse4}/g; 
+            $_ =~ s/{PARSEDRESULT5}/$parsedresult{parseresponse5}/g; 
+        } 
+        push(@xmlbody,"$_");
+    } 
+    close(XMLBODY); 
     
-    if ($case{addheader}) {  #add an additional HTTP Header if specified
-        my @addheaders = split(/\|/, $case{addheader});  #can add multiple headers with a pipe delimiter
-        foreach (@addheaders) {
-            $_ =~ m~(.*): (.*)~;
-            $request->header($1 => $2);  #using HTTP::Headers Class
-        }
-        $case{addheader} = '';
-    }
+    $request = new HTTP::Request('POST', "$case{url}");  
+    $request->content_type("$case{posttype}"); 
+    $request->content(join("", @xmlbody));  #load the contents of the file into the request body  
     
-    $cookie_jar->add_cookie_header($request);
-    #print $request->as_string; print "\n\n";    
-    $starttimer = time(); 
-    $response = $useragent->request($request); 
-    $endtimer = time(); 
-    $latency = (int(1000 * ($endtimer - $starttimer)) / 1000);  #elapsed time rounded to thousandths 
-    #print $response->as_string; print "\n\n";    
+    if ($case{addheader}) {  #add an additional HTTP Header if specified 
+        my @addheaders = split(/\|/, $case{addheader});  #can add multiple headers with a pipe delimiter 
+        foreach (@addheaders) { 
+            $_ =~ m~(.*): (.*)~; 
+            $request->header($1 => $2);  #using HTTP::Headers Class 
+        } 
+        $case{addheader} = ''; 
+    } 
 
-    $cookie_jar->extract_cookies($response);
+    $cookie_jar->add_cookie_header($request); 
+    #print $request->as_string; print "\n\n";     
+    $starttimer = time();  
+    $response = $useragent->request($request);  
+    $endtimer = time();  
+    $latency = (int(1000 * ($endtimer - $starttimer)) / 1000);  #elapsed time rounded to thousandths  
+    #print $response->as_string; print "\n\n";     
+ 
+    $cookie_jar->extract_cookies($response); 
     #print $cookie_jar->as_string; print "\n\n";
-
-
-    my $xmlparser = new XML::Parser;
-    try {  #see if the XML parses properly
-        $xmlparser->parse($response->content);
-        #print "good xml\n";
-        unless ($reporttype) {  #we suppress most logging when running in a plugin mode
-            print RESULTS qq|<span class="pass">Passed XML Parser (content is well-formed)</span><br />\n|;
-            print RESULTSXML qq|            <verifyxml-success>true</verifyxml-success>\n|;
-        }
-        unless ($nooutput) { #skip regular STDOUT output 
-            print STDOUT "Passed XML Parser (content is well-formed) \n";
-        }
-        $passedcount++;
-        return; #exit try block
-    }
-    catch Error with {
-        my $ex = shift;  #get the exception object
-        #print "bad xml\n";
-        unless ($reporttype) {  #we suppress most logging when running in a plugin mode
-            print RESULTS qq|<span class="fail">Failed XML Parser: $ex</span><br />\n|;
-            print RESULTSXML qq|            <verifyxml-success>false</verifyxml-success>\n|;
-        }
+    
+    my $xmlparser = new XML::Parser; 
+    try {  #see if the XML parses properly 
+        $xmlparser->parse($response->content); 
+        #print "good xml\n"; 
+        unless ($reporttype) {  #we suppress most logging when running in a plugin mode 
+            print RESULTS qq|<span class="pass">Passed XML Parser (content is well-formed)</span><br />\n|; 
+            print RESULTSXML qq|  <verifyxml-success>true</verifyxml-success>\n|; 
+        } 
         unless ($nooutput) { #skip regular STDOUT output  
-            print STDOUT "Failed XML Parser: $ex \n";         
-        }
-        $failedcount++;
-        $isfailure++;
-    };  # <-- remember the semicolon
-
-}
+            print STDOUT "Passed XML Parser (content is well-formed) \n"; 
+        } 
+        $passedcount++; 
+        return; #exit try block 
+    } 
+    catch Error with { 
+        my $ex = shift;  #get the exception object 
+        #print "bad xml\n"; 
+        unless ($reporttype) {  #we suppress most logging when running in a plugin mode 
+            print RESULTS qq|<span class="fail">Failed XML Parser: $ex</span><br />\n|; 
+            print RESULTSXML qq|  <verifyxml-success>false</verifyxml-success>\n|; 
+        } 
+        unless ($nooutput) { #skip regular STDOUT output   
+            print STDOUT "Failed XML Parser: $ex \n";     
+        } 
+        $failedcount++; 
+        $isfailure++; 
+    };  # <-- remember the semicolon 
+} 
 #------------------------------------------------------------------
 sub httppost_form_data {  #send multipart/form-data HTTP request and read response
 	
@@ -1037,12 +1054,12 @@
     foreach (@configfile) {
 
         for my $config_const (qw/baseurl baseurl1 baseurl2 gnuplot proxy timeout
-                globaltimeout globalhttplog standaloneplot/) {
+                globaltimeout globalhttplog standaloneplot opt_output/) {
 
             if (/<$config_const>/) {
                 $_ =~ m~<$config_const>(.*)</$config_const>~;
                 $config{$config_const} = $1;
-                #print "\n$_ : $config{$_} \n\n";
+                print "\n$_ : $config{$_} \n\n" if ($DEBUG);
             }
         }
             
@@ -1052,16 +1069,21 @@
                $reporttype = $1;
 	       $nooutput = "set";
 	    } 
-            #print "\nreporttype : $reporttype \n\n";
+            print "\nreporttype : $reporttype \n\n" if ($DEBUG);
         }    
-            
+        if (/<outputdir>/) {
+		$_ =~ m~<outputdir>(.*)</outputdir>~;
+		$opt_output=$1;
+		print "\noutput_dir : $opt_output \n\n" if ($DEBUG);
+
+	}    
         if (/<useragent>/) {   
             $_ =~ m~<useragent>(.*)</useragent>~;
             $setuseragent = $1;
             if ($setuseragent) { #http useragent that will show up in webserver logs
                 $useragent->agent($setuseragent);
             }  
-            #print "\nuseragent : $setuseragent \n\n";
+            print "\nuseragent : $setuseragent \n\n" if ($DEBUG);
         }
          
         if (/<httpauth>/) {
@@ -1111,10 +1133,27 @@
         
     close(XMLTOCONVERT);   
         
-    open(XMLTOCONVERT, ">$dirname"."$currentcasefile".".$$".".tmp") or die "\nERROR: Failed to open temp file for writing\n\n";  #open file handle to temp file  
-    print XMLTOCONVERT @xmltoconvert;  #overwrite file with converted array
-    close(XMLTOCONVERT);
+#    open(XMLTOCONVERT, ">$dirname"."$currentcasefile".".$$".".tmp") or die "\nERROR: Failed to open temp file for writing\n\n";  #open file handle to temp file  
+    our ($fh, $filename) = tempfile(UNLINK => 1, DIR => &getostempdir) or die "\nERROR: Failed to create temporary file in ".&getostempdir."\n"; # create temporary files for storage of converted file
+    print STDERR "temp filename $filename\n" if ($DEBUG);
+#    print XMLTOCONVERT @xmltoconvert;  #overwrite file with converted array
+    print $fh @xmltoconvert;
+    close ($fh);
+#    close(XMLTOCONVERT); 
+    return $filename;
+}
+#-----------------------------------------------------------------
+# get temporary directory based on OS
+sub getostempdir{
+	print STDERR "os: ".$^O."\n" if ($DEBUG);
+	if ($^O =~ m/win/i) {
+		return "c:\\";
+	}
+	else {
+		return "/tmp/";
+	}
 }
+
 #------------------------------------------------------------------
 sub fixsinglecase{ #xml parser creates a hash in a different format if there is only a single testcase.
                    #add a dummy testcase to fix this situation
@@ -1122,8 +1161,9 @@
     my @xmltoconvert;
         
     if ($casecount == 1) {
-            
-        open(XMLTOCONVERT, "$dirname"."$currentcasefile".".$$".".tmp") or die "\nError: Failed to open temp file\n\n";  #open file handle   
+        my $temp = $_[0];    
+        #open(XMLTOCONVERT, "$dirname"."$currentcasefile".".$$".".tmp") or die "\nError: Failed to open temp file\n\n";  #open file handle   
+        open(XMLTOCONVERT,"$temp");
         @xmltoconvert = <XMLTOCONVERT>;  #read the file into an array
             
         for(@xmltoconvert) { 
@@ -1131,7 +1171,8 @@
         }       
         close(XMLTOCONVERT);
             
-        open(XMLTOCONVERT, ">$dirname"."$currentcasefile".".$$".".tmp") or die "\nERROR: Failed to open temp file for writing\n\n";  #open file handle   
+        #open(XMLTOCONVERT, ">$dirname"."$currentcasefile".".$$".".tmp") or die "\nERROR: Failed to open temp file for writing\n\n";  #open file handle   
+        open(XMLTOCONVERT,">$temp") or die "\nERROR: Failed to create temporary file in ".&getostempdir."\n";
         print XMLTOCONVERT @xmltoconvert;  #overwrite file with converted array
         close(XMLTOCONVERT);
     }
