File Coverage

blib/lib/Plack/App/PubSubHubbub/Subscriber/Client.pm
Criterion Covered Total %
statement 54 74 72.9
branch 5 18 27.7
condition 0 3 0.0
subroutine 13 16 81.2
pod 7 7 100.0
total 79 118 66.9


line stmt bran cond sub pod time code
1             package Plack::App::PubSubHubbub::Subscriber::Client;
2 2     2   32903 use strict;
  2         8  
  2         74  
3 2     2   13 use warnings;
  2         6  
  2         59  
4              
5 2     2   12 use URI;
  2         4  
  2         53  
6 2     2   1976 use HTTP::Request;
  2         23947  
  2         80  
7 2     2   7044 use HTTP::Response;
  2         34215  
  2         83  
8 2     2   2464 use LWP::UserAgent;
  2         42048  
  2         78  
9              
10 2     2   48 use Plack::App::PubSubHubbub::Subscriber::Client;
  2         4  
  2         1800  
11              
12             =head1 NAME
13              
14             Plack::App::PubSubHubbub::Subscriber::Client
15              
16             =head1 SYNOPSIS
17              
18             my $client = Plack::App::PubSubHubbub::Subscriber::Client(
19             config => $conf,
20             );
21              
22             my $result = $client->subscribe( $hub, $topic, $token );
23             ...
24              
25             =head2 $class->new( config => $conf )
26              
27             Take a L object as parmeter,
28             ideally the same config used for the Plack App.
29              
30             =cut
31              
32             sub new {
33 1     1 1 15 my $class = shift;
34 1         4 my %args = @_;
35 1         5 my $self = bless {}, $class;
36 1 50       9 $self->{config} = $args{config}
37             or die "config required";
38 1         4 return $self;
39             }
40              
41 19     19 1 2955 sub config { $_[0]->{config} }
42              
43             =head2 $self->ua( $user_agent )
44              
45             Can be used to set the user agent, by default return an L object.
46              
47             =cut
48              
49             sub ua {
50 0     0 1 0 my $self = shift;
51 0         0 my ($ua) = @_;
52 0 0       0 $self->{__ua} = $ua if $ua;
53 0   0     0 $self->{__ua} ||= LWP::UserAgent->new;
54 0         0 return $self->{__ua};
55             }
56              
57             sub _inject_token {
58 7     7   4642 my ($url, $token) = @_;
59 7         22 $url = URI->new($url);
60 7         455 my $path = $url->path;
61 7         82 $path =~ s/\/$//;
62 7         26 $url->path($path.'/'.$token);
63 7         246 return $url->as_string;
64             }
65              
66             sub _request {
67 4     4   8 my $self = shift;
68 4         9 my ($hub, $feed, $token, $mode) = @_;
69              
70 4         32 my %params = (
71             "hub.callback" => $self->config->callback,
72             "hub.mode" => $mode,
73             "hub.topic" => $feed,
74             "hub.verify" => $self->config->verify,
75             );
76              
77 4 50       13 if (defined $self->config->lease_seconds) {
78 0         0 $params{"hub.lease_seconds"} = $self->config->lease_seconds;
79             }
80              
81 4 50       11 if ($token) {
82 4 100       8 if ($self->config->token_in_path) {
83             # overwrite the callback
84 2         6 $params{"hub.callback"} = _inject_token($self->config->callback, $token);
85             }
86             else {
87 2         4 $params{"hub.verify_token"} = $token;
88             }
89             }
90              
91 4         26 my $url = URI->new('http:');
92 4         203 $url->query_form(%params);
93 4         869 my $content = $url->query;
94              
95 4         59 my $req = HTTP::Request->new(POST => $hub, );
96 4         434 $req->content_type('application/x-www-form-urlencoded');
97 4         116 $req->content($content);
98 4         86 return $req;
99             }
100              
101             =head2 $self->subscribe_request( $hub, $feed, $token )
102              
103             Prepare and return the subscribe request (L object)
104             Note that it does not run the request, this is useful
105             if you want to run the request yourself, in an event
106             loop client for example.
107              
108             =cut
109              
110             sub subscribe_request {
111 2     2 1 1261 my $self = shift;
112 2         6 my ($hub, $feed, $token) = @_;
113 2         8 return $self->_request($hub, $feed, $token, 'subscribe');
114             }
115              
116             =head2 $self->subscribe( $hub, $feed, $token )
117              
118             Build the request using 'subscribe_request' and run it.
119             Return { success => 'verified' } if the subscription is active.
120             Return { success => 'tobeverified' } in case of async verification.
121             Return { error => $msg } in case of error.
122              
123             =cut
124              
125             sub subscribe {
126 0     0 1 0 my $self = shift;
127 0         0 my $req = $self->subscribe_request(@_);
128 0         0 my $res = $self->ua->request($req);
129 0 0       0 if ($res->code == 204) {
    0          
130 0         0 return { success => 'verified' };
131             }
132             elsif ($res->code == 202) {
133 0         0 return { success => 'tobeverified' };
134             }
135             else {
136 0         0 return { success => '', error => $res->content };
137             }
138             }
139              
140             =head2 $self->unsubscribe_request( $hub, $feed, $token )
141              
142             Same as subscribe_request but for unsubscribe.
143              
144             =cut
145              
146             sub unsubscribe_request {
147 2     2 1 5127 my $self = shift;
148 2         5 my ($hub, $feed, $token) = @_;
149 2         7 return $self->_request($hub, $feed, $token, 'unsubscribe');
150             }
151              
152             =head2 $self->unsubscribe( $hub, $feed, $token )
153              
154             Same as subscribe but for unsubscribe.
155              
156             =cut
157              
158             sub unsubscribe {
159 0     0 1   my $self = shift;
160 0           my $req = $self->unsubscribe_request(@_);
161 0           my $res = $self->ua->request($req);
162 0 0         if ($res->code == 204) {
    0          
163 0           return { success => 'verified' };
164             }
165             elsif ($res->code == 202) {
166 0           return { success => 'tobeverified' };
167             }
168             else {
169 0           return { success => '', error => $res->content };
170             }
171             }
172              
173             1;