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

Wise monks,

I seek enlightment with the following question:
I want to redirect users from a webpage on my server to a webpage on an external server.
The webpage I am redirecting to is this one:

Molsurfer

I'd like to execute the script form on this webpage with data that is provided from my website (2 PQR files).
The user should then see the results from the MolSurfer webpage (Java applet).
Is this possible in Perl?
I am a newbie regarding CGI and web programming, please be easy on me.
I did some experiments with Mechanize:

#!/usr/bin/perl use warnings; use strict; use Data::Dumper; use WWW::Mechanize; my $m = WWW::Mechanize->new(); my $url = 'http://projects.villa-bosch.de/dbase/molsurfer/submit-elec. +html'; $m->get($url); #$m->form_name('f'); $m->set_fields( FILE1 =>'12E8_L.pqr', FILE2 =>'12E8_M.pqr', mapsize =>'59x59', resolution =>'med', pdie =>'4', sdie =>'80', ioss =>'150', ionr =>'1.5', nmap =>'0.0' ); my $response = $m->submit();

From this point I am clueless.
I am thankful for every suggestion.
Many thanks,
Thomas

Replies are listed 'Best First'.
Re: redirecting, html forms, mechanize
by Marshall (Canon) on Jun 27, 2009 at 05:31 UTC
    Here is just an example of how to do that.
    #!/usr/bin/perl -w use CGI qw(:standard); # No spaces below around URL=value!!! # Posts the message in p() and then goes to cgi30.cgi within 5 secs. print header(-refresh => '5; URL=./cgi30.cgi'), start_html, p("This site has moved. You will be transferred to the new URL! +\n"); end_html;
Re: redirecting, html forms, mechanize
by Your Mother (Archbishop) on Jun 27, 2009 at 19:01 UTC

    If I understand correctly you want to redirect a POST request as a POST to the other site. This is possible (well, most of it is; I'm not entirely sure about the file fields) but it can be a pain. The last time I did this was about 4 years ago and the different browsers (Safari at least; which IIRC was the only one which followed the HTTP spec strictly) handled this differently.

    I'd actually love to help you but it's been long enough that I'd have to do an hour or two of digging and I've got other fish to fry right now. I just wanted you to know that it is possible. But as the kittehs says: yur doin it rong.

    You'll need to construct a POST request. Perhaps with HTTP::Request::Common, perhaps there is a way to tease the request out of WWW::Mechanize but you do not want to $mech->submit the request, you want to use its body in a redirected POST which ends up submitted by your user. The file upload fields are the tricky part and you should verify with some object dumps that they are getting loaded into the POST as complete multi-part data. I recommend using a couple of *small* test files like test.txt and test.gif to eyeball. A big gene file or something is going to make visually inspecting the POST a drag.

    User -> GET something from your CGI Your CGI -> Construct POST body that Molsurfer accepts -> Give User a POST redirect with the POST body -> Redirect status should be 303, I think (or maybe 302; test on different browsers)
      It was finally not that difficult, in case you encounter something similar:
      You only need to add the requesting IP as _location to the http header.
      Thanks!
      #!/usr/bin/perl use warnings; use strict; use Data::Dumper; use WWW::Mechanize; use CGI qw/:standard/; use CGI::Carp qw(warningsToBrowser fatalsToBrowser); my $q = new CGI; my $addr = $ENV{'REMOTE_ADDR'}; my $m = WWW::Mechanize->new(); my $url = 'http://projects.villa-bosch.de/dbase/molsurfer/submit-elec. +html'; $m->get($url); $m->add_header(location => $addr); $m->set_fields( FILE1 => $file1, FILE2 => $file2, mapsize =>'59x59', resolution =>'med', pdie =>'4', sdie =>'80', ioss =>'150', ionr =>'1.5', nmap =>'0.0' ); my $response = $m->submit(); print $q->header; print $response->content();

        Nice! Thanks much for updating with the solution.

      Thanks for your reply and your pointers. I will first try the idea that Beth had, your experience with the different browsers make me too nervous. ;)
Re: redirecting, html forms, mechanize
by ELISHEVA (Prior) on Jun 27, 2009 at 19:19 UTC

    Just out of curiosity - why aren't you using mod_rewrite for this? If you are using an Apache server (maybe you are not?), you can handle simple static redirections like the above directly in the server. Perl scripts are really only needed if you are dynamically selecting the redirection location or munging the post parameters before you redirect.

    Best, beth

      Dear Beth,

      thanks for your answer.
      I am not really a web-programmer or webmaster. I am just at the beginning to learn all the things Apache can do. I read a bit about the mod_rewrite, using it seems like a good idea. This task has been assigned pretty much last minute to me, is there a chance that you could give me some hints how to transfer files using mod_rewrite?

      Many thanks,
      Thomas

        Unfortunately, I can't give more than general help and learning tips. I'm only a casual user of mod_rewrite and don't have an experimental Apache server handy.

        On one foot, mod_rewrite lets you use Perl compatible regular expressions to convert a part of a URL you don't like to one you do like. The phrase "Perl compatible" should be taken with a small grain of salt - usually it means some subset of full-blown Perl regexes. I've never really done much more than simple rewrites, so I don't really know how full the emulation is (perhaps some other monk does?).

        The hardest part of mod_rewrite is learning its syntax for selecting URLs to be rewritten. In my experience, when mod_rewrite "doesn't work", it is usually a screw up with the selection process: thinking selection criteria are being or'd when they are really being and'd; regexes that don't do what you think they do; accidentally chaining together rules, and so on.

        Basically, you define a set of rules for selecting a URL using a series of RewriteCond statements. Each of these has three parts: the word "RewriteCond", a variable representing the thing you want to match (e.g. %{REMOTE_HOST}), and a regex to compare to it. These are the equivalent of $servervar =~ /.../ expressions in Perl.

        A series of these RewriteCond statements is normally and'd together but you can "or" them, by adding [OR] at the end of each RewriteCond statement. At the end of all of the RewriteCond statements, is a RewriteRule statement. This contains the URL transformation and has the format:

        RewriteRule regex-matching-what-you-want-to-get-rid-of text-you-actually-want.

        You can think of it as a fancy version of Perl substitution: s/regex-matching-what-you-want-to-get-rid-of/text-you-actually-want. So your redirection to MolSurfer might look something like this:

        RewriteCond %{REMOTE_HOST} ^host1.* [OR] RewriteCond %{REMOTE_HOST} ^host2.* [OR] RewriteCond %{REMOTE_HOST} ^host3.* RewriteRule regex replacement-for-regex [R,L]

        The things in square brackets at the end are instructions to the server. [OR] was already discussed above. L means "the end". If it is missing, and there is another set of RewriteCond/RewriteRule statements after it, Apache chains them, just as if you had successive $foo =~ s/blah/blech/ statements in a Perl script. [NC] means ignore case. See the documentation for other codes.

        The official documentation is very far from a tutorial, so here are some articles with examples. These should get you started. After reading them, you may want to go back to the mod_rewrite reference page and see if anything there starts making more sense.

        You might also try searching the net for Apache forums - you are likely to get more detailed help there.

        There is also a way you can insert a Perl script to do the URL conversion if you need to get a bit fancier with the conversion or use something like a lookup table stored in a database, but that is a lot more complex than you probabably need right now. If you are interested in it later on, scan the main mod_rewrite documentation page for the word "Perl". They have a short sample script.

        Best, beth