libwww-perl / libwww-perl/HTTP-Daemon
Setting $\ to "\n" inserts newlines in the file send with $c->send_file() or $c->send_file_response()
Nobody has claimed this yet.
- Dominant language
- Perl
- Stars
- 6
- Forks
- 17
- PR merge metrics
- No merged PRs in 30d
Description
When you set $\ ($OUTPUT_RECORD_SEPARATOR) to anything other than "" (empty string) in the server script,
the value of $\ is inserted multiple times in a file send with $c->send_file() or $c->send_file_response();
It may not be too bad for a text file but it makes a BINARY FILE corrupted and useless, a video for example.
I put an example of the server and client script that I used.
I also found the problem.
This is coming from the send_file() method.
This method reads the file to be send by chunk of 8K and it prints the temporary buffer to a filehandle.
And because $\ is global, a new line is inserted on each print of HTTP::Daemon::send_file().
The SOLUTION is to put :
local ($\ = "");
in the method send_file()
The reason I didn't make a pull request is because I am not sure if that is the best solution.
Would it be better to put local ($\ = ""); at the top of the package for example ?
ALSO,
the same problem that I found might also impact other methods of this package
because there is other methods that prints to a filehandle. And I do not know enough HTTP to decide myself.
In particular, when it concerns the CRLF "\r\n"
Those are the methods that can be possibly impacted : (because of a print to a filehandle)
I put aside methods that print to STDERR.
sub send_status_line {
sub send_crlf {
sub send_basic_header {
sub send_header {
sub send_response {
sub send_redirect {
sub send_error {
sub send_file_response {
sub send_file {
####################################################
EXAMPLE
SERVER SCRIPT
my $file = "/path/to/small/video_file.mp4";
my $port = 3000;
my $d = HTTP::Daemon->new(LocalPort => $port) || die "fail";
$\ = "\n";
print $d->url;
while (my $c = $d->accept) {
while (my $r = $c->get_request) {
if ($r->method eq "GET") {
print "got a GET request"; # the reason to set $\ to "\n"
# $c->send_file_response($file);
$c->send_file($file);
}
}
$c->close;
undef $c;
}
####################################################
CLIENT SCRIPT
my $url = "http://localhost:3000/";
my $req = HTTP::Request->new(GET => $url);
my $ua = LWP::UserAgent->new();
$ua->show_progress(1);
my $res = $ua->request($req);
open FH, ">:bytes", "response.mp4";
print FH $res->content;
close FH;
PS :
Sorry for the indentation, I don't know how that works
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by inspecting HTTP::Daemon's send_file() and send_file_response() entry points, then review the listed methods that print to filehandles. Reproduce the binary transfer with the provided server and client scripts, and verify that the response remains unmodified when $\ is set; done means the affected send paths no longer insert separator data.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- perl
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100