sub
new {
my
(
$class
,
$port
) =
@_
;
if
(!
$port
) {
$port
= Net::EmptyPort::empty_port();
}
if
(!
$port
) {
die
"Missing positional parameter 'port' required"
;
}
return
$class
->SUPER::new(
$port
);
}
sub
handle_request {
my
(
$self
,
$cgi
) =
@_
;
my
$params
=
$cgi
->Vars;
return
act_as_proxy(
@_
)
if
$self
->{is_proxy};
my
$request_uri
=
$ENV
{REQUEST_URI};
if
(
$request_uri
!~ m!^/! ) {
warn
"ERROR - not absolute request_uri '$request_uri'"
;
return
;
}
$self
->stdout_handle->autoflush(1);
if
(
exists
$params
->{redirect} ) {
my
$num
=
$params
->{redirect} || 0;
$num
--;
if
(
$num
> 0 ) {
print
$cgi
->redirect(
-uri
=>
"?redirect=$num"
,
-nph
=> 1, );
print
"You are being redirected..."
;
}
else
{
print
$cgi
->header(
-nph
=> 1 );
print
"No longer redirecting"
;
}
}
elsif
(
exists
$params
->{delay} ) {
sleep
(
$params
->{delay} );
print
$cgi
->header(
-nph
=> 1 );
print
"Delayed for '$params->{delay}'.\n"
;
}
elsif
(
exists
$params
->{trickle} ) {
print
$cgi
->header(
-nph
=> 1 );
my
$trickle_for
=
$params
->{trickle};
my
$finish_at
=
time
+
$trickle_for
;
local
$| = 1;
while
(
time
<=
$finish_at
) {
print
time
.
" trickle $$\n"
;
sleep
0.1;
}
print
"Trickled for '$trickle_for'.\n"
;
}
elsif
(
exists
$params
->{cookie} ) {
print
$cgi
->header(
-nph
=> 1,
-cookie
=>
$cgi
->cookie(
-name
=>
"x"
,
value
=>
"test"
),
);
print
"Sent test cookie\n"
;
}
elsif
(
exists
$params
->{bad_header} ) {
my
$headers
=
$cgi
->header(
-nph
=> 1, );
$headers
=~ s{ \s* \z }{\n}xms;
$headers
.=
"Bad header: BANG!\n"
;
print
$headers
.
"\n\n"
;
print
"Produced some bad headers."
;
}
elsif
(
my
$when
=
$params
->{break_connection} ) {
for
(1) {
last
if
$when
eq
'before_headers'
;
print
$cgi
->header(
-nph
=> 1 );
last
if
$when
eq
'before_content'
;
print
"content\n"
;
}
}
elsif
(
my
$id
=
$params
->{set_time} ) {
my
$now
=
time
;
print
$cgi
->header(
-nph
=> 1 );
print
"$id\n$now\n"
;
}
elsif
(
exists
$params
->{not_modified} ) {
my
$last_modified
= HTTP::Date::time2str(
time
- 60 * 60 * 24 );
print
$cgi
->header(
-status
=>
'304'
,
-nph
=> 1,
'Last-Modified'
=>
$last_modified
,
);
print
"content\n"
;
}
else
{
warn
"DON'T KNOW WHAT TO DO: "
. Dumper
$params
;
}
}
sub
act_as_proxy {
my
(
$self
,
$cgi
) =
@_
;
my
$request_uri
=
$ENV
{REQUEST_URI};
if
(
$request_uri
!~ m!^https?://! ) {
warn
"ERROR - not fully qualified request_uri '$request_uri'"
;
return
;
}
my
$response
= LWP::UserAgent->new(
max_redirect
=> 0 )->get(
$request_uri
);
$response
->header(
WasProxied
=>
'yes'
);
print
$response
->as_string;
return
1;
}
sub
parse_request {
my
$self
=
shift
;
my
$chunk
;
while
(
sysread
( STDIN,
my
$buff
, 1 ) ) {
last
if
$buff
eq
"\n"
;
$chunk
.=
$buff
;
}
defined
(
$chunk
) or
return
;
$_
=
$chunk
;
m/^(\w+)\s+(\S+)(?:\s+(\S+))?\r?$/;
my
$method
= $1 ||
''
;
my
$uri
= $2 ||
''
;
my
$protocol
= $3 ||
''
;
return
(
$method
,
$uri
,
$protocol
);
}
sub
print_banner {
my
$self
=
shift
;
note(
ref
(
$self
)
.
": You can connect to your server at "
.
$self
->port
.
"/"
);
}
1;