view release on metacpan or search on metacpan
dev/xml-test.pl view on Meta::CPAN
#
# usage:
# xml-test.pl (automatic mode)
# xml-test.pl libxml
# xml-test.pl expat
use strict;
use warnings;
use XML::SAX;
use XML::SAX::ParserFactory;
use Scalar::Util qw(weaken);
use Test::More tests => 11;
use Data::Dumper;
my $mode = shift;
my $factory = XML::SAX::ParserFactory->new;
my $wanted = ""; # set to nothing to let the factory choose a parser
my $iter_method;
if ($mode eq "") {
dev/xml-test.pl view on Meta::CPAN
{
my $handler = EventRecorder->new(\$full_events);
my $p = $factory->parser(Handler => $handler);
if ($wanted) {
isa_ok($p, $wanted);
} else {
ok(1);
}
$p->parse_string($fulldoc);
$weakcheck = \$p;
weaken($weakcheck);
$weakcheck_h = \$handler;
weaken($weakcheck_h);
like($full_events, qr/\{aa\}name/, "parser supports namespaces properly");
like($full_events, qr/\{bb\}name/, "parser supports namespaces properly");
like($full_events, qr/\{\}global/, "parser supports namespaces properly");
}
is($weakcheck, undef, "parser was destroyed");
is($weakcheck_h, undef, "handler was destroyed");
# now we do the way we want, sending chunks:
my $streamed_events;
{
my $handler = EventRecorder->new(\$streamed_events);
my $p = $factory->parser(Handler => $handler);
$p->$iter_method($first_chunk);
$p->$iter_method($second_chunk);
$weakcheck = \$p;
weaken($weakcheck);
}
is($weakcheck, undef, "parser was destroyed");
use Text::Diff;
my $diff = diff(\$full_events, \$streamed_events);
#$diff = substr($diff, 0, 200);
is($diff, "", "events match either way");
# byte at a time
dev/xml-test.pl view on Meta::CPAN
package XML::LibXML::SAX::Better;
use strict;
use vars qw($VERSION @ISA);
$VERSION = '1.00';
use XML::LibXML;
use XML::SAX::Base;
use base qw(XML::SAX::Base);
use Carp;
use Data::Dumper;
use Scalar::Util qw(weaken);
sub new {
my ($class, @params) = @_;
my $inst = $class->SUPER::new(@params);
my $libxml = XML::LibXML->new;
$libxml->set_handler( $inst );
$inst->{LibParser} = $libxml;
# setup SAX. 1 means "with SAX"
lib/DJabberd.pm view on Meta::CPAN
# if they set s2s_port to explicitly 0, it's disabled for all vhosts
# but not setting it means 5269 still listens, if vhosts are configured
# for s2s.
# {=serverportnumber}
$self->{s2s_port} = 5269 unless defined $self->{s2s_port};
croak("Unknown server parameters: " . join(", ", keys %opts)) if %opts;
bless $self, $class;
$server{$self} = $self;
Scalar::Util::weaken($server{$self});
return $self;
}
sub DESTROY {
delete $server{$_[0]};
}
# class method
sub foreach_vhost {
lib/DJabberd.pm view on Meta::CPAN
# return the version of the spec we implement
sub spec_version {
my $self = shift;
return $self->{_spec_version} ||= DJabberd::StreamVersion->new("1.0");
}
my %obj_source; # refaddr -> file/linenumber
my %obj_living; # file/linenumber -> ct
use Scalar::Util qw(refaddr weaken);
use Data::Dumper;
sub dump_obj_stats {
print Dumper(\%obj_living);
my %class_ct;
foreach (values %obj_source) {
$class_ct{ref($_->[1])}++;
}
print Dumper(\%class_ct);
}
lib/DJabberd.pm view on Meta::CPAN
my $fileline;
while (!$fileline) {
$i++;
my ($pkg, $filename, $line, $subname) = caller($i);
next if $subname eq "new";
$fileline = "$filename/$line";
}
my $addr = refaddr($obj);
warn "New object $obj -- $fileline\n" if $ENV{TRACKOBJ};
$obj_source{$addr} = [$fileline, $obj];
weaken($obj_source{$addr}[1]);
$obj_living{$fileline}++;
dump_obj_stats() if $ENV{TRACKOBJ};
}
sub track_destroyed_obj {
return unless $ENV{TRACKOBJ};
my ($class, $obj) = @_;
my $addr = refaddr($obj);
lib/DJabberd/Bot.pm view on Meta::CPAN
sub vhost {
return $_[0]->{vhost};
}
sub register {
my ($self, $vhost) = @_;
my $barejid = DJabberd::JID->new("$self->{nodename}\@" . $vhost->server_name );
my $resource = $self->{resource};
$self->{vhost} = $vhost;
Scalar::Util::weaken($self->{vhost});
my $reg_jid;
my $regcb = DJabberd::Callback->new({
registered => sub {
(undef, $reg_jid) = @_;
$logger->debug("Bot $reg_jid is now registered");
},
error => sub {
$logger->error("Bot $barejid/$resource failed to register");
},
lib/DJabberd/Connection.pm view on Meta::CPAN
sub new {
my ($class, $sock, $server) = @_;
my $self = $class->SUPER::new($sock);
croak("Server param not a DJabberd (server) object, '" . ref($server) . "'")
unless $server->isa("DJabberd");
$self->{vhost} = undef; # set once we get a stream start header from them.
$self->{server} = $server;
Scalar::Util::weaken($self->{server});
$self->{log} = DJabberd::Log->get_logger($class);
# hack to inject XML after Connection:: in the logger category
my $xml_category = $class;
$xml_category =~ s/Connection::/Connection::XML::/;
$self->{xmllog} = DJabberd::Log->get_logger($xml_category);
my $fromip = $self->peer_ip_string || "<undef>";
lib/DJabberd/Connection.pm view on Meta::CPAN
}
# this can fail to signal that this connection can't work on this
# vhost for instance, this vhost doesn't support s2s, so a serverin or
# dialback subclass can override this to return 0 when s2s isn't
# enabled for the vhost
sub set_vhost {
my ($self, $vhost) = @_;
Carp::croak("Not a DJabberd::VHost: $vhost") unless UNIVERSAL::isa($vhost, "DJabberd::VHost");
$self->{vhost} = $vhost;
Scalar::Util::weaken($self->{vhost});
return 1;
}
# called by DJabberd::SAXHandler
sub on_stanza_received {
my ($self, $node) = @_;
die "SUBCLASSES MUST OVERRIDE 'on_stanza_received' for $self\n";
}
# subclasses should override returning 0 or 1
lib/DJabberd/Connection/ComponentIn.pm view on Meta::CPAN
sub new {
my ($class, $socket, $server, $handler) = @_;
$logger->debug("Making a $class for fd ".fileno($socket));
my $self = $class->SUPER::new($socket, $server);
$self->{authenticated} = 0;
$self->{cmpnt_handler} = $handler;
Scalar::Util::weaken($self->{cmpnt_handler});
return $self;
}
sub close {
my $self = shift;
return if $self->{closed};
$self->{cmpnt_handler}->handle_component_disconnect($self);
lib/DJabberd/Connection/ComponentOut.pm view on Meta::CPAN
my $self = $class->SUPER::new($sock, $server);
$self->watch_write(1);
$self->set_vhost($vhost);
$self->{secret} = $secret;
$self->{authenticated} = 0;
$self->{state} = 'connecting';
#$self->{cmpnt_handler} = $handler;
#Scalar::Util::weaken($self->{cmpnt_handler});
$logger->debug("$class initialized");
return $self;
}
sub on_connected {
my ($self) = @_;
my $vhost = $self->{vhost};
lib/DJabberd/Connection/DialbackVerify.pm view on Meta::CPAN
connect $sock, Socket::sockaddr_in($port, Socket::inet_aton($fromip));
$DJabberd::Stats::counter{connect}++;
my $self = $class->SUPER::new($sock, $server);
$self->{db_result} = $db_result;
$self->{final_cb} = $final_cb;
$self->{state} = "connecting";
$self->{conn} = $conn;
Scalar::Util::weaken($self->{conn});
$self->watch_write(1);
}
sub event_write {
my $self = shift;
if ($self->{state} eq "connecting") {
$self->{state} = "connected";
$self->log->debug("$self->{id} connected for DialbackResult " . $self->{db_result}->orig_server);
lib/DJabberd/Connection/ServerOut.pm view on Meta::CPAN
$ip = $endpt->addr;
connect $sock, Socket::sockaddr_in($endpt->port, Socket::inet_aton($ip));
$DJabberd::Stats::counter{connect}++;
my $self = $class->SUPER::new($sock, $queue->vhost->server);
$self->log->debug("Connecting to '$ip' for '$queue->{domain}'");
$self->{state} = "connecting";
$self->{queue} = $queue;
$self->{vhost} = $queue->vhost;
Scalar::Util::weaken($self->{queue});
return $self;
}
sub namespace {
return "jabber:server";
}
sub start_connecting {
my $self = shift;
lib/DJabberd/Connection/SimpleIn.pm view on Meta::CPAN
my ($cmd, $rest) = ($1, $2);
if ($cmd eq "set_vhost") {
my $vhostname = $rest;
my $vhost = $self->server->lookup_vhost($vhostname);
unless ($vhost) {
$self->write("ERROR no vhost '$vhostname'\n");
return;
}
$self->{vhost} = $vhost;
Scalar::Util::weaken($self->{vhost});
$self->write("OK\n");
return;
}
if ($cmd eq "send_xml") {
my ($to, $enc_xml) = split(/\s+/, $rest);
my $xml = durl($enc_xml);
warn "SIMPLE: sending to '$to', the XML '$xml'\n";
my $vhost = $self->vhost;
lib/DJabberd/Delivery.pm view on Meta::CPAN
}
sub vhost {
return $_[0]->{vhost};
}
sub set_vhost {
my ($self, $vhost) = @_;
Carp::croak("Not a vhost: '$vhost'") unless UNIVERSAL::isa($vhost, "DJabberd::VHost");
$self->{vhost} = $vhost;
Scalar::Util::weaken($self->{vhost});
}
1;
lib/DJabberd/PresenceChecker.pm view on Meta::CPAN
my ($class) = @_;
return bless {}, $class;
}
sub vhost { $_[0]->{vhost} }
sub register {
my ($self, $vhost) = @_;
$self->{vhost} = $vhost;
Scalar::Util::weaken($self->{vhost});
# this is an odd hook, in that it wants to be called a lot, but the
# normal hook chain system doesn't support that, so instead
# this provides a cleaner interface for subclasses, which just call
# 'add' and 'done', and this takes care of the ugliness of calling
# the $add_cb callback.
$vhost->register_hook("PresenceCheck", sub {
my (undef, $cb, $jid, $add_cb) = @_;
# cb can 'decline' only
lib/DJabberd/SAXHandler.pm view on Meta::CPAN
package DJabberd::SAXHandler;
use strict;
use base qw(XML::SAX::Base);
use DJabberd::XMLElement;
use DJabberd::StreamStart;
use Scalar::Util qw(weaken);
use Time::HiRes ();
sub new {
my ($class, $conn) = @_;
my $self = $class->SUPER::new;
if ($conn) {
$self->{"ds_conn"} = $conn;
weaken($self->{ds_conn});
}
$self->{"capture_depth"} = 0; # on transition from 1 to 0, stop capturing
$self->{"on_end_capture"} = undef; # undef or $subref->($doc)
$self->{"events"} = []; # capturing events
return $self;
}
sub set_connection {
my ($self, $conn) = @_;
$self->{ds_conn} = $conn;
if ($conn) {
weaken($self->{ds_conn});
} else {
# when sax handler is being put back onto the freelist...
$self->{on_end_capture} = undef;
}
}
# called when somebody is about to destroy their reference to us, to make
# us clean up.
sub cleanup {
my $self = shift;
lib/DJabberd/SAXHandler.pm view on Meta::CPAN
$self->{capture_depth}++;
return;
}
# start capturing...
$self->{"events"} = [
[EVT_START_ELEMENT, $data],
];
$self->{capture_depth} = 1;
Scalar::Util::weaken($conn);
$self->{on_end_capture} = sub {
my ($doc, $events) = @_;
my $nodes = _nodes_from_events($events);
# {=xml-stanza}
my $t1 = Time::HiRes::time();
$conn->on_stanza_received($nodes->[0]) if $conn;
my $td = Time::HiRes::time() - $t1;
# ring buffers for latency stats:
if ($td > $DJabberd::Stats::latency_log_threshold) {
lib/DJabberd/Stanza.pm view on Meta::CPAN
);
sub downbless {
my $class = shift;
if (ref $_[0]) {
my ($self, $conn) = @_;
my $new = fields::new($class);
%$new = %$self; # copy fields
if ($conn) {
$new->{connection} = $conn;
Scalar::Util::weaken($new->{connection});
}
return $new;
} else {
croak("Bogus use of downbless.");
}
}
sub as_summary {
my $self = shift;
lib/DJabberd/VHost.pm view on Meta::CPAN
}
sub server {
my $self = shift;
return $self->{server};
}
sub set_server {
my ($self, $server) = @_;
$self->{server} = $server;
Scalar::Util::weaken($self->{server});
}
sub run_hook_chain {
my $self = shift;
my %opts = @_;
my ($phase, $methods, $args, $fallback, $hook_inv)
= @opts{qw(phase methods args fallback hook_invocant)};
if (0) {
lib/DJabberd/XMLParser.pm view on Meta::CPAN
# my ($sys_id, $pub_id) = @_;
# warn "Received external entity: $sys_id:$pub_id";
"";
},
});
$libxml->set_handler($self);
$self->{LibParser} = $libxml;
# this buys nothing but less noise when using Devel::Cycle:
# make it a developer option?
# Scalar::Util::weaken($self->{LibParser});
$libxml->init_push;
$self->{CONTEXT} = $libxml->{CONTEXT};
}
# expat mode:
if (0) {
#use XML::SAX::Expat::Incremental;
my $parser = XML::SAX::Expat::Incremental->new(Handler => $self);
$self->{expat} = $parser;
t/hookchain.t view on Meta::CPAN
# -*-perl-*-
use strict;
use Test::More tests => 4;
use Scalar::Util qw(weaken);
use lib 't/lib';
require 'djabberd-test.pl';
my $server = DJabberd->new;
my $local = DJabberd::Delivery::Local->new();
my $vhost = DJabberd::VHost->new(server_name => "foo");
$vhost->add_plugin($local);
$server->add_vhost($vhost);
DJabberd::HookDocs->allow_hook("Foo");
t/hookchain.t view on Meta::CPAN
$vhost->register_hook("Foo", sub {
my ($srv, $cb, @args) = @_;
$cb->baz;
});
# testing an object in the args being destroyed
{
my $obj = {};
$track_obj = \$obj;
weaken($track_obj);
$vhost->run_hook_chain(phase => "Foo",
args => [ $obj, "arg2", "arg3" ],
methods => {
bar => sub {
$outside = "bar!\n";
},
baz => sub {
$outside = "baz!\n";
},
t/hookchain.t view on Meta::CPAN
fallback => sub {
print "fallback.\n";
});
}
is($track_obj, undef, "ref in args destroyed");
# testing an object in the callbacks being destroyed
{
my $obj = {};
$track_obj = \$obj;
weaken($track_obj);
$vhost->run_hook_chain(phase => "Foo",
args => [ "arg1", "arg2" ],
methods => {
bar => sub {
$outside = "bar $obj!\n";
},
baz => sub {
$outside = "baz $obj!\n";
},
t/hookchain.t view on Meta::CPAN
fallback => sub {
print "fallback.\n";
});
}
is($track_obj, undef, "ref in callbacks destroyed");
# testing an object in the fallback being destroyed
{
my $obj = {};
$track_obj = \$obj;
weaken($track_obj);
$vhost->run_hook_chain(phase => "Foo",
args => [ "arg1", "arg2" ],
methods => {
bar => sub {
print "bar!\n";
},
baz => sub {
$outside = "baz!\n";
},
t/hookchain.t view on Meta::CPAN
fallback => sub {
$outside = "fallback $obj.\n";
});
}
is($track_obj, undef, "ref in fallback destroyed");
# testing an object in the fallback being destroyed, when we execute the fallback
{
my $obj = {};
$track_obj = \$obj;
weaken($track_obj);
$vhost->run_hook_chain(phase => "Nothing",
args => [ "arg1", "arg2" ],
methods => {
bar => sub {
print "bar!\n";
},
baz => sub {
$outside = "baz!\n";
},
t/xmlparsing.t view on Meta::CPAN
#!/usr/bin/perl
use strict;
use warnings;
use XML::SAX;
use DJabberd::XMLParser;
use XML::SAX::PurePerl;
use Scalar::Util qw(weaken);
use Test::More tests => 14;
use Data::Dumper;
my $fulldoc = qq{<?xml version="1.0"?><root xmlns='root' xmlns:a='aa' global='foo' xmlns:b='bb' a:name='aname' b:name='bname' name='globalname'>
<a:tag />
<b:tag />
<tag />
</root>};
my $correct;
t/xmlparsing.t view on Meta::CPAN
my $dummy;
my $ref;
{
my $handler = EventRecorder->new(\$dummy);
my $p = DJabberd::XMLParser->new(Handler => $handler);
$p->finish_push;
ok(!$dummy);
$ref = \$p;
weaken($ref);
}
ok(!$ref, "p went away");
{
my $handler = EventRecorder->new(\$dummy);
my $p = DJabberd::XMLParser->new(Handler => $handler);
$p->parse_more("<foo><<tag>");
$p->finish_push;
like($dummy, qr/foo.+tag/s);
$ref = \$p;
weaken($ref);
}
ok(!$ref, "p went away");
## external entities are disabled
{
use FindBin;
my $v = "$FindBin::Bin/v.txt";
my $xml1 = <<"EOF";
<?xml version="1.0"?>