App-cdnget

 view release on metacpan or  search on metacpan

lib/App/cdnget/Downloader.pm  view on Meta::CPAN

sub processHook
{
	my $self = shift;
	my ($response) = @_;
	my @params = split /\s+/, $self->hook;
	my $hook = shift @params;
	return unless defined($hook);
	given ($hook)
	{
		when (/^img/i)
		{
			return $self->processHook_img($hook, $response, @params);
		}
		when (/^css/i)
		{
			return $self->processHook_css($hook, $response, @params);
		}
		when (/^js/i)
		{
			return $self->processHook_js($hook, $response, @params);
		}
		default
		{
			$self->throw("Unsupported hook");
		}
	}
	return;
}

sub run
{
	my $self = shift;
	my $tid = threads->tid();

	my $fh;
	eval
	{
		$fh = FileHandle->new($self->path, ">") or $self->throw($!);
	};
	if ($@)
	{
		lock($self);
		cond_signal($self);
		return $@;
	}

	$self->tid = $tid;
	do
	{
		lock($self);
		cond_signal($self);
	};

	eval
	{
		my $max_size = undef;
		if ($self->hook)
		{
			$max_size = 20*1024*1024;
		}
		$fh->binmode(":bytes") or $self->throw($!);
		my $ua = LWP::UserAgent->new(agent => "p5-cdnget/${App::cdnget::VERSION}",
			max_redirect => 1,
			max_size => $max_size,
			requests_redirectable => [],
			timeout => 5);
		my $response_header = sub
			{
				my ($response, $ua) = @_;
				local ($/, $\) = ("\r\n")x2;
				my $status = $response->{_rc};
				my $headers = $response->{_headers};
				$fh->print("Status: ".$status) or $self->throw($!);
				$fh->print("Client-URL: ".$self->url) or $self->throw($!);
				$fh->print("Client-Date: ".POSIX::strftime($App::cdnget::DTF_RFC822_GMT, gmtime)) or $self->throw($!);
				for my $header (sort grep /^(Content\-|Location\:)/i, $headers->header_field_names())
				{
					$fh->print("$header: ", $headers->header($header)) or $self->throw($!);
				}
				$fh->print("") or $self->throw($!);
				return 1;
			};
		my $content_cb = sub
			{
				my ($data, $response) = @_;
				$fh->write($data, length($data)) or $self->throw($!);
				$self->throw("Terminating") if $self->terminating;
				return 1;
			};
		my %matchspec = (':read_size_hint' => $App::cdnget::CHUNK_SIZE);
		unless ($self->hook)
		{
			$ua->add_handler(
				response_header => $response_header,
			);
			$matchspec{':content_cb'} = $content_cb;
		}
		my $response = $ua->get($self->url, %matchspec);
		die $response->header("X-Died")."\n" if $response->header("X-Died");
		$self->throw("Download failed") if $response->header("Client-Aborted");
		unless ($self->hook)
		{
			unless ($response->is_success)
			{
				$content_cb->($response->decoded_content, $response);
			}
		} else
		{
			if ($response->is_success)
			{
				my ($header, $data) = $self->processHook($response);
				if ($header)
				{
					$header .= "Client-URL: ".$self->url."\r\n";
					$header .= "Client-Hook: ".$self->hook."\r\n";
					$header .= "Client-Date: ".POSIX::strftime($App::cdnget::DTF_RFC822_GMT, gmtime)."\r\n";
					$data = "" unless defined($data);
					$fh->print($header."\r\n".$data) or $self->throw($!);
				}
			} else
			{



( run in 1.917 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )