Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 7, 2021 04:36 am GMT

Perling and Curling

Most of us probably know curl as a quick and easy way to send HTTP requests from the command line.

That tool, though, is just an interface to the curl projects real gold: the libcurl API. Using this API, applications in all sorts of languages have easy access to the awesome power that libcurl provides. This article will discuss how to use that power in Perl.

A Quick Example

use Net::Curl::Easier;my $easy = Net::Curl::Easier->new(    url => 'http://perl.org',    followlocation => 1,)->perform();print $easy->head(), $easy->body();

Lets talk about what just happened.

Net::Curl::Easier is a thin wrapper around Net::Curls easy interfaceeasy is what libcurl calls it!that smooths over some rough edges in Net::Curl.

(Full disclosure: I am Net::Curl::Easiers maintainer.)

Once we create our Easier object, having given it the proper URL and told it to follow HTTP redirects (followlocation refers to HTTPs Location header), we run perform() on the Easier object.

After that, we print the HTTP response headers and body, and were done!

Why not just use HTTP::Tiny?

Indeed. Well, error reporting, for one. Consider:

Net::Curl::Easier->new(    url => 'http://blahblah',)->perform();

If you run this youll probably just see Couldn't resolve host name printed to standard error. But if you dig deeper youll see something nifty:

use Net::Curl::Easier;use Data::Dumper;eval {    Net::Curl::Easier->new(        url => 'http://blahblah',    )->perform();};print Dumper $@;

It turns out that that error isnt just a string; its an exception object.

In large systems I often want to handle certain failure types differently from others. HTTP::Tinys errors are just strings, so type-specific failure handling with HTTP::Tiny entails parsing strings, which is brittle. What if someone decides to reword some error message for clarity, thus breaking my string parser?

With Net::Curl I can look for specific numeric error codes, documentation for which the curl project itself maintains. This is much more robust.

Dont care. What else you got?

OK. How about this:

my $easy = Net::Curl::Easier->new(    username => 'hal',    userpwd => 'itsasecret',    url => 'imap://mail.example.com/INBOX/;UID=123',)->perform();

I just queried an email inbox?!?

Curl doesnt just speak HTTP; it speaks many other protocols including IMAP, LDAP, SCP, and MQTT. To see the full list of protocols that your curl supports, run curl --version.

Concurrency

Curl can also run concurrent queries. To do that I recommend using Net::Curl::Promiser. (Full disclosure: I also maintain this module.)

Example, assuming use of Mojolicious:

use Net::Curl::Easier;use Net::Curl::Promiser::Mojo;use Mojo::Promise;my $easy1 = Net::Curl::Easier->new(    url => 'http://perl.org',    followlocation => 1,);my $easy2 = Net::Curl::Easier->new(    username => 'hal',    userpwd => 'itsasecret',    url => 'imap://mail.example.com/INBOX/;UID=123',);my $easy3 = Net::Curl::Easier->new(    username => 'hal',    userpwd => 'itsasecret',    url => 'scp://tty.example.com/path/to/file',);my $promiser = Net::Curl::Promiser::Mojo->new();Mojo::Promise->all_settled(    $promiser->add_handle($easy1)->then( sub {        print $easy1->head(), $easy1->body();    } ),    $promiser->add_handle($easy2)->then( sub {        # ... whatever you want with the IMAP result    } ),    $promiser->add_handle($easy3)->then( sub {        # ... whatever you want with the SCP result    } ),)->wait();

We just grabbed a web page, queried a mailbox, and downloaded a file via SCP, all in parallel!

Net::Curl::Promiser also works natively with
AnyEvent and
IO::Async, should those be of greater interest to you. It also provides a convenience layer for custom select-based event loops, in case thats how you roll.

Other Modules

Some alternatives to modules presented above:

  • AnyEvent::YACurl: A newer library than Net::Curl that simplifies the interface a bit. It assumes use of AnyEvent, though, so if youre not using AE then this may not be for you.

  • WWW::Curl: The library of which Net::Curl is a fork. It lacks access to libcurls advanced multi interface.

  • Net::Curl::Simple: A wrapper by Net::Curls original author. It provides some of the same conveniences as Net::Curl::Promiser and Net::Curl::Easier but uses callbacks rather than promises.

Closing Thoughts

Curl exposes an awesome breadth of functionality, of which the above examples have just scratched the surface. Check it out!


Original Link: https://dev.to/fgasper/perling-and-curling-2i10

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To