Gossamer Forum
Home : Products : Gossamer Links : Discussions :

reading STDIN buffer not working

Quote Reply
reading STDIN buffer not working
Hi there,

I am trying to get the order of fields as they were passed in via another page.
I'm trying the following at the top of my cgi-script:

if ($ENV{'REQUEST_METHOD'} eq 'GET') {
@pairs = split(/&/,$ENV{'QUERY_STRING'});
}
elsif ($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/,$buffer);
}

The GET method, gives me pairs I can use, but the following doesn't return any pairs.
elsif ($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
}


Anyone have any ideas why @pairs is blank when data is being sent in via POST

I'm running Links 2.1.0 and the method works with other scripts on this server.

Thanks in advance for any ideas.

peace.

klangan
Quote Reply
Re: [klangan] reading STDIN buffer not working In reply to
Noooo you don't want to use that code, it's out-dated :)

$IN is a cgi object all ready for you to use.

my $input = $IN->get_hash;

All your input regardless of the request method is then stored in the $input hashref.

Last edited by:

Paul: May 13, 2003, 2:05 PM
Quote Reply
Re: [Paul] reading STDIN buffer not working In reply to
aaaggh, thanks for your quick reply, you answer is exactly what I was afraid of.

Is there anyway to get the order of the fields as they were passed in?

my $rec = $IN->get_hash; does not return the fields in the order they were submitted from on the calling page, and that's exactly what I need.

(Matt's script archive formmail does this, so I know it can be done by reading Content_Length into a buffer, but if that is not available to us, than how would we do that?)

any ideas?

peace.

klangan
Quote Reply
Re: [klangan] reading STDIN buffer not working In reply to
Not really any of my business but just to get a feel for what's going on could I ask why you need it in order?
Quote Reply
Re: [Paul] reading STDIN buffer not working In reply to
HI Paul,

You know how in formmail you can issue an email with the contents listed in the order that they were submitted from by the calling page? as in Matt's Script Archive Formmail.pl

That's exactly what I'm trying to do. I'm working on a project that uses LinksSQl to send mail instead of Formmail.pl as then I can off the user of opting into my MailingList. The only thing I have to work out is the order of the fields that get sent via the email.

I've found a couple of work arounds for it like passing in the order, but that's such a pain on long forms, I'm praying there's an easier way.

Hope that makes sense and sparks a few ideas

thanks again for responding so quickly.

peace.

klangan
Quote Reply
Re: [klangan] reading STDIN buffer not working In reply to
Hmm the code you have for reading POSTed variables looks like it should work. Inside that elsif block trying printing $buffer to see what it contains.
Quote Reply
Re: [Paul] reading STDIN buffer not working In reply to
Paul,

I had checked that and $buffer is blank. I have no idea why.
GT seems to read from it in GT::CGI->load_data;

I looked at the environment for the incoming data and got this:
CONTENT_LENGTH => 271
CONTENT_TYPE => application/x-www-form-urlencoded
Does the CONTENT_TYPE change how the the pairs get pulled out?

peace and thank you for sticking with me on this.

Klangan
Quote Reply
Re: [klangan] reading STDIN buffer not working In reply to
GT use pretty much the same code as you have...

Code:
read(STDIN, my $data, $content_length, 0);

I can't see why $buffer would be empty :(
Quote Reply
Re: [Paul] reading STDIN buffer not working In reply to
Yeah,

I also tried GT's exact same code as well.

wierd huh, it must have something to do with using CGI to read in the data to begin with.

thanks for your efforts.

peace.

klangan
Quote Reply
Re: [klangan] reading STDIN buffer not working In reply to
How about using sysread?

Best regards,
Webmaster33


Paid Support
from Webmaster33. Expert in Perl programming & Gossamer Threads applications. (click here for prices)
Webmaster33's products (upd.2004.09.26) | Private message | Contact me | Was my post helpful? Donate my help...
Quote Reply
Re: [webmaster33] reading STDIN buffer not working In reply to
That was a good idea to, but I found the problem.
What I found was that I can read from the STDIN

Before this happens:
Links::init('/usr/web/santafe.org/html/cgi-bin/siteman/admin');
Links::init_user();

Once Links::init happens, you can't read from STDIN any longer.

The only way then to get the order of the incoming fields is to modify GT::CGI::load_data and write the field names into a $IN variable during the read process, which I did get to work.

Anyone have any better ideas?
Quote Reply
Re: [klangan] reading STDIN buffer not working In reply to
Not sure this will help, but a solution idea.
Try:
if you use sysread:
sysseek (STDIN, 0, 0);
if you use read:
seek (STDIN, 0, 0);

But I don't see why you couldn't use GT::CGI::load_data and write into a variable, even into $IN or into your own variable.

Best regards,
Webmaster33


Paid Support
from Webmaster33. Expert in Perl programming & Gossamer Threads applications. (click here for prices)
Webmaster33's products (upd.2004.09.26) | Private message | Contact me | Was my post helpful? Donate my help...
Quote Reply
Re: [klangan] reading STDIN buffer not working In reply to
And a better solution without using seek:
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}, 0);

Doc says:
read FILEHANDLE,SCALAR,LENGTH,OFFSET

And you missed the offset, so starts from last offset. Using the example above will start from 0 offset. You even don't need seek, however using seek should also work. Cool

Best regards,
Webmaster33


Paid Support
from Webmaster33. Expert in Perl programming & Gossamer Threads applications. (click here for prices)
Webmaster33's products (upd.2004.09.26) | Private message | Contact me | Was my post helpful? Donate my help...
Quote Reply
Re: [webmaster33] reading STDIN buffer not working In reply to
Hey thanks for the advice.

I did try it with the offset and no luck. STDIN just isn't available any longer after the Links::Init routine calls GT::CGI::load_data which does the post read from STDIN.


The only way to get order of the fields is to directly modify GT::CGI::load_data (which you suggested in a previous email) and write the order of the incoming fields, extracted during that 'read' process, into my own $self->{inc_order} variable. And that does workSmile. I can then reference it as $IN->{inc_order} It'd be cool if GT could do something similar in a future release.

Thanks for everyones help.

peace.

klangan
Quote Reply
Re: [klangan] reading STDIN buffer not working In reply to
Why can't you just use the links mailer?

It sets up the required headers, and you can add anything else to them you want. Just take the passed in data, assign it to new variables, and pass it to GT::Mail

Look at Modify.pm to do it.

_that_ is how you _should_ pass off and do mailings from within Links SQL, especially if you want to maintain upwards compatibility through upgrades, etc.


PUGDOG� Enterprises, Inc.

The best way to contact me is to NOT use Email.
Please leave a PM here.
Quote Reply
Re: [pugdog] reading STDIN buffer not working In reply to
Hi Pugdog,

With some sites and their needs, and the current state of Linksql it's sometimes impossible to maintain upwards compatibility. This is one of those cases. Even if Use Links::Mailer, I still have to call Links::Init in my calling cgi program. That doesn't solve the problem. The problem is that it's impossible to do the following twice:

read (STDIN, my $data, $content_length, 0);

GT does it once in GT::CGI::load_data:
read (STDIN, my $data, $content_length, 0);
$data =~ s/\r?\n/&/g;
$self->parse_str($data);

Now that GT's done it, if I do this or anything similar $data is blank:
read (STDIN, my $data, $content_length, 0);

And visa versa is true as well. If I do the read before callings Links::Init. I can read, but then GT::CGI::load_data cannot. Interesting huh.

Anyway, I need the $data string before it's been parsed, because the GT parsing process puts everything into a hash. The original order then gets lost and there is now way to get it back.

How does Links::Mailer help overcome that? I'm just doing this when it comes time to send the email:

# Mail the validation letter.
require GT::Mail;
GT::Mail->send ( {
smtp => $CFG->{db_smtp_server},
sendmail => $CFG->{db_mail_path},
from => $Config->{email},
subject => $Config->{subject},
to => $Config->{recipient},
msg => $input->{mailloop_results}
} ) or die $GT::Mail::error;


I have 7 email forms all asking different questions so there's not really a way to standardize the incoming fields. My only hope when using post is to read in the order during the load_data process, so I can spit them back out in that same order. That just means I've got to make some teeny little changes in GT::CGI each time I upgrade. It's a pain I know, but I always hope that GT reads these and makes notes on the subtleties that are still missing in LinksSQL.

