Skip Menu |

This queue is for tickets about the HTTP-Async CPAN distribution.

Report information
The Basics
Id: 84429
Status: resolved
Priority: 0/
Queue: HTTP-Async

People
Owner: Nobody in particular
Requestors: lingvista [...] email.cz
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: 0.14
Fixed in: (no value)



Subject: [PATCH] Incorrect handling of headers
Hello, I've found out that HTTP::Async doesn't handle headers from HTTP::Headers correctly while composing the request. HTTP::Headers is super-inteligent about the case of header names - it can deal with mistyped header names like USer-aGENT. BUT it creates a special key called '::std_case' among the legal header names in its internal data structure. HTTP::Async is behaving a little bit too much low-level when it extracts the headers and, as a consequence, it can send out something like "::std_case: HASH(0x1234567)" among the HTTP headers. (When for example a Cookie header is used). That makes the request illegal and (to give an example) Facebook doesn't like it at all (400 - Bad Request). The attached patch is pretty straighforward. I hope it will be useful. Anyway, thank you for a good work. I've been messing with events and threads in the last week (to no good result) and it was HTTP::Async that did the job for me in the end.
Subject: Async.pm.patch
*** Async.pm 2013-04-04 14:14:16.000000000 +0200 --- Async.pm.patched 2013-04-04 14:14:04.000000000 +0200 *************** *** 684,690 **** return 1; } ! my %headers = %{ $request->{_headers} }; # Decide what to use as the request_uri my $request_uri = $request_is_to_proxy # is this a proxy request.... --- 684,693 ---- return 1; } ! my %headers; ! for my $key ($request->{_headers}->header_field_names) { ! $headers{$key} = $request->header($key); ! } # Decide what to use as the request_uri my $request_uri = $request_is_to_proxy # is this a proxy request....
Hi Josef, Thanks for your bug report and patch, very helpful! Unfortunately it looks like none of the existing unit tests cover that code path - if I put a "die" in the for loop you added the tests still pass. Awkward... Could you possibly share some code or a test with me that shows the problem? Thanks, - Alex On Thu Apr 04 08:46:15 2013, lingvik wrote: Show quoted text
> Hello, I've found out that HTTP::Async doesn't handle headers from > HTTP::Headers correctly while composing the request. > > HTTP::Headers is super-inteligent about the case of header names - it > can deal with mistyped header names like USer-aGENT. BUT it creates > a special key called '::std_case' among the legal header names in > its internal data structure. > > HTTP::Async is behaving a little bit too much low-level when it > extracts the headers and, as a consequence, it can send out > something like "::std_case: HASH(0x1234567)" among the HTTP > headers. (When for example a Cookie header is used). That makes the > request illegal and (to give an example) Facebook doesn't like it > at all (400 - Bad Request). > > The attached patch is pretty straighforward. I hope it will be useful. > > Anyway, thank you for a good work. I've been messing with events and > threads in the last week (to no good result) and it was HTTP::Async > that did the job for me in the end.
From: lingvista [...] email.cz
Hello Alex, thank you for a quick response. It took me more time than expected because I stumbled on another bug along the way :-) Anyway, try to look at and run the attached script. I kept it as simple as possible. Your "die" might have been skipped if none of the tests used any headers. I'll create a new ticket for the other bug to keep things in order. Josef On Thu Apr 04 09:39:22 2013, KAORU wrote: Show quoted text
> Hi Josef, > > Thanks for your bug report and patch, very helpful! > > Unfortunately it looks like none of the existing unit tests cover that > code path - if I put a "die" in the for loop you added the tests still > pass. Awkward... > > Could you possibly share some code or a test with me that shows the > problem? > > Thanks, > > - Alex >
Subject: fail.pl
#!/usr/bin/env perl use warnings; use strict; use HTTP::Async; use HTTP::Request; my $request = HTTP::Request->new('GET', 'http://www.facebook.com'); $request->header('Cookie', 'foo=bar'); my $client = HTTP::Async->new(); $client->add($request); my $response = $client->wait_for_next_response; # Expected: "200 - OK" # # With the 'Cookie' header set the response is "400 - Bad Request". # # =============== # # And when the cookie is not set (try commenting out the line where it's set): # # The request is redirected to 'https://www.facebook.com' # # Without the _make_url_absolute() patch the address is being rewritten to # 'http://https://www.facebook.com' (illegal) and the final response is # "503 - Service Unavailable" print $response->code, " - ", $response->message, "\n";