#!/usr/bin/perl use warnings; use strict; use POE; use POE::Component::Server::TCP; use POE::Component::Client::HTTP; use POE::Filter::HTTPD; use HTTP::Response; use Data::Dumper; use IO::All; use DB::DBI; use Time::HiRes; # use CGI; use CGI::Session; sub DUMP_REQUESTS () { 0 } sub DUMP_RESPONSES () { 0 } sub LISTEN_PORT () { 8088 } ### Spawn a web client to fetch requests through. POE::Component::Client::HTTP->spawn( Alias => 'ua' ); ### Spawn a web server. # The ClientInput function is called to deal with client input. # ClientInput's callback function will receive entire HTTP requests # because this server uses POE::Filter::HTTPD to parse its input. # # InlineStates let us attach our own events and handlers to a TCP # server. Here we attach a handler for the got_response event, which # will be sent to us by Client::HTTP when it has fetched something. POE::Component::Server::TCP->new ( Alias => "web_server", Port => LISTEN_PORT, ClientFilter => 'POE::Filter::HTTPD', ClientInput => \&handle_http_request, InlineStates => { got_response => \&handle_http_response, }, ); ### Run the proxy until it is done, then exit. print "http proxy started on localhost:".&LISTEN_PORT." [OK]\n"; POE::Kernel->run(); exit 0; ### Handle HTTP requests from the client. Pass them to the HTTP ### client component for further processing. Optionally dump the ### request as text to STDOUT. sub handle_http_request { my ( $kernel, $heap, $request ) = @_[ KERNEL, HEAP, ARG0 ]; # print Data::Dumper::Dumper ($request); # If the request is really a HTTP::Response, then it indicates a # problem parsing the client's request. Send the response back so # the client knows what's happened. if ( $request->isa("HTTP::Response") ) { $heap->{client}->put($request); $kernel->yield("shutdown"); return; } my $tmp_str=$request->as_string(); #print $tmp_str; $tmp_str=~/CARMEN_SID=(\w+)/; $request->{_sid}=$1; $request->{_cgi_session} = new CGI::Session(undef, $request->{_sid}, {Directory=>'/tmp'}); $request->{_sid} = $request->{_cgi_session}->id; $request->{Time_HiRes_gettimeofday} = [Time::HiRes::gettimeofday]; $request->{Time_HiRes_time} = Time::HiRes::time(); # Client::HTTP doesn't support keep-alives yet. $request->header( "Connection", "close" ); $request->header( "Proxy-Connection", "close" ); $request->remove_header("Keep-Alive"); $kernel->post( "ua" => "request", "got_response", $request ); } ### Handle HTTP responses from the POE::Component::Client::HTTP we've ### spawned at the beginning of the program. Send each response back ### to the client that requested it. Optionally display the response ### as text. sub handle_http_response { my ( $kernel, $heap ) = @_[ KERNEL, HEAP ]; my $http_response = $_[ARG1]->[0]; $http_response->push_header( Set_Cookie => 'CARMEN_SID='.$http_response->{_request}->{_sid} ); my $response_type = $http_response->content_type(); if ( $response_type =~ /^text/i ) { $http_response->as_string() if DUMP_RESPONSES; } else { print "Response wasn't text.\n" if DUMP_RESPONSES; } my $obj_http_response = DB::http_response->create({ http_response => Data::Dumper::Dumper ($http_response), time_request => $http_response->{_request}->{Time_HiRes_time}, time_http_response => Time::HiRes::time(), time_interval => Time::HiRes::tv_interval ( $http_response->{_request}->{Time_HiRes_gettimeofday}, [Time::HiRes::gettimeofday]), sid => $http_response->{_request}->{_sid}, uri => $http_response->request->uri }); $obj_http_response->update(); # Avoid sending the response if the client has gone away. $heap->{client}->put($http_response) if defined $heap->{client}; # Shut down the client's connection when the response is sent. $kernel->yield("shutdown"); }