Better way to proxy an HTTP request using Perl HTTP::Response and LWP? -


i need perl cgi script fetches url , returns result of fetch - status, headers , content - unaltered cgi environment "proxied" url returned web server user's browser if they'd accessed url directly.

i'm running script cgi-bin in apache web server on ubuntu 14.04 host, question should independent of server platform - can run perl cgi scripts should able it.

i've tried using lwp::useragent::request() , i've got close. returns http::response object contains status code, headers , content, , has "as_string" method turns human-readable form. problem cgi perspective "as string" converts status code "http/1.1 200 ok" rather "status: 200 ok", apache server doesn't recognise output valid cgi response.

i can fix using other methods in http::response split out various parts, there seems no public way of getting @ encapsulated http::headers object in order call as_string method; instead have hack perl blessed object hash , yank out private "_headers" member directly. me seems evil, there better way?

here's code illustrate above. if put in cgi-bin directory can call as

http://localhost/cgi-bin/lwp-test?url=http://localhost/&http-response=1&show=1

you can use different url testing if want. if set http-response=0 (or drop param altogether) working piece-by-piece solution. if set show=0 (or drop it) proxied request returned script. apache return proxied page if have http-response=0 , choke 500 internal server error if it's 1.

#!/usr/bin/perl  use strict; use warnings;  use cgi::simple; use http::request; use http::response; use lwp::useragent;  $q = cgi::simple->new(); $ua = lwp::useragent->new(); $req = http::request->new(get => $q->param('url')); $res = $ua->request($req);  # print text/plain header if called "show=1" in query string # proxied url response shown in browser, otherwise output # proxied response if ours. if ($q->param('show')) {     print $q->header("text/plain");     print "\n"; }  if ($q->param('http-response')) {     # prints status "http/1.1 200 ok", not "status: 200 ok".     print $res->as_string; } else {     # works correctly proxy, using {_headers} @     # private encapsulated http:response object seems bit evil.     # there must better way!     print "status: ", $res->status_line, "\n";     print $res->{_headers}->as_string;     print "\n";     print $res->content; } 

please bear in mind script written purely demonstrate how forward http::response object cgi environment , bears no resemblance actual application.

you can go around internals of response object @ $res->{_headers} using $res->headers method, returns actual http::headers instance used. http::response inherits http::message.

it this:

print "status: ", $res->status_line, "\n"; print $res->headers->as_string; 

that looks less evil, though it's still not pretty.


Comments

Popular posts from this blog

ruby - Trying to change last to "x"s to 23 -

jquery - Clone last and append item to closest class -

c - Unrecognised emulation mode: elf_i386 on MinGW32 -