Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

avoiding premature end of script header when NO reply to IE desired

Status
Not open for further replies.

NewtownGuy

Technical User
Joined
Jul 27, 2007
Messages
146
Location
US
I'm a newbie so please forgive this simple question.

I'm trying to launch a perl script on an Apache/2.0.49 HTTP server on Fedora Core 2 or a similar version on Fedora Core 3. I want the script to output the data that is sent to it by the web browser out the COM / ttyS0 port on the machine that is running the HTTP server. I do not want any message printed on IE.

I get the error message:

...premature end of script headers: serialscript.pl

in error_log for the HTTP server, and I get Internal Server Error in IE.

I gather that I'm getting the error messages because I'm not returning anything to the browser, but I don't want the browser to print anything.

Here's how I invoke the script from the URL line of IE:

Code:
[URL unfurl="true"]http://192.168.192.94:8000/cgi-bin/serialscript.pl?value=1234[/URL]

Here's my serialscript.pl:

Code:
#!/usr/bin/perl
use CGI;
$cgi = new CGI;
$value = $cgi->param('value');
open(OUT, ">/dev/ttyS0");
print OUT $value;
close(OUT);

How do I fix this ?

I don't get any error messages if I run:

./serialscript.pl

from the Linux command line from the folder with serialscript.pl in it, but I don't know how to pass parameters to the script from the command line. How do I do that ?

Thank you.
 
Feherke suggestion is a good one, but note that you still have to send something back to the broswer, there is no getting around that.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
I'm doing something wrong. I'm still getting an Internal Server Error.

Here's the reference from IE6:

Code:
[URL unfurl="true"]http://192.168.192.94:8000/cgi-bin/serialscript.pl?value=#FF010A0C3F3F95FF010A0C000017[/URL]

Here's my revised serialscript.pl:

Code:
#!/usr/bin/perl
use CGI;
$cgi = new CGI;
$value = $cgi->param('value');
print header(-status=>'204 No Content');
open(OUT, ">/dev/ttyS0");
print OUT $value;
close(OUT);

Here's the Apache error_log that results -- it's unhappy about the new print statement:

Code:
[Tue Jul 31 13:13:12 2007] [error] [client 192.168.192.128] Undefined subroutine &main::header called at /var/[URL unfurl="true"]www/cgi-bin/serialscript.pl[/URL] line 5., referer: [URL unfurl="true"]http://192.168.192.94:8000[/URL]
[Tue Jul 31 13:13:12 2007] [error] [client 192.168.192.128] Premature end of script headers: serialscript.pl, referer: [URL unfurl="true"]http://192.168.192.94:8000[/URL]

How do I fix this ? Can someone revise serialscript.pl to show me exactly how it should be ?

Thank you.
 
Hi

Code:
#!/usr/bin/perl
use CGI [red]qw/:standard/[/red];
$cgi = new CGI;
$value = $cgi->param('value');
print header(-status=>'204 No Content');
open(OUT, ">/dev/ttyS0");
print OUT $value;
close(OUT);

Feherke.
 
Well, I assume NewtownGuy not wants to reform the transfer protocol...

the point is that the script has to send some type of http header back. The header is a reply, even if it is a 204, which is appropriate if there is no content.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Thanks ! The addition of qw:/standard/ fixed the error messages.

Now that that problem is fixed, here's what I'm really trying to do. I know I've massacred perl:

Code:
#!/usr/bin/perl
#output a sequence of (a) one 8-bit value that is always 0xFF, (b) n 8-bit values, each of which is sent as two hex characters by caller, and (c) one 8-bit value, the check sum, cks, which is the modulo 256 sum of the n 8-bit values sent by caller

use CGI qw/:standard/;
$cgi = new CGI;
$value = $cgi->param('value');
print header(-status=>'204 No Content'); #dummy no-value returned to web page to avoid error messages

$bytes = length($value) / 2; #halve the length of the string since each 8-bit value is sent by caller as two hex digits
$cks = 0; #initialize check sum
open(OUT, ">/dev/ttyS0"); #everything actually goes out a COM port
flock(OUT, 2); #lock the file to protect it from writing by others
print OUT FF; #output one 8-bit value, which is a fixed sync byte whose value is 0xFF

for ($i = 0; ($i < $bytes); $i++) { 
my $hex = substr($value, $i, 2); 
my $c = sscanf("%02x", $hex); 
print SERIAL $c; 
$cks = $cks + my $hex; #add new character to cks
}

$cks = $cks AND FF; #modulo 256 sum, want an 8-bit result
print OUT $cks; #output checksum as one byte
flock(OUT, 8); #unlock the file
close(OUT);

Can you tell me how to fix this ? I've been reading PERL and CGI for the world wide web, but I can't find the syntax of some of the constructs that have been given to me.

Thank you.
 
is that all the code? There are no other references to "SERIAL" filehandle or the sscanf() function, which is not a core perl function.

Not sure what you want to do here:

Code:
$cks = $cks + my $hex

maybe:

Code:
$cks .= $hex; #appends $hex to the end of $cks

or:

Code:
$cks += $hex; #adds $hex to the value of $cks as in 2+2=4

this I just don't know what you want to do:

Code:
$cks = $cks AND FF; #modulo 256 sum, want an 8-bit result

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
If you ever don't want to print something but you think that you have to include a print statement why not just use

print "";

The statement is included, but nothing is outputted
 
I've rewritten the code to try to explain what I'm trying to do. The key elements are that if, for example, 0x12 is sent by caller, then 00010010 (binary) is output.

I've put some of the more problematical parts of the code in blue.

Here's the revised code:

Code:
#!/usr/bin/perl
#output a sequence of (a) sync -- an initial 8-bit whose value is always 0xFF, (b) n 8-bit values, each of which is sent to this script as two hex characters by caller, and (c) one final 8-bit value, the checksum, which is the modulo 256 sum of the n 8-bit values sent by caller, to a COM port

use CGI qw/:standard/;
$cgi = new CGI;
$value = $cgi->param('value');
print header(-status=>'204 No Content'); #dummy no-value returned to web page to avoid error messages

$bytes = length($value) / 2; #each 8-bit value to be output is sent by caller as two hex characters, so the number of bytes to be output (not counting the sync and checksum bytes) is half the number of characters sent by caller
$cks = 0; #initialize checksum, which will be computed as the sum of the n 8-bit values output
open(OUT, ">/dev/ttyS0"); #open output file and redirect to COM port
flock(OUT, 2); #lock the file to protect it from writing by others
[COLOR=blue]print OUT FF; #output one fixed 8-bit value whose value is 0xFF -- is this how I output one byte whose value is 11111111 (binary) ?[/color]

for ($i = 0; ($i < $bytes); $i++) { 
[COLOR=blue]$hex = substr($value, $i, 2); #how do I form one 8-bit value from the 4 lsb's from two hex characters ???
[/color]
[COLOR=blue]print OUT $hex; #output one 8-bit value from two hex characters -- how does print know to output only one byte -- same question as above ?[/color]
$cks = $cks + $hex; #add 8-bit value from new character to cks. Only compute cks to 8 bits since the calculation is modulo 256
}

[COLOR=blue]print OUT $cks; #output checksum as the final byte -- again, I only want to output one byte[/color]
flock(OUT, 8); #unlock the file
close(OUT);

Thank you.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top