Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Re^4: Serving video files in specific byte-ranges

by goofball (Acolyte)
on Sep 06, 2011 at 19:29 UTC ( #924451=note: print w/replies, xml ) Need Help??

in reply to Re^3: Serving video files in specific byte-ranges
in thread Serving video files in specific byte-ranges

That's a helpful link - thanks! Although, that code uses an HTTP::Response object to pass back to the daemon. Any advice on printing out the response object when not using a daemon? The CPAN docs are entirely clear on this (HTTP::Response and HTTP::Message), and when I implement the print $response->decoded_content in the following code, I get an error of Can't decode ref content at /usr/local/lib/perl5/site_perl/5.8.9/HTTP/ line 294.
use HTTP::Response; use IO::File; my $response = new HTTP::Response( 404,undef,undef,"404 - Not foun +d." ); $|=1; my $file = new IO::File "< $path"; if (defined $file) { $response->code( 200 ); binmode $file; my $size = -s $file; my ($startrange, $endrange) = (0,$size-1); if (defined $ENV{HTTP_RANGE} and $ENV{HTTP_RANGE} =~ /bytes\s* +=\s*(\d+)-(\d+)?/) { $response->code( 206 ); ($startrange,$endrange) = ($1,$2 || $endrange); }; $file->seek($startrange,0); $response->header(Content_Length => $endrange-$startrange); $response->header(Content_Range => "bytes $startrange-$endrang +e/$size"); $response->content( sub { sysread($file, my ($buf), 16*1024); # No error checking ?? +? return $buf; }); }; print $response->decoded_content;

Another option I tried, just printing the HTTP headers and content to STDOUT, follows below. This prints the requested ranges using a Transfer-Encoding method of chunked, as described here: and here: Wiki. There are no server-side errors using this script, but the iPhone Safari client still shows a broken file.

my @ranges; if($ENV{HTTP_RANGE} =~ s/^bytes=//i) { @ranges = split /,/, $ENV{HTTP_RANGE}; print "Transfer-Encoding: chunked\n"; warn "printing ranges @ranges\n"; } else { print "Content-length: $filesize\n\n"; } if(@ranges) { open my $fh, '<', $path; foreach $range (@ranges) { my($begin, $end) = split /-/, $range; print "Content_Range: bytes $begin-$end/$filesize\ +n\n"; my $whence = ($begin)? 0 : 2; my $position = ($begin)? $begin : 0 - $end; seek $fh, $position, $whence; if($end) { $range = ($begin)? $end - $begin : $end; my $chunk_header = sprintf("%x", $range); print "$chunk_header\r\n"; sysread $fh, $_ , $range; print "$_\r\n"; warn "printed range of $range bytes from $begi +n to $end\n"; } else { while(<$fh>) { print } } } close $fh; print "0\r\n"; } else { open(FILE, $path) or die; while(<FILE>) { print } close(FILE); }

Replies are listed 'Best First'.
Re^5: Serving video files in specific byte-ranges
by Corion (Pope) on Sep 06, 2011 at 20:22 UTC

    Looking at the source of HTTP::Message, it just does not want to decode the content delivered by a callback:

    ... $content_ref = $self->content_ref; die "Can't decode ref content" if ref($content_ref) ne "SCALAR"; ...

    Either you fix HTTP::Message or you try it with ->content() instead of ->decoded_content. Alternatively, look at Plack as your server framework - it should handle callback responses more gracefully than your approach.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://924451]
[shmem]: thao4 example of the text and program missing in your post
[Eily]: also you can use <p> or <br /> tags to have multiple lines
[hippo]: Please also take a moment to read through I know what I mean. Why don't you? - this guidance will help others to help you.

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (8)
As of 2018-02-21 10:13 GMT
Find Nodes?
    Voting Booth?
    When it is dark outside I am happiest to see ...

    Results (277 votes). Check out past polls.