Fedora Core 4
httpd-2.0.54-10
mod_perl-2.0.0-0.rc5.3
nph mod_perl script

If I user $r->print to print the response to the client, it returns that
it sent more bytes than length($write_buffer) and the JPEG, which is part of the response, is bad if the response header contains a Content-Disposition in which the filename field is set from appended hash values.

Code Example 1:
------------------------------------------------------------------
my $snapshot_filename = "$stream->{'feed-id'}-$stream->{'id'}.jpg";
print STDERR "snap=#$snapshot_filename#\n";
$write_buffer = "$ENV{'SERVER_PROTOCOL'} 200 OK\r\n" .
       "Pragma: no-cache\r\n" .
       "Cache-Control: must-revalidate, no-cache, no-store\r\n" .
       "Content-Type: image/jpeg\r\n";
if ( defined($attachment) && $attachment eq "true" ){
$write_buffer .= "Content-Disposition: attachment; filename=\"$snapshot_filename\"\r\n";
}
$write_buffer .= "Content-Length: " . length($jpeg) . "\r\n";
$write_buffer .= "\r\n" . $jpeg . "\r\n\r\n";
$sent_bytes = $r->print($write_buffer);
------------------------------------------------------------------

Code Example 2:
------------------------------------------------------------------
my $snapshot_filename = "$stream->{'feed-id'}-$stream->{'id'}.jpg";
print STDERR "snap=#$snapshot_filename#\n";
$write_buffer = "$ENV{'SERVER_PROTOCOL'} 200 OK\r\n" .
       "Pragma: no-cache\r\n" .
       "Cache-Control: must-revalidate, no-cache, no-store\r\n" .
       "Content-Type: image/jpeg\r\n";
if ( defined($attachment) && $attachment eq "true" ){
$write_buffer .= "Content-Disposition: attachment; filename=\"$snapshot_filename\"\r\n";
}
$write_buffer .= "Content-Length: " . length($jpeg) . "\r\n";
$write_buffer .= "\r\n";
$sent_bytes = $r->print($write_buffer);
$sent_bytes += $r->print($jpeg);
$sent_bytes += $r->print("\r\n\r\n");
------------------------------------------------------------------

Code Example 3:
------------------------------------------------------------------
my $snapshot_filename = "$stream->{'feed-id'}-$stream->{'id'}.jpg";
print STDERR "snap1=#$snapshot_filename#\n";
$snapshot_filename = "feed_1-stream_2.jpg";
print STDERR "snap2=#$snapshot_filename#\n";
$write_buffer = "$ENV{'SERVER_PROTOCOL'} 200 OK\r\n" .
       "Pragma: no-cache\r\n" .
       "Cache-Control: must-revalidate, no-cache, no-store\r\n" .
       "Content-Type: image/jpeg\r\n";
if ( defined($attachment) && $attachment eq "true" ){
$write_buffer .= "Content-Disposition: attachment; filename=\"$snapshot_filename\"\r\n";
}
$write_buffer .= "Content-Length: " . length($jpeg) . "\r\n";
$write_buffer .= "\r\n" . $jpeg . "\r\n\r\n";
$sent_bytes = $r->print($write_buffer);
------------------------------------------------------------------

$attachment="true" for all tests.

In Code Example 1, snap=#feed_1-stream_2.jpg# and $r-print reports that it has sent more bytes than length($write_buffer) (bytes_sent=10951 vs length($write_buffer)=7648) and the attachment on the client's end is corrupted.

If I change "$sent_bytes = $r->print($write_buffer);" to "print $write_buffer;" in Code Example 1, the attachment is a valid JPEG on the client's end.

In Code Example 2, snap=#feed_1-stream_2.jpg# and I use $r->print to send the message, but I send each "section" as a separate $r->print call. In this case, $r-print prints the correct number of bytes and the attachment is a valid JPEG on the client's end.

In Code Example 3, snap1=#feed_1-stream_2.jpg# and snap2=#feed_1-stream_2.jpg#, I print the unified message just like I did in Example 1 and the reported bytes sent is correct and the JPEG is valid on the client's end. If I test snap1 and snap2 for string equality, they match.

So, Code Example 1 and 3 should be exactly the the save except the in Code Example 3 I do not build the string from values in a hash. But, the two strings match, so why does Code Example 3 work where Code Example 1 failes? Why does Code Example 1 work if replace "$bytes_sent = $r->print($write_buffer)" with "print $write_buffer". Why does Code Example 2 work even though it should be equivalent to Code Example 1?

And how can $r->print legitimately return bytes_sent larger than the length of the buffer?

Has anyone see this behavior before? I am not sure where to go from here...

thanks for any help,
Christopher

Reply via email to