Most of the sites I've done have required the same customization of GT's code.


I always have to modify Links.pm::clean_output and user_page - for several reasons:
1. to clean javascript ouput cause it doesn't properly parse onclick=newwindow('<%URL%>').
2. to stop multiple dynamic_preserve variables from returning like d=hash(0x0860) in my urls;
3. to allow LinksSQL to preserve the variables even if d is not set (Alex thought this a good idea, I don't know if he's planning on implementing it.) The original discussion is here:
http://www.gossamer-threads.com/...earch_string;#186989

I always have to modify browser.pm so that links show up in Editor listed in the same order as they do on the site (like isValidated DESC, $CFG->{build_sort_order_category}.

I always have to change GT::Display::HTML so that radio buttons are on the left side of the value as are the checkboxes and to get checkboxes and radio buttons to list in multiple columns.

I always have to install a category plugin so that I can allow any given Category to specify it's own link order and so that I can know what category a link belongs to when I'm printing the link, as that info is not passed when building the link code. (it doesn't make sense to look it up again when it's already available.)

I keep customized versions of changed files on hand for the upgrades, so that I can just upload over the new code with my modified code. It's a pain I know, but often I'm left with no other real choice. What the client demands is what ultimately rules the decision making process.

peace.

klangan
Quote Reply
Re: [klangan] reading STDIN buffer not working In reply to
Did you try seek, too?

Also Pugdog is right. GT::Mail should do what you want.

Quote:
working on a project that uses LinksSQl to send mail instead of Formmail.pl as then I can off the user of opting into my MailingList. The only thing I have to work out is the order of the fields that get sent via the email
Once you got the user email from the unsibscribe form, you can opt out him immediately by deleting his record from database, and sending out the notification email.
What's problem with that?
Why do you need exact form order to send out an email?
Something is strange for me...

Best regards,
Webmaster33


Paid Support
from Webmaster33. Expert in Perl programming & Gossamer Threads applications. (click here for prices)
Webmaster33's products (upd.2004.09.26) | Private message | Contact me | Was my post helpful? Donate my help...
Quote Reply
Re: [klangan] reading STDIN buffer not working In reply to
Quote:
7 email forms all asking different questions so there's not really a way to standardize the incoming fields. My only hope when using post is to read in the order during the load_data process, so I can spit them back out in that same order
Still not clear why you need to have the input forms in order.

Or if you need them in order, why you can't use a serial number in the input fields?
<input type=text name="1_formname" value="">
<input type=text name="2_formname" value="">
etc...

Or you you need just in order of pages, then put the page number there, so you can sort them later...

Best regards,
Webmaster33


Paid Support
from Webmaster33. Expert in Perl programming & Gossamer Threads applications. (click here for prices)
Webmaster33's products (upd.2004.09.26) | Private message | Contact me | Was my post helpful? Donate my help...
Quote Reply
Re: [webmaster33] reading STDIN buffer not working In reply to
I haven't tried seek yet, but as it's reading from STDIN, I'll bet it's already empty.

Anyway, the reason I need them in the order they're submitted is that the formmail contents get entered into an offnetwork database in the same order via cut and paste - yup, legacy crap. It's how the form was built to begin with and since it worked with formmail.pl, I've got to make it work here as well, otherwise I'll have to spend a bunch more time recoding html forms as you suggested - blechhhh. The goal is to be able to repoint which formmail I call, and be done with it. Happily I've accomplished that goal with a simple change in one spot. Now I have access to it everywhere else without having to seek or read.

What I must say is interesting here is that while they're may be a workaround for what I need, that's exactly what it is, a work around. Work arounds always require extra work to begin with and then to watch out for later. The best solution for my problem is to make the change in the code where it counts. And while making the changes in GT::CGI::load_data is not the preferably place to make the changes solely because of upgrading, it is nonetheless the best and most elegant place to make the change. It kills 7+ chores with 1 minor change, and gives me back what little functionality I otherwise lose with LinksSQL.

Thanks again for your thoughts, I'll give seek a try when I have a chance.

peace.

klangan