package Devel::hdb::Client;
use strict;
use warnings;
use LWP::UserAgent;
use JSON;
use Carp;
use Data::Dumper;
use URI::Escape qw();
use Data::Transform::ExplicitMetadata '0.02';
use Scalar::Util q
Exception::Error' => {
isa => 'Devel::hdb::Client::Exception',
},
);
my $JSON ||= JSON->new->utf8->allow_nonref();
sub new {
my $class = shift;
my %params = @_;
my %
$self->_GET($url);
_assert_success($response, q(Can't get stack position));
my $stack = $JSON->decode($response->content);
foreach my $frame ( @$stack ) {
$frame->{args} = _decode
tings) {
return [ 200,
['Content-Type' => 'application/json'],
[ $app->encode_json($settings) ] ];
} else {
return [ 404,
[ 'Content
$file) = @_;
my $body = $class->_read_request_body($env);
my $additional = $app->decode_json($body);
local $@;
$file = eval { $app->save_settings_to_file($file, $additional) };
config',
);
return [ 200,
[ 'Content-Type' => 'application/json' ],
[ $app->encode_json(\%data) ]
];
}
sub program_name {
my($class, $app, $env) = @_;
$PROGRAM_NAME;
return [200, ['Content-Type' => 'text/plain'],
[ $app->encode_json({ program_name => $PROGRAM_NAME }) ],
];
}
1;
=pod
=head1 NAME
Devel::hdb::App::Prog
me of the running program, $0
=head2 Routes
=over 4
=item GET /program_name
Returns 200 and a JSON-encoded hash with one key:
program_name => $0 when the program was started
=back
=head1 SEE A
ement
return [ 200,
[ 'Content-Type' => 'application/json' ],
[ $app->encode_json(\@rv) ]
];
} else {
return [ 404,
[ '
>loaded_files();
return [ 200,
[ 'Content-Type' => 'application/json' ],
[ $app->encode_json(\@files) ]
];
}
1;
=pod
=head1 NAME
Devel::hdb::App::SourceFile -
he files used by the debugger, and the file-like
entities for "eval"ed strings.
Returns 200 an a JSON-encoded array containing hashes with these keys:
filename => Pathname of the file
href =>
ge($package) };
return [ 200,
[ 'Content-Type' => 'application/json' ],
[ $app->encode_json({ name => $package, packages => \@sub_packages, subroutines => \@subs }) ]
keys;
return [ 200,
[ 'Content-Type' => 'application/json' ],
[ $app->encode_json(\%data) ],
];
} else {
return [ 404,
Get information about the named package, or 'main::' if no package is given.
Returns 200 and a JSON in the body:
{
name: String - package name
packages: [ // list of packages under this p
ata($app, $env);
return [ 200,
[ 'Content-Type' => 'application/json' ],
[ $app->encode_json($status) ] ];
}
sub _program_status_data {
my($class, $app, $env) = @_;
my $responder = shift;
my $writer = $responder->([ 200, [ 'Content-Type' => 'application/json' ]]);
$env->{'psgix.harakiri.commit'} = Plack::Util::TRUE;
my $cb = sub {
my $status = $class->_program_status_data($app, $env);
$writer->write( $app->encode_json($status) );
$writer->close();
};
$app->on_notify_stopped($cb);
};
$watchpoint_exprs{$expr} = undef;
return [ 201,
['Content-Type' => 'application/json'],
[ '{}' ], # JQuery requires _something_ in the response
];
}
sub delete
et_one($expr);
return [ 200,
['Content-Type' => 'application/json'],
[ $app->encode_json($wp_data) ],
];
} else {
return _not_found();
}
}
su
_) } keys(%watchpoint_exprs);
return [ 200, ['Content-Type' => 'application/json'],
[ JSON::encode_json( \@wp_list ) ]
];
}
sub Devel::hdb::App::notify_watch_expr {
my($a
$app, $env) = @_;
my $body = $class->_read_request_body($env);
my $params = $app->decode_json( $body );
if (my $error = $class->is_file_or_line_invalid($app, @$params{'filename','line'})
$app, $params);
return [ 200,
[ 'Content-Type' => 'application/json' ],
[ $app->encode_json($resp_data) ],
];
}
sub change {
my($class, $app, $env, $id) = @
_;
my $body = $class->_read_request_body($env);
my $params = $app->decode_json( $body );
foreach my $prop (qw( filename line )) {
if (exists($params->{$prop})) {
retu
0,
[ 'Content-Type' => 'application/json',
'X-Stack-Depth' => scalar(@$frames),
],
[ $app->encode_json($frames) ],
];
}
sub stack_head {
= @_;
my $stack = $app->stack;
return [ 200,
[ 'Content-Type' => 'application/json',
'X-Stack-Depth' => $stack->depth,
],
[],
];
}
s
($frame, $base_url, $level, $req->param('exclude_sub_params'));
$rv->[2] = [ $app->encode_json($serialized_frame) ];
}
return $rv;
}
sub stack_frame_head {
my($class, $app, $env,
;
my $json = $app->{json};
$app->user_requested_exit();
return sub {
my $responder = shift;
my $writer = $responder->([ 204, [ 'Content-Type' => 'application/json' ]]);
er
code Perl code string
inactive True if the breakpoint is inactive
Returns 200 and a JSON-encoded array containing hashes with these keys:
filename => File name
lineno => Line num
fy this action
=item POST /actions
Create an action. Action details must appear in the body as JSON hash
with these keys:
filename File name
line Line number
code Action code to ru
00 with the same JSON-encoded hash as GET /actions.
Returns 403 if the line is not breakable.
Returns 404 if the filename is not loaded.
=item GET /actions/<id>
Return the same JSON-encoded hash as
$app, $env) = @_;
my $body = $class->_read_request_body($env);
my $params = $app->decode_json($body);
my $eval_string = Devel::hdb::Utils::_fixup_expr_for_eval($params->{code});
retu
:encode($value);
return [ 200,
[ 'Content-Type' => 'application/json' ],
[ $app->encode_json($result) ]
];
}
sub _eval_plumbing_closure {
my($app, $env, $eval_
200,
[ 'Content-Type' => 'application/json' ],
[ $app->encode_json($result) ]]);
}
);
};
}
1;
=pod
=head1 NAM
use IO::File;
use LWP::UserAgent;
use Data::Dumper;
use Sys::Hostname;
use IO::Socket::INET;
use JSON qw();
use Data::Transform::ExplicitMetadata;
use Sub::Name qw(subname);
use Devel::hdb::Router;
ass;
$self->_make_json_encoder();
$self->_make_listen_socket();
$parent_pid = eval { getppid() } if ($Devel::hdb::TESTHARNESS);
return $self;
}
sub _make_json_encoder {
my $self
{json} = JSON->new->utf8->allow_nonref();
return $self;
}
sub encode_json {
my $self = shift;
my $json = $self->{json};
return map { $json->encode($_) } @_;
}
sub decode_json {
m