homepage Welcome to WebmasterWorld Guest from 184.72.72.182
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
Forum Library, Charter, Moderators: coopster & jatar k & phranque

Perl Server Side CGI Scripting Forum

    
Web page stalls on "print 'Location:mydomain\n\n'"
Works fine on "print 'Location:example.com\n\n"
MichaelBluejay




msg:4539372
 9:27 pm on Jan 25, 2013 (gmt 0)

This works fine:
#! /usr/bin/perl
print "Location:http://
example.com/\n\n";
close(STDOUT); close(STDIN); close(STDERR);
[some long process]

But the following way stalls the browser, refusing to redirect until the long process is finished:
#! /usr/bin/perl
print "Location:http://
mydomain/\n\n";
close(STDOUT); close(STDIN); close(STDERR);
[some long process]

Yes, I'm using the ".com" after "mydomain", I just didn't want to get spanked by a mod putting a non- example.com in my post.

What the hell?

 

Brett_Tabke




msg:4539375
 9:46 pm on Jan 25, 2013 (gmt 0)

hmmm

try a non buffered output
$ pipe = 1



are you using gzip? mod deflate?


you could fork a new process too

g1smd




msg:4539381
 10:01 pm on Jan 25, 2013 (gmt 0)

Needs a space after Location:

That likely won't solve your problem though.

How do you set 301 status, or are you wanting the default 302?

MichaelBluejay




msg:4539423
 4:15 am on Jan 26, 2013 (gmt 0)

Thanks for the suggestions!

Adding a space after Location: didn't help.

I'd never heard of non-buffering, but I looked it up and added
$ (pipe character) = 1; before the print command, after the print command, and before [some long process], but it didn't help.

I'd have no idea how to use gzip or mod deflate (whatever that is). Um, am I supposed to try those to see if they help, or could they have caused the problem had I been using them?

I don't know how to fork a process, but it scares me, and it seems quite inelegant.

I don't understand the question about 301 or 302. The way my app works is, the user goes to
send.html which has a form, and the Submit button goes to send.cgi, which grabs the addresses for sending, redirects to sent.html, and then proceeds to actually mail out the newsletter...except that it's actually doing all the sending before redirecting, if I try to redirect to a page that's on the same domain as the send.cgi script.

I did some more testing and I have some more info now. I thought I'd be clever and redirect to a page on a different domain (on the same server), and have an htaccess command on that other domain simply redirect back to the target page on the original domain. Amazingly (to me), that doesn't work either: The address bar switches to the 2nd domain and then to the target page, but I still have to wait for [some long process] to finish before the target page actually loads.

Then I tried redirecting to another page *on a completely different server*, but on the same webhost. Same problem.

It works fine if I redirect to anywhere else, like example.com, Google, NY Times, eBay, Amazon, etc. Only when I print Location: to a page on my same webhost do I have the problem. I guess I have to take it up with my webhost?

MichaelBluejay




msg:4539515
 3:55 pm on Jan 26, 2013 (gmt 0)

Okay, it still doesn't work, but I made a mistake in my testing. It *does* work fine if I "print Location" to any other domain, even if the target domain is on the same server. What *doesn't* fix the problem is doing a "print Location" to another domain with an htaccess/Redirect back to the original domain, even if the target domain is on another server.

I tried doing a "print Location" to a .cgi file on another domain, that does a "print Location" right back to a page on the target domain, but that doesn't work either -- the browser still stalls.

I know the server isn't tied up because while [some long process] is executing, I can still load pages from that domain the script is on in another browser window.

What gives?

g1smd




msg:4539522
 4:44 pm on Jan 26, 2013 (gmt 0)

Are there any clues using the Live HTTP Headers extension for Firefox?

lucy24




msg:4539556
 9:08 pm on Jan 26, 2013 (gmt 0)

I tried doing a "print Location" to a .cgi file on another domain, that does a "print Location" right back to a page on the target domain, but that doesn't work either -- the browser still stalls.

I know the server isn't tied up because while [some long process] is executing, I can still load pages from that domain the script is on in another browser window.


Maybe it's time to take a closer look at that [some long process]. You've been pretty coy about it so far. Somehow that [long process] has made itself a precondition for fulfilling the page request, when it should be doing its thing independently in the background. And the only reason you've noticed is that this time it happens to be a [long process]; if it were a [swift process] it could be doing exactly the same thing, only you wouldn't notice because it zips by too fast.

:: scurrying off to some other forum where I might conceivably know what I'm talking about ::

MichaelBluejay




msg:4539686
 11:40 pm on Jan 27, 2013 (gmt 0)

The particular long process doesn't matter, as any long process will cause the same behavior. In my original script, it was sending out an email newsletter to ~600 subscribers, with a 5-second delay between each send. In my testing, I'm simply using "sleep 5;" or "sleep 10;". The idea is, of course, that I don't want to make the user wait while the script is doing its thing. I want to redirect the user to another page and then let the script continue.

I installed the Live HTTP Headers but I'm not sure what to make of the output.
http://example.com/test3.cgi

GET /test3.cgi HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive

HTTP/1.1 302 Found
Date: Sun, 27 Jan 2013 23:31:49 GMT
Server: Apache
Location: http://example.com/
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 187
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1

Then after it deigns to redirect:
http://example.com/

GET / HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive

HTTP/1.1 200 OK
Date: Sun, 27 Jan 2013 23:31:54 GMT
Server: Apache
Accept-Ranges: bytes
X-Mod-Pagespeed: 0.10.21.2-1381
Vary: Accept-Encoding
Content-Encoding: gzip
MS-Author-Via: DAV
Cache-Control: max-age=0, no-cache
Content-Length: 12189
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
Content-Type: text/html

MichaelBluejay




msg:4541648
 3:01 am on Feb 2, 2013 (gmt 0)

My webhost had no ideas. (They suggested it might be a MySQL problem, go figure.) So I'm at a dead-end for now...unless anyone understands what the headers I posted mean....

MichaelBluejay




msg:4542073
 7:10 pm on Feb 3, 2013 (gmt 0)

I looked up how to do forking and tried it, and now the redirect happens right away, but the forked code doesn't get executed (i.e., the file doesn't get created).

#! /usr/bin/perl

if ($pid = fork) { }
else {
close STDOUT();
open(FILE,'>test.txt');
print FILE time;
close(FILE);
exit(0);
}
print "Location: http://mydomain.com/\n\n";

MichaelBluejay




msg:4542409
 1:59 am on Feb 5, 2013 (gmt 0)

Okay, I can get my fork code to work by changing STDOUT() to (STDOUT). (Whoops.)

But I'm still wondering if there's an easier way to be able to redirect and keep processing without having to fork a new process...

Brett_Tabke




msg:4550459
 3:31 pm on Mar 2, 2013 (gmt 0)

I just tried this on my windows box and linux boxes and it always waits for the process to complete.

I think part of the issue is you maybe running an apache wrapper or other exec_cgi like module. These are pretty common among webhosts and panels. They limit things like forking processes and buffered output doesn't act as expected. (I've not dug to far into these as I have not had an issue).

Instead of 'long process' or even forking a process, I would use cron to process it. Write your 'long process' params to a file and have a cron job that runs every few minutes check for it and process it. (which is how email notifications are handled here)

MichaelBluejay




msg:4551253
 5:50 am on Mar 5, 2013 (gmt 0)

Thank you for testing this and then reporting back, Brett. That's a good idea about setting a flag and then letting a cron job pick it up. But I've already coded the fork, and it seems to be working, so I'm inclined to keep it as it is for now.

I still wonder why Perl won't redirect and *then* keep processing. I presume I could redirect and then keep processing if I coded it in PHP instead of Perl....

coopster




msg:4552098
 2:08 pm on Mar 7, 2013 (gmt 0)

I don't think that's it, MBJ. I code in both languages and I would be very surprised if one handled the fork process different than the other. Unless the wrapper was different or non-existent for one or the other on your server.

I have also attempted using header() for redirection with PHP and no exit() with unexpected results. I wish I could remember details right now and I realize without proof this advice may be worthless but I can truly testify from experience that I program all my redirection with an immediate exit() and have been doing so for years now. FWIW.

Brett_Tabke




msg:4552103
 2:22 pm on Mar 7, 2013 (gmt 0)

> why Perl won't redirect and *then* keep processing

I don't think it is PERL that is the issue. Something is waiting for the process to stop before Apache flushes the output buffer.

phranque




msg:4552139
 2:41 pm on Mar 7, 2013 (gmt 0)

it may be the behavior of the specific handler that is processing the cgi script that is buffering.

it may also be caused by another apache module in process.
for example if you are using mod_deflate, perhaps that module is buffering the output of the cgi module.

you might try disabling the data compression if that is enabled, or perhaps try another method of handling the perl script.

MichaelBluejay




msg:4553216
 11:29 pm on Mar 10, 2013 (gmt 0)

I found mod_deflate in my host's httpd.conf file for my site. I commented it out and restarted, but I had the same problem.

It's really weird that it works fine for external sites, but not for internal ones.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved