Perl CGI download file - perl

I need to create an HTML file which input text or file. The text will be processed and printed while the file is processed and downloaded.
I am not able to create download. I tried with download header, but it didn't work. A new file will be created with #array after processing the file. output_file.txt should be downloadable by the user.
#!C:/perl64/bin/perl.exe
use strict;
use warnings;
use CGI::Pretty qw(:all);
# HTML
print header();
print start_html();
print start_form();
print textfield('text');
print (submit);
print filefield('file');
print submit();
print end_form();
print end_html();
if (param ('file')) {
my $fh = param('file');
# File processed to get #result and made new file
open (OUT, ">output/output_file.txt");
print OUT #result;
# Need to download output_file.txt file
}
# Text processed and printed
elsif(param('text')){
my $text = param('text')
}

Try the following:
#!/usr/bin/perl -w
use strict;
use warnings;
use CGI::Pretty qw(:all);
my #result;
if (param ('file')) {
my $file_name=param('file');
my $file_handle =upload('file');
my $file_size=-s $file_handle;
print header(
-type=>'application/octet-stream',
-attachment=> $file_name,
-Content_Length=>$file_size
);
# file processed to get #result and made new file
binmode($file_handle);
while (<$file_handle>){
print $_;
push (#result,$_);
}
# need to download output_file.txt file
}
# text processed and printed
elsif(param('text')){
my $text = param('text');
print header(
-type=>'application/octet-stream',
-attachment=> "Sample.txt",
-Content_Length=>length($text)
);
print $text;
}
# html
print header();
print start_html();
print start_form();
print textfield('text');
print (submit);
print end_form();
print start_form();
print filefield('file');
print submit();
print end_form();
print end_html();

Here's an example I modified:
#!C:\Program Files\perl\bin\perl.exe
use CGI ':standard';
use CGI::Carp qw ( fatalsToBrowser );
$input_val = $ENV{'QUERY_STRING'};
($field_name, $command) = split (/=/, $input_val);
($file_name, $option_name) = split(/&/, $command);
$file_path= "Database/$file_name";
$directorypath = "Database/";
my $files_location;
my #fileholder;
$files_location = $directorypath;
if ($file_name eq '')
{
print "Content-type: text/html\n\n";
print "File doesn't exist";
} else {
open(DLFILE, "<$files_location/$file_name") || Error('open', 'file');
#fileholder = <DLFILE>;
close (DLFILE) || Error ('close', 'file');
print "Content-Type:application/x-download\n";
print "Content-Disposition:attachment;filename=$file_name\n\n";
print #fileholder;
}
print "</HTML>";
exit 0;
Refer to this website: http://www.perlnotes.com/study0680.htm

Related

Getting Blank Screen for Perl CGI Script

I am getting blank screen for the below Perl CGI Script on the web page.
Script is getting executed fine on the terminal, but when I run it from the web browser it is blank. Please help.
This works when I move the Web Content to the top of the page. Basically whatever content I put after the DB connection is not getting displayed on the web browser.
OS : Unix
Apache2 Web Server
Note: The script has execute permission.
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
use CGI;
print "Content-type: text/html\n\n";
# Simple HTML code follows
my $driver= "Oracle";
my $dsn = "DBI:$driver:sid=xxxxx;host=xxxxx;port=1521";
my $dbh = DBI->connect($dsn,'xxxx','xxxx');
#print $dbh;
my $sth = $dbh->prepare("SELECT * FROM TABLE WHERE ROWNUM <= 10");
$sth->execute;
print "<html> <head>\n";
print "<title>Hello, world!</title>";
print "</head>\n";
print "<body>\n";
print "<h1>Hello, world!</h1>\n";
print "<p>The Details are as follows:</p>\n";
print "<table cols=5 border=1>\n";
print "<tr>\n";
print "<th>ACTION</th>\n";
print "<th>ALARM_TEXT</th>\n";
print "<th>ALARM_SEV</th>\n";
print "<th>EMS_NAME</th>\n";
print "</tr>";
while( my $ref = $sth->fetchrow_hashref() ) {
print "<tr>\n";
print "<td>", $ref->{'ACTION'}, "</td>\n";
print "<td>", $ref->{'ALARM_TEXT'}, "</td>\n";
print "<td>", $ref->{'ALARM_SEV'}, "</td>\n";
print "<td>", $ref->{'EMS_NAME'}, "</td>\n";
print "</tr>\n";
}
print "</table>\n";
print "<h1>Hello, world!</h1>\n";
print "</body> </html>\n";
Fixed it by adding the below line to the httdd.conf file.
SetEnv ORACLE_HOME /oracle/app/oracle/product/11.2.0.4/db_1

Failed to pass variable from one sub routine to another sub routine using perl cgi?

Here i had tried to pass variable from one sub routine to another sub routine using perl cgi.But my variable is not passing from one sub routine to another,
use strict;
use warnings;
use CGI ':standard';
print header;
print start_html("example");
print end_html;
my $file = "text.txt";
open my $fh,'<', $file or die $!;
sub1($fh);
sub2($fh);
sub sub1 {
my $fh = shift;
while ( my $line = <$fh> ) {
print $line;
}
return $fh;
}
sub sub2 {
my $line = shift;
print start_form;
print "<table>";
print "<th>content</th>";
print "<tr>";
print "<td>$line<td>";
print "</tr>";
print "</table>";
print end_form;
}
In the above sub routine (i.e sub2 $line contents are not passing from sub1)
Maybe you wanted
my $content = sub1($fh);
sub2($content);
sub sub1 {
my $fh = shift;
my $content;
while ( my $line = <$fh> ) {
print $line;
$content .= $line;
}
return $content;
}
Also file handle $fh can be close after sub1 call

Only the first result is printed in the CSV file

I am printing 110000 fileds one by one in CSV file but it is printing only the first result in the file
#!/usr/bin/perl
use strict;
use warnings;
use Switch;
use Text::CSV_XS;
use Data::Dumper;
use File::Slurp;
use LWP::Simple;
use Parallel::ForkManager;
my #links=("doba_media26.upcs");
my $pm = new Parallel::ForkManager(16);
foreach my $linkarray (#links) {
$pm->start and next; # do the fork
my $csv = Text::CSV_XS->new ({
binary => 1,
eol => "\r\n",
sep_char => "\t"
}) or die "Cannot use CSV: ".Text::CSV_XS->error_diag ();
open my $sample, ">:encoding(utf8)", $linkarray."_sample.csv"
or die "result.csv: $!";
my #lines = read_file( $linkarray );
my $numLines = #lines;
foreach my $line(#lines) {
eval {
my #tabs;
print $line;
push (#tabs,"");
push (#tabs,"");
push (#tabs,"");
push (#tabs,$line);
my #line = "\n";
$csv->print($sample,\#tabs);
}
};
if ($#) {
redo;
sleep(1200);
}
$pm->finish; # do the exit in the child process
}
$pm->wait_all_children;
The file has 11,000 results but the above code is printing only the first field in csv file?

Add headings to the a text file in perl

I have a text file with the following lines as example
This is line
This is line with test
This is ine with 2test
This is line 2
This is line 3
This is line with 3test
This is line 4
This is line with 4test
Now I want a code to change the text file as follows:
Lines with test
This is line with test
This is ine with 2test
This is line with 3test
This is line with 4test
Lines without test
This is line
This is line 2
This is line 3
This is line 4
I am using the following code. I am assuming my code would print the title with every line but I am not able to execute the code due to some errors.
Can you please help me?
#!/usr/bin/perl
use strict;
use warnings;
open(FH, '<filetest.txt');
my #queues = <FH>;
close(FH);
open(OFH,'>testfile.txt');
my $name;
foreach $name(#queues)
{
if($name =~ 'test')
{
print OFH "Lines with test\n";
print OFH $1;
}
else{
print OFH "Lines without test\n";
print OFH $1;
}
close(OFH);
}
Note: I corrected the error to remove the syntax errors but still there is nothing being written to the file testfile.txt
Have a try with:
#!/usr/bin/perl
use strict;
use warnings;
my $infile = 'filetest.txt';
my $outfile = 'testfile.txt';
# use 3-arg open and if open succeeded
open my $fh_in, '<', $infile or die "Unable to open file '$infile' for reading: $!";
my #with_test;
my #without_test;
while (<$fh_in>) {
if (/test/) {
push #with_test, $_;
} else {
push #without_test, $_;
}
}
close $fh_in;
open my $fh_out, '>', $outfile or die "Unable to open file '$outile' for writting: $!";
print $fh_out "Lines with test\n";
print $fh_out #with_test;
print $fh_out "Lines without test\n";
print $fh_out #without_test;
close $fh_out;
I haven't tested this. The idea is to write the "with test" lines to the file immediately
The "without test" lines are stored (in an array called "without") until the end of the program and then written
#!/usr/bin/perl
use strict;
use warnings;
open(FH, '<filetest.txt');
my #queues = <FH>;
close(FH);
open(OFH,'>testfile.txt');
my $name;
my #without=();
foreach $name(#queues)
{
if($name =~ 'test')
{
print OFH $name;
}
else{
push #without, $name;
}
print OFH "\n\nlines without\n";
print OFH #without;
}
also you should add a local $/ before reading the file handle.
check this out:
how to read the whole file.
the match format should be like this: if($somestr =~ /#/).
and you shouldn't close the filehandle in the loop.
#!/usr/bin/perl
use strict;
use warnings;
local $/;
open(FH, 'file#.txt');
my $s;
$s = <FH>;
close(FH);
open(FH, '>file#.txt');
my #queues = split(/\n/, $s);
my #arr;
my #arr2;
for($s=0; $s<$#queues+1; $s++)
{
if($queues[$s] =~ /#/)
{
push(#arr, $queues[$s]."\n");
}
else
{
push(#arr2, $queues[$s]."\n");
}
}
print FH "lines with #\n";
print FH #arr;
print FH "lines without #\n";
print FH #arr2;

Perl resume download from this script

I have this Perl-based download script.
I'd like to know how to make sure that when a user downloads a file with this script, can pause and resume the download (download resumable).
This is the code:
#!/usr/bin/perl
use XFSConfig;
use HCE_MD5;
use CGI::Carp qw(fatalsToBrowser);
my $code = (split('/',$ENV{REQUEST_URI}))[-2];
my $hce = HCE_MD5->new($c->{dl_key},"XFileSharingPRO");
my ($file_id,$file_code,$speed,$ip1,$ip2,$ip3,$ip4,$expire) = unpack("LA12SC4L", $hce->hce_block_decrypt(decode($code)) );
print("Content-type:text/html\n\nLink expired"),exit if time > $expire;
$speed||=500;
my $dx = sprintf("%05d",$file_id/$c->{files_per_folder});
my $ip="$ip1.$ip2.$ip3.$ip4";
$ip=~s/\.0$/.\\d+/;
$ip=~s/\.0\./.\\d+./;
$ip=~s/\.0\./.\\d+./;
$ip=~s/^0\./\\d+./;
print("Content-type:text/html\n\nNo file"),exit unless -f "$c->{upload_dir}/$dx/$file_code";
print("Content-type:text/html\n\nWrong IP"),exit if $ip && $ENV{REMOTE_ADDR}!~/^$ip/;
my $fsize = -s "$c->{upload_dir}/$dx/$file_code";
$|++;
open(my $in_fh,"$c->{upload_dir}/$dx/$file_code") || die"Can't open source file";
# unless($ENV{HTTP_ACCEPT_CHARSET}=~/utf-8/i)
# {
# $fname =~ s/([^A-Za-z0-9\-_.!~*'() ])/ uc sprintf "%%%02x",ord $1 /eg;
# $fname =~ tr/ /+/;
# }
print qq{Content-Type: application/octet-stream\n};
print qq{Content-length: $fsize\n};
#print qq{Content-Disposition: attachment; filename="$fname"\n};
print qq{Content-Disposition: attachment\n};
print qq{Content-Transfer-Encoding: binary\n\n};
$speed = int 1024*$speed/10;
my $buf;
while( read($in_fh, $buf, $speed) )
{
print $buf;
select(undef,undef,undef,0.1);
}
sub decode
{
$_ = shift;
my( $l );
tr|a-z2-7|\0-\37|;
$_=unpack('B*', $_);
s/000(.....)/$1/g;
$l=length;
$_=substr($_, 0, $l & ~7) if $l & 7;
$_=pack('B*', $_);
}
Thanks
To pause and resume downloads you should handle the http range header.
Take a look at http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35