Hi Bradley,
I'm thinking that we should instead document the {proxy} attribute. It can be useful to have it available in $response->request to be able to tell where the request was sent.
The reason why _need_proxy() does not override {proxy} if set is that it allows other handlers to set it up. You might for instance want to set up a handler that proxies everything not going to your intranett, or just set it explicitly for some requests.
--Gisle
On Apr 9, 2011, at 0:44 , Bradley Dean wrote:
> Greetings,
>
> I've been looking at what feels to me like a bug with the handling of proxy configuration. When a HTTP::Request is made through an LWP::UserAgent with a proxy configured the HTTP::Request is changed by LWP::UserAgent::__need_proxy:
>
> sub _need_proxy {
> ...
> $req->{proxy} = $HTTP::URI_CLASS->new($proxy);
> }
>
> "proxy" is not a documented attribute of the HTTP::Request class, but when it is set _need_proxy ignores the current LWP::UserAgent proxy settings:
>
> sub _need_proxy {
> my($req, $ua) = @_;
> return if exists $req->{proxy};
> ...
> }
>
> This becomes a problem when trying to use a single HTTP::Request instance across multiple proxies - for example:
>
> my $request = HTTP::Request->new(GET => 'http://www.example.com/');
> my $ua = LWP::UserAgent->new();
> $ua->proxy('http', 'http://proxy_one.example.org:12345/');
>
> # This first request goes through proxy_one
> $ua->request($request);
>
> # Now change the proxy on the LWP::UserAgent
> $ua->proxy('http', 'http://proxy_two.example.org:12345/');
>
> # This second request goes through proxy_one still because
> # $request->{proxy} == "http://proxy_one.example.org:12345/"
> $ua->request($request);
>
> This can be worked around in the calling software by deleting $request->{proxy} between requests but it's a hack (and one which could fail at any time given that this is a non-documented attribute).
>
> I've thought of a few possible patches:
>
> PATCH 1:
>
> Remove the "return if exists $req->{proxy};" line from _need_proxy. I think this is the cleanest approach.
>
> Thinking of reasons not to do this: that it incurs some extra processing cost per request (but only in the case that a single request is used over and over again); it might break existing code that relies on the undocumented "proxy" attribute (where people are building requests with proxies rather than configuring via LWP::UserAgent). If this is a concern see 2.
>
> PATCH 1 GIT:
>
> diff --git a/lib/LWP/UserAgent.pm b/lib/LWP/UserAgent.pm
> index 1ee9ffb..945cd8a 100644
> --- a/lib/LWP/UserAgent.pm
> +++ b/lib/LWP/UserAgent.pm
> @@ -934,7 +934,6 @@ sub mirror
>
> sub _need_proxy {
> my($req, $ua) = @_;
> - return if exists $req->{proxy};
> my $proxy = $ua->{proxy}{$req->uri->scheme} || return;
> if ($ua->{no_proxy}) {
> if (my $host = eval { $req->uri->host }) {
>
>
> PATCH 2:
>
> A more expensive option would be to check if the LWP::UserAgent has a proxy configured and if it is different from the proxy attribute on the HTTP::Request.
>
> If it is different I would argue that LWP::UserAgent value should override the requestm, so if the values were different the LWP::UserAgent could change the value of the proxy atttribute.
>
> I've not included a git patch for this option but could supply one if it was of interest.
>
> PATCH 3:
>
> At the moment $request->{proxy} has to be set because the request is passed out of the LWP::UserAgent to a protocol handler. As I recall at this stage the LWP::UserAgent is not visible to the protocol handler, so $request is used to pass on the proxy configuration.
>
> A much bigger change to the code would have the protocol handler given access to the LWP::UserAgent so that the proxy did not have to be attached to the HTTP::Request. The same decision still needs to be made as in PATCH 2 (ie what happens if someone has set the proxy attribute).
>
> As with patch 2, I've not included a git patch for this option but could supply one if it was of interest.
>
> Cheerio,
>
> Brad
Thread Previous
|
Thread Next