1LWP::Protocol::PSGI(3pmU)ser Contributed Perl DocumentatiLoWnP::Protocol::PSGI(3pm)
2
3
4

NAME

6       LWP::Protocol::PSGI - Override LWP's HTTP/HTTPS backend with your own
7       PSGI application
8

SYNOPSIS

10         use LWP::UserAgent;
11         use LWP::Protocol::PSGI;
12
13         # $app can be any PSGI application: Mojolicious, Catalyst or your own
14         my $app = do {
15             use Dancer;
16             set apphandler => 'PSGI';
17             get '/search' => sub {
18                 return 'searching for ' . params->{q};
19             };
20             dance;
21         };
22
23         # Register the $app to handle all LWP requests
24         LWP::Protocol::PSGI->register($app);
25
26         # can hijack any code or module that uses LWP::UserAgent underneath, with no changes
27         my $ua  = LWP::UserAgent->new;
28         my $res = $ua->get("http://www.google.com/search?q=bar");
29         print $res->content; # "searching for bar"
30
31         # Only hijacks specific host (and port)
32         LWP::Protocol::PSGI->register($psgi_app, host => 'localhost:3000');
33
34         my $ua = LWP::UserAgent->new;
35         $ua->get("http://localhost:3000/app"); # this routes $app
36         $ua->get("http://google.com/api");     # this doesn't - handled with actual HTTP requests
37

DESCRIPTION

39       LWP::Protocol::PSGI is a module to hijack any code that uses
40       LWP::UserAgent underneath such that any HTTP or HTTPS requests can be
41       routed to your own PSGI application.
42
43       Because it works with any code that uses LWP, you can override various
44       WWW::*, Net::* or WebService::* modules such as WWW::Mechanize, without
45       modifying the calling code or its internals.
46
47         use WWW::Mechanize;
48         use LWP::Protocol::PSGI;
49
50         LWP::Protocol::PSGI->register($my_psgi_app);
51
52         my $mech = WWW::Mechanize->new;
53         $mech->get("http://amazon.com/"); # $my_psgi_app runs
54

TESTING

56       This module is extremely handy if you have tests that run HTTP requests
57       against your application and want them to work with both internal and
58       external instances.
59
60         # in your .t file
61         use Test::More;
62         use LWP::UserAgent;
63
64         unless ($ENV{TEST_LIVE}) {
65             require LWP::Protocol::PSGI;
66             my $app = Plack::Util::load_psgi("app.psgi");
67             LWP::Protocol::PSGI->register($app);
68         }
69
70         my $ua = LWP::UserAgent->new;
71         my $res = $ua->get("http://myapp.example.com/");
72         is $res->code, 200;
73         like $res->content, qr/Hello/;
74
75       This test script will by default route all HTTP requests to your own
76       PSGI app defined in $app, but with the environment variable "TEST_LIVE"
77       set, runs the requests against the live server.
78
79       You can also combine Plack::App::Proxy with LWP::Protocol::PSGI to
80       route all requests made in your test against a specific server.
81
82         use LWP::Protocol::PSGI;
83         use Plack::App::Proxy;
84
85         my $app = Plack::App::Proxy->new(remote => "http://testapp.local:3000")->to_app;
86         LWP::Protocol::PSGI->register($app);
87
88         my $ua = LWP::UserAgent->new;
89         my $res = $ua->request("http://testapp.com"); # this hits testapp.local:3000
90

METHODS

92       register
93             LWP::Protocol::PSGI->register($app, %options);
94             my $guard = LWP::Protocol::PSGI->register($app, %options);
95
96           Registers an override hook to hijack HTTP requests. If called in a
97           non-void context, returns a guard object that automatically resets
98           the override when it goes out of context.
99
100             {
101                 my $guard = LWP::Protocol::PSGI->register($app);
102                 # hijack the code using LWP with $app
103             }
104
105             # now LWP uses the original HTTP implementations
106
107           When %options is specified, the option limits which URL and hosts
108           this handler overrides. You can either pass "host" or "uri" to
109           match requests, and if it doesn't match, the handler falls back to
110           the original LWP HTTP protocol implementor.
111
112             LWP::Protocol::PSGI->register($app, host => 'www.google.com');
113             LWP::Protocol::PSGI->register($app, host => qr/\.google\.com$/);
114             LWP::Protocol::PSGI->register($app, uri => sub { my $uri = shift; ... });
115
116           The options can take either a string, where it does a complete
117           match, a regular expression or a subroutine reference that returns
118           boolean given the value of "host" (only the hostname) or "uri" (the
119           whole URI, including query parameters).
120
121       unregister
122             LWP::Protocol::PSGI->unregister;
123
124           Resets all the overrides for LWP. If you use the guard interface
125           described above, it will be automatically called for you.
126

DIFFERENCES WITH OTHER MODULES

128   Mock vs Protocol handlers
129       There are similar modules on CPAN that allows you to emulate LWP
130       requests and responses. Most of them are implemented as a mock library,
131       which means it doesn't go through the LWP guts and just gives you a
132       wrapper for receiving HTTP::Request and returning HTTP::Response back.
133
134       LWP::Protocol::PSGI is implemented as an LWP protocol handler and it
135       allows you to use most of the LWP extensions to add capabilities such
136       as manipulating headers and parsing cookies.
137
138   Test::LWP::UserAgent
139       Test::LWP::UserAgent has the similar concept of overriding LWP request
140       method with particular PSGI applications. It has more features and
141       options such as passing through the requests to the native LWP handler,
142       while LWP::Protocol::PSGI only allows one to map certain hosts and
143       ports.
144
145       Test::LWP::UserAgent requires you to change the instantiation of
146       UserAgent from "LWP::UserAgent->new" to "Test::LWP::UserAgent->new"
147       somehow and it's your responsibility to do so. This mechanism gives you
148       more control which requests should go through the PSGI app, and it
149       might not be difficult if the creation is done in one place in your
150       code base. However it might be hard or even impossible when you are
151       dealing with third party modules that calls LWP::UserAgent inside.
152
153       LWP::Protocol::PSGI affects the LWP calling code more globally, while
154       having an option to enable it only in a specific block, thus there's no
155       need to change the UserAgent object manually, whether it is in your
156       code or CPAN modules.
157

AUTHOR

159       Tatsuhiko Miyagawa <miyagawa@bulknews.net>
160
162       Copyright 2011- Tatsuhiko Miyagawa
163

LICENSE

165       This library is free software; you can redistribute it and/or modify it
166       under the same terms as Perl itself.
167

SEE ALSO

169       Plack::Client LWP::UserAgent
170
171
172
173perl v5.32.0                      2020-07-28          LWP::Protocol::PSGI(3pm)
Impressum