http://www.perlmonks.org?node_id=785543

socrtwo has asked for the wisdom of the Perl Monks concerning the following question:

Hi. Sorry for the confusing English...,

My father is a stamp dealer for French or Chinese stamps. I am trying to create a stamp ID Web service using ImgSeek, where a user can upload an image of a French or Chinese stamp and then get back 10 or so images from a collection of 3,250 scanned images that are most similar in color and image shape. The image names are attached to the images and since the image names contain the Scott Catalog Number, the stamp can be possibly identified.

I realize there are copyright issues with the Scott Catalog's publisher, an issue which I would rather not discuss here. I'm using this only as test case. I'm wishing to create a broader uploaded image ID system for release as open source after later switching to an open source uploader and adding a GIF, JPEG and PNG to BMP converter module.

I have presently modified a commercial freeware CGI uploader script from perlservices. I have added code from a Japanese site here, that catalogs each uploaded BMP image using the Perl Module wrapper of ImgSeek, Image::Seek.

The cataloging works pretty well seemingly easily detecting if I have already uploaded a BMP image, and not adding it to the imgname and imgseek databases specified in the code named "makedb.pl" on the Japanese site.

On that site there is also a CGI script called "seek.cgi" which will return the images most similar to the one whose database number key is added either to the form with it's naked URL or added to the returned results CGI page, where the form exists again for further entry.

Since the 'makedb.pl' code returns the newly uploaded image's newly created imgname.db and imgseek.db number keys, with regular expressions, I'm able to isolate the new key and construct the URL of the seek.cgi query which I would like to make, which is that of the newly uploaded image. For instance: http://www.godskingsandheroes.info/stamps/seek.cgi?id=2352.

So, here's the rub, I can get my uploader CGI results to print my constructed URL for the uploaded image, but I can't the browser to redirect to the new page. I have tried to put this code from the Perl Cookbook in the header section of the upload script:

$url = "$From-a-Transform-of-the-Makedb.pl-Results"; print "Location: $url\n\n"; exit;

I have Jail Shell access, and was able to check that the makedb.pl was not running through successfully when the header was executing, suggesting that the file had not uploaded yet when the header was writing...I guess. This was true, even if I made my makedb.pl script sleep. So here is that code:

`perl makedb.pl > testout.txt`; sleep 1 while ( !(-e "testout.txt") ); use File::Copy; copy("testout.txt", "testout2.txt") or die "File cannot be copied."; $file = "testout.txt"; unlink($file); { local $/=undef; open FILE, "testout2.txt" or die "Couldn't open file: $!"; binmode FILE; $content = <FILE>; close FILE; } # URL that generated this code: # http://txt2re.com/index.php3?s=[3418]./img10_small.bmp&7 $txt=$content; $re1='.*?'; # Non-greedy match on filler $re2='(\\d+)'; # Integer Number 1 $re=$re1.$re2; if ($txt =~ m/$re/is) { $int1=$1; print "http://www.godskingsandheroes.info/stamps/seek.cgi?id=$int1 +"; } #----- # Paste the code into a new perl file. Then in Unix: # $ perl x.pl #-----

I also tried putting this first method from the Cookbook, after everything but the footer printed. Then I tried redirecting from inside the footer too. None of these methods would execute a redirection.

So I tried the second Perl Cookbook method:

my $url = $From-a-Transform-of-the-Makedb.pl-Results; # See the code j +ust above print redirect( -URL => $url);

I tried this code too, in the header, in the middle of the script and in the footer...no redirection. In the footer I tried putting the statement before printing </body>, and I also tried putting it after printing just </body>

print qq~</body>~; blahblahcode; print qq~</html>~;

From my cPanel X account, I also tried installing and then using CGI::Application::Plugin::Redirect;, with this code

sub PrintHead { print qq~Content-type: text/html\n\n~; BEGIN { my $homedir = ( getpwuid($>) )[7]; my @user_include; foreach my $path (@INC) { if ( -d $homedir . '/perl' . $path ) { push @user_include, $homedir . '/perl' . $path; } } unshift @INC, @user_include; } use CGI::Application::Plugin::Redirect; sub byebye { my $self = shift; return $self->redirect("http://www.godskingsandheroes.info/stamps +/seek.cgi?id=2225", '301 Moved Permanently'); # Just trying to get an + example working... } print qq~ <html> <title>PerlServices.net Free upload utility</title> <body bgcolor="#ffffff"> ~; }

Nothing happens from the header, my results page is returned per normal (from my last project). cPanel makes you put in the 'include' code that's at the beginning if that is confusing you. It allows the module work. I tested the module with Jail Shell to make sure it was not producing an error and it did not return an error.

I tried several permutations not mentioned here, also without success. Why is it so difficult to get a redirection?

Replies are listed 'Best First'.
Re: Can't Get CGI Results Page to Redirect
by thezip (Vicar) on Aug 03, 2009 at 20:30 UTC
    socrtwo, it's difficult to follow your node because you have included too many extraneous details. I think you'll have much more specific success if you reduce the sheer amount detail in your node.

    With that said, I'll offer up a couple of general comments which may or may not be of help, pending further explanations on your part:
    1. You only get one shot at printing a CGI header. Thus, if you've already printed out one header, it is impossible to get a redirect to work.
    2. Have you tried hardcoding a URL to see if that will redirect?

    What can be asserted without proof can be dismissed without proof. - Christopher Hitchens
      Thanks for your response. Sorry about the detail. I will go lighter I hope as I learn more Perl... Anyway, if you only get one shot at the header, should I write the redirect before the first line in the default header?
      print qq~Content-type: text/html\n\n~;?
      Yeah I hard coded the redirection and no redirecting occurred.
        Just don't print the header until you're ready to either print the page -or- generate a redirect.

        A technique you can use to defer printing the header is to build up your HTML output into a string, and then do:

        #!/usr/bin/perl use strict; use warnings; use CGI qw/:standard/; my $q = CGI->new(); my $do_redirect = 1; # for example only # ... build the entire output into a string $str = "This is your concatenated HTML doc"; if ($do_redirect) { print redirect($url); } else { print $q->header(), $str; }
        The idea is to wait until the absolute last second to print either header.

        What can be asserted without proof can be dismissed without proof. - Christopher Hitchens