Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Re: sending a large file via http

by rhesa (Vicar)
on Jun 18, 2007 at 22:17 UTC ( [id://621880]=note: print w/replies, xml ) Need Help??


in reply to sending a large file via http

LWP::UserAgent allows you to pass a callback to the request() method, which you can use to stream data into the request.

This is the relevant quote:

$ua->request( $request, $content_cb )

You are allowed to use a CODE reference as content in the request object passed in. The content function should return the content when called. The content can be returned in chunks. The content function will be invoked repeatedly until it return an empty string to signal that there is no more content.

Replies are listed 'Best First'.
Re^2: sending a large file via http
by mifflin (Curate) on Jun 18, 2007 at 22:52 UTC
    So does this mean that the content-length header value is no longer used?
    Here is some untested sample code based on your response and reading the lwp::useragent docs...
    use strict; use warnings; use LWP; use IO::Handle; use Fatal qw( open close ); my $url = 'https://........'; my filename = 'file2send.txt'; my $LINES_PER_CHUNK = 100; open my $fh, '<', $filename; sub sendthis { my @buf; my $linesread = 0; if ($fh->isopened) { while (my $line = <$fh>) { $linesread++; push(@buf, $line); if ($linesread == $LINES_PER_CHUNK) { return join('', @buf); } } close $fh; return join('', @buf); } return ''; } eval { my $headers = HTTP::Headers->new(); $headers->header('Content-Type' => 'text/plain; charset=utf-8'); $headers->header('Content-Length' => -s $file2send); my $request = HTTP::Request->new('POST', $url, $headers); $request->protocol('HTTP/1.1'); my $browser = LWP::UserAgent->new(); my $response = $browser->request($request, \&sendthis); my $gotthis = $response->content(); print $gotthis; }; if ($@) { # handle error ! }
    Edit: made changes that rhesa suggested regarding request method callback and content length
      So does this mean that the content-length header value is no longer used?
      I can't tell from the LWP docs if it handles that for you, but you can still set it yourself, for example with my $length = -s $filename; and then adding the appropriate header.

      Regarding your code, I read the docs slightly differently:

      my $request = HTTP::Request->new('POST', $url, $headers); $request->protocol('HTTP/1.1'); my $browser = LWP::UserAgent->new(); my $response = $browser->request($request, \&sendthis);
      That is, you pass the callback to the LWP->request method, not the HTTP::Request constructor.
        Thanks for the response.
        I made the changes you suggested above.
        Now if I could just get the client to give me a url so I can test....
        Check out LWP/Protocol/http.pm
          When request is called here, your coderef is in $arg
        
        sub request {
          my($self, $request, $proxy, $arg, $size, $timeout) = @_;
         ...
            my $content_ref = $request->content_ref;
            $content_ref = $$content_ref if ref($$content_ref);
        ....
                if (ref($content_ref) eq 'CODE') {
                    my $buf = &$content_ref();
        ...
        
        http.pm doesn't look at $arg as a code ref.
        Instead it looks at $content_ref.
        But if $content_ref was a code ref, then you'll get a run time error.
        
        It'll never work !  This feature is totally broken.
        

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://621880]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (5)
As of 2024-04-24 08:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found