Skip to content

Instantly share code, notes, and snippets.

@augensalat
Last active August 29, 2015 14:23
Show Gist options
  • Save augensalat/53b164655b57deb993e1 to your computer and use it in GitHub Desktop.
Save augensalat/53b164655b57deb993e1 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
BEGIN {
$ENV{MOJO_REACTOR} = 'Mojo::Reactor::Poll';
}
use strict;
use warnings;
use Mojo::IOLoop;
use Mojo::UserAgent;
use Getopt::Std;
use Params::Util '_POSINT';
use Pod::Usage;
our $VERSION = '0.001_000';
$VERSION = eval $VERSION;
getopts('fhs:', \my %opts);
$opts{h} and pod2usage();
my $URL = shift || 'http://example.com/';
my $fin = $opts{f};
my $size = _POSINT($opts{s}) || 200_000;
# Build a normal transaction
my $ua = Mojo::UserAgent->new;
my $bcr = my $bcw = 0;
$ua->on(start => sub {
my ($ua, $tx) = @_;
$tx->on(connection => sub {
my ($tx, $connection) = @_;
my $s = Mojo::IOLoop->stream($connection);
$s->on(write => sub {
my $bc = length pop;
$bcw += $bc;
warn "++ Stream write event - $bc bytes written.\n";
});
$s->unsubscribe('read')->on(read => sub {
my ($s, $data) = @_;
my $bc = length $data;
$bcr += $bc;
warn "++ Stream read event - $bc bytes read.\n";
if ($bcr > $size) {
warn "++ Stream closing connection\n";
if ($fin) {
$s->handle->shutdown(2)
or warn "++ shutdown: $!";
}
$s->close;
}
});
$s->on(close => sub {
warn "++ Stream close event\n";
});
});
});
# Process transaction
$ua->get($URL, {Connection => 'close'} => sub {
my ($ua, $tx) = @_;
my $res = $tx->res;
my $size = $res->start_line_size + $res->header_size + $res->body_size;
my $finished = $tx->is_finished ? "true" : "false";
my $status = $res->code;
warn <<EOT;
++ DONE: $bcr bytes read, $bcw bytes written.
Response content size is $size bytes.
Tx is finished: $finished, HTTP status = $status.
EOT
});
Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
__END__
=head1 NAME
streamres.pl - Emulate an interrupted HTTP download
=head1 SYNOPSIS
streamres.pl [-f] [-s SIZE] URL
=head1 OPTIONS
=over 4
=item B<-h>
Print help text and exit.
=item B<-f>
Send a FIN packet at the end. By default the connection is closed
by sending an RST packet.
=item B<-s>
Minimum amount of data in bytes that is sent before the connection is
closed. Default is 200_000 bytes.
=back
=head1 DESCRIPTION
streamres.pl ...
=head1 EXAMPLES
$ streamres.pl -f -s 1000000 http://download.com/file/42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment