Release HTTP-AnyUA 0.901
[chaz/p5-HTTP-AnyUA] / lib / HTTP / AnyUA / Middleware.pm
1 package HTTP::AnyUA::Middleware;
2 # ABSTRACT: A base class for HTTP::AnyUA middleware
3
4 =head1 SYNOPSIS
5
6 package HTTP::AnyUA::Middleware::MyMiddleware;
7
8 use parent 'HTTP::AnyUA::Middleware';
9
10 sub request {
11 my ($self, $method, $url, $args) = @_;
12
13 # Maybe do something with the request args here.
14
15 # Let backend handle the response:
16 my $response = $self->backend($method, $url, $args);
17
18 my $handle_response = sub {
19 my $response = shift;
20
21 # Maybe do something with the response here.
22
23 return $response;
24 };
25
26 if ($self->response_is_future) {
27 $response->transform(
28 done => $handle_response,
29 fail => $handle_response,
30 );
31 }
32 else {
33 $response = $handle_response->($response);
34 }
35
36 return $response;
37 }
38
39 =head1 DESCRIPTION
40
41 This module provides an interface for an L<HTTP::AnyUA> "middleware," which is a component that sits
42 between an L<HTTP::AnyUA> object and the L<backend|HTTP::AnyUA::Backend> (which may in fact be
43 another middleware).
44
45 The easiest way to use middleware is to use L<HTTP::AnyUA/apply_middleware>.
46
47 The middleware mechanism can be used to munge or react to requests and responses to and from the
48 backend user agent. Middlewares are a completely optional part of L<HTTP::AnyUA>. They can be
49 wrapped around each other to create multiple layers and interesting possibilities. The functionality
50 provided by middleware may be alternative to features provided by some of the supported user agents,
51 themselves, but implementing functionality on this layer makes it work for I<all> the user agents.
52
53 =cut
54
55 use warnings;
56 use strict;
57
58 our $VERSION = '9999.999'; # VERSION
59
60 sub _croak { require Carp; Carp::croak(@_) }
61 sub _usage { _croak("Usage: @_\n") }
62
63
64 =method new
65
66 $middleware = HTTP::AnyUA::Middleware::MyMiddleware->new($backend);
67 $middleware = HTTP::AnyUA::Middleware::MyMiddleware->new($backend, %args);
68
69 Construct a new middleware.
70
71 =cut
72
73 sub new {
74 my $class = shift;
75 my $backend = shift or die 'Backend is required';
76 my $self = bless {backend => $backend}, $class;
77 $self->init(@_);
78 return $self;
79 }
80
81 =method init
82
83 Called by the default constructor with the middleware arguments.
84
85 This may be overridden by implementations instead of the constructor.
86
87 =cut
88
89 sub init {}
90
91 =method wrap
92
93 $middleware = HTTP::AnyUA::Middleware::MyMiddleware->wrap($backend, %args);
94 $middleware->wrap($backend);
95
96 Construct a new middleware or, when called on an instance, set a new backend on an existing
97 middleware.
98
99 =cut
100
101 sub wrap {
102 my $self = shift;
103 my $backend = shift or _usage($self . q{->wrap($backend, %args)});
104
105 if (ref $self) {
106 $self->{backend} = $backend;
107 }
108 else {
109 $self = $self->new($backend, @_);
110 }
111
112 return $self;
113 }
114
115 =method request
116
117 $response = $middleware->request($method => $url, \%options);
118
119 Make a request, get a response.
120
121 This should be overridden by implementations to do whatever they want with or to the request and/or
122 response.
123
124 =cut
125
126 sub request { shift->backend->request(@_) }
127
128 =attr backend
129
130 Get the current backend that is wrapped.
131
132 =cut
133
134 sub backend { shift->{backend} }
135
136 =attr ua
137
138 Get the backend user agent.
139
140 =cut
141
142 sub ua { shift->backend->ua(@_) }
143
144 =attr response_is_future
145
146 Get whether or not responses are L<Future> objects. Default is whatever the backend returns.
147
148 This may be overridden by implementations.
149
150 =cut
151
152 sub response_is_future { shift->backend->response_is_future(@_) }
153
154 1;
This page took 0.040561 seconds and 4 git commands to generate.