1LWP::Protocol::PSGI(3pmU)ser Contributed Perl DocumentatiLoWnP::Protocol::PSGI(3pm)
2
3
4
6 LWP::Protocol::PSGI - Override LWP's HTTP/HTTPS backend with your own
7 PSGI application
8
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
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
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
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
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
159 Tatsuhiko Miyagawa <miyagawa@bulknews.net>
160
162 Copyright 2011- Tatsuhiko Miyagawa
163
165 This library is free software; you can redistribute it and/or modify it
166 under the same terms as Perl itself.
167
169 Plack::Client LWP::UserAgent
170
171
172
173perl v5.32.0 2020-07-28 LWP::Protocol::PSGI(3pm)