Discuss Redirection after other output in the Perl Programming forum on Dev Shed. Redirection after other output Perl Programming forum discussing coding in Perl, utilizing Perl modules, and other Perl-related topics. Perl, the Practical Extraction and Reporting Language, is the choice for many for parsing textual information.
The ASP Free website provides in-depth information on the latest developer tools available from Microsoft. Our cadre of writers, highly experienced industry experts, reveals the best ways to use established technologies as well as new and emerging technologies. Our coverage of Microsoft's development and administration technologies is among the most respected in the IT industry today.
ASP Free and Iron Speed Designer are giving away $5,500+ in FREE licenses. Iron Speed's RAD CASE toolset can save up to 80% of your coding time. One free license per week, one perpetual license per month! Download and Activate to enter!
Intel® Graphics Performance Analyzers is a powerful tool suite for analyzing and optimizing your games, media, and graphics-intensive applications. Used by some of the best developers on the planet, Intel GPA lets you maximize your app’s performance.
Posts: 44
Time spent in forums: 15 h 48 m
Reputation Power: 9
Redirection after other output
The effect I am trying to achieve is something similar to the following. Print a header (HTML header, like doctype, title, and other constants), and then print a form. If the person fails at entering the proper data into said form, redirect them somewhere. If they do right, redirect them somewhere else.
Now, before we continue, this redirection should not use a form action. I know that in PHP I could do something very easily with code like:
PHP Code:
function redirect($page){ header("Location: $page"); }
And I could call this anywhere on the page, assuming I had output bufferring enabled.
Now, in Perl, I cannot find anything that can do this, at all. No modules, no functions--nothing.
But as you can tell, compared to the PHP example which can work anywhere, this method, which can only work if there is absolutely nothing else output at all, is very very limited, and comparatively useless.
If this is impossible in Perl, that just doesn't make any sense at all to me; if anyone knows and this is the case, care to explain why, exactly?
Thanks for any help again, guys.
Yes, I searched. Couldn't find anything fully relevant.
Posts: 55
Time spent in forums: 23 h 39 m 8 sec
Reputation Power: 7
I suppose I should also point out, &SwapBuffer; must be called before any output is sent, and &ResumeBuffer; can be called any time after MyRedirect();, either immediately after or just before the script exits. I'd imagine the sooner the better though, especially if the page is large, as the more information that gets sent to the custom buffer, the more information needs to be re-read and sent back to the original buffer.
Posts: 1,302
Time spent in forums: 5 Days 34 m 49 sec
Reputation Power: 362
@Duminas:
That's because you need to print a header (Content-type: text/html\n\n) from Perl script - so ussualy scripts that you can find everywhere do that as first thing Unless you do that Web server ussualy complains ...
Anyway, when you get to the point where you will use some templating (such as HTML::Template), some module for validating form input (such as Data::FormValidator) and maybe even some framework (such as CGI::Application) you will forget about those little things and conentrate on the problem itself.
@Tedward:
That is the craziest solution I have ever seen I mean ok - with Perl TMTOWTDI. But I would never even think of something like that. Somehow to me it's quite logical thinking :
1. Get form data
2. Validate it
3. If OK print header and whatever
3. If NOT OK print redirection header
Eitherway, both your and mine solutions are not how it's done in real world. Data::FormValidator gives you nice output to be combined with HTML::Template so you print out the same form, but add error messages next to fields that have errors.
Of course, you use something like HTML::FillInForm to "fill" the input back to the form before you return it back.
missing => 'Please enter this field. It is required.',
invalid => 'Please enter this field in right format'}
});
}
__________________
www.booking.com is hiring Perl developers!
Work along some of the biggest names in Perl community. Live in Amsterdam - relocation assistance is provided (paperwork/visa and financial) for you and your family members - for details send me an message
Posts: 131
Time spent in forums: 22 h 27 m 27 sec
Reputation Power: 8
Tedward's solution is horrible!
You generate a random filename and don't even check whether it already exists before stomping on it. You don't check whether the open() call succeeds.
This isn't a deficiency in perl, it's a bad design practice that php perpetuates.
The real error is that you're sending out a content-type header before you know whether you really should be. As techcode rightly suggests, check your input, then you can decide what type of header to send.
Posts: 55
Time spent in forums: 23 h 39 m 8 sec
Reputation Power: 7
"You generate a random filename and don't even check whether it already exists before stomping on it. You don't check whether the open() call succeeds."
Considering the size of the random number, and considering the amount of time the file will be in existance, it's pretty safe to assume. You are right however, that you should check for that kind of thing. However, he didnt ask how to open files, he asked how to send a different type of header. I left it up to him to add any little checks he wants done.
"The real error is that you're sending out a content-type header before you know whether you really should be."
Say you're writing an addon to a forum. Say, you need to check to make sure the person is logged in before you can proceed to figure out what header to send. What if the only way to check to see if theyre logged in is to include the main forum files. What if those send output automatically? That's quite common, and you don't always have the option of killing it. In cases like that, you need to be able to modify what's already been sent. Quite simple, with my script. Just swap the buffer before calling the forum script, then call it, and figure out what needs to be done.
It may not be the best way to do things, but in some cases, it may be the only practical way.
ps. you forgot to complain that I didnt use -w and my()
Posts: 44
Time spent in forums: 15 h 48 m
Reputation Power: 9
@fireartist:
I'm really bad at math, but I know for certain that the chance of having a filename collision with 25 numbers generating the filename is minute; and as this is something I intend to use in a small capacity (about 1200 people plowing through it over the course of a couple hours), there is no real need for anything else.
Also, I used the form as an example. Sometimes I will not have a form to be checking. Should have clarified that prior, but don't be so quick to assume it'll be done one, and only one way.
"Bad design practice?" Care to explain that?
@techcode:
Thanks. I'll look into those modules (I'm trying to keep it as module-free as I can at this point, since it will run on various servers that might not have all these modules installed, or the capability to install them). And I already use HTML::Template--guess I better get used to the FormValidator~
And then only call ResumeBuffer() if you don't actually redirect. Example:
perl Code:
Original
- perl Code
if($wantToRedirect){
MyRedirect("http://www.google.ca");
}else{
&ResumeBuffer;
}
Now I'm not actually positive if Perl will bother sending any output after a redirect header, or if it does, if browsers will wait around to see it after it's gotten the redirect header, but these changes should help prevent that either way. It will also save a few milliseconds taken to re-read and print the buffer if it isn't actually needed.
Posts: 1,302
Time spent in forums: 5 Days 34 m 49 sec
Reputation Power: 362
Quote:
Thanks. I'll look into those modules (I'm trying to keep it as module-free as I can at this point, since it will run on various servers that might not have all these modules installed, or the capability to install them). And I already use HTML::Template--guess I better get used to the FormValidator~
All modules that I wrote are pure Perl - which means I just copy them to the server I'm installing my application to - and it works That's what I like most about it.
Quote:
"Bad design practice?" Care to explain that?
I care. The whole idea behing PHP is bad because it untill recently forced you to mix php and html code. And when you start writing a bit more complex applications you will see yourself why that is not the happiest solution. Especialy if there is another person included that will do design.
Of course PHP folks realised the problems (as many others did) so they came up with templating.
Also, I believe mysql functions are built-in inside php, that's another bad thing. I also saw people saying they dont want to use PEAR because it starts to look like CPAN - like that's a bad thing :?:
Don't know what _fireartist_ tougth about it - would also like to hear.
Posts: 131
Time spent in forums: 22 h 27 m 27 sec
Reputation Power: 8
I agree with techcode.
A "good design practice" for a program that allows plugins, would have different hooks for different stages of the server response.
Each plugin would register itself for different hooks.
So, if a plugin may need to send a redirect header, it would register with a hook that would be called very early on, before normal headers are sent.
Bad design practice?
A buffer is intended to allow data to be sent across the network in optimal sized chunks. In just the same way a harddrive buffer allows the physical disk to write a lot of data at the same time, rather than staying busy making lots of short writes.
A buffer shouldn't be able to be undone.
Also, regarding random filenames, I think it's a lot easier to say
Code:
use Temp::File;
my $fh = Temp::File->new;
Quote: "return name and handle of a temporary file safely" docs
Posts: 55
Time spent in forums: 23 h 39 m 8 sec
Reputation Power: 7
"A buffer is intended to allow data to be sent across the network in optimal sized chunks. In just the same way a harddrive buffer allows the physical disk to write a lot of data at the same time, rather than staying busy making lots of short writes.
A buffer shouldn't be able to be undone."
Unless you tell your script to send all output as it happens ($|++, it isnt sent until the entire script is finished. So, when you modify the buffer, it shouldnt have any negative side effects, as when the entire script finishes it should still break down the buffer to these optimal sized chunks, modified or not.
And for your random file idea above, I agree with that if it works. As I said earlier though, my code wasnt an example on how to open a file, it was an example on how to change your headers
Posts: 44
Time spent in forums: 15 h 48 m
Reputation Power: 9
Quote:
I care. The whole idea behing PHP is bad because it untill recently forced you to mix php and html code. And when you start writing a bit more complex applications you will see yourself why that is not the happiest solution. Especialy if there is another person included that will do design.
That designer reference is exactly why I almost immediately started Perl with HTML::Template. The other way I was considering (which is how I did it in PHP) is with a heredoc, and that is... not pleasant, to say the least (my syntax highlighting also goes wonky if I have HTML embedded in PHP/Perl files).
And I still don't quite get why sending redirect headers like this seems to be so frowned upon (fireartist's comments seem to portray this), but I digress.
Oh, and script execution timing breaks if I use Ted's solution under mod_perl, but whatever. Works fine otherwise.
That's all there is to it. Read the CGI docs for more information on redirection headers. And remember, don't print any HTTP headers if you intend to do redirects.
As techcode mentioned, if you use a framework such as CGI::Application, then there's no need to think about how to do redirections - it is all taken care of by the application module. It works seamlessly with most templating packages such as HTML::Template and can be used for simple or advanced projects.
Posts: 55
Time spent in forums: 23 h 39 m 8 sec
Reputation Power: 7
Even using CGI.PM (which doesnt really make redirection any easier, unless you don't know what you're doing...), I highly doubt you can send the redirect command after other headers have been sent.
Posts: 1,573
Time spent in forums: 1 Week 1 Day 12 h 23 m 56 sec
Reputation Power: 46
Quote:
Originally Posted by Tedward
Even using CGI.PM (which doesnt really make redirection any easier, unless you don't know what you're doing...), I highly doubt you can send the redirect command after other headers have been sent.
Maybe I'm missing something that seems so important to some - why would you want to print a HTTP header, then do a redirect?
If you're talking about META redirection, then do it in HTML.