source: main/trunk/greenstone2/perllib/cpan/Mojo/Transaction.pm@ 32205

Last change on this file since 32205 was 32205, checked in by ak19, 6 years ago

First set of commits to do with implementing the new 'paged_html' output option of PDFPlugin that uses using xpdftools' new pdftohtml. So far tested only on Linux (64 bit), but things work there so I'm optimistically committing the changes since they work. 2. Committing the pre-built Linux binaries of XPDFtools for both 32 and 64 bit built by the XPDF group. 2. To use the correct bitness variant of xpdftools, setup.bash now exports the BITNESS env var, consulted by gsConvert.pl. 3. All the perl code changes to do with using xpdf tools' pdftohtml to generate paged_html and feed it in the desired form into GS(3): gsConvert.pl, PDFPlugin.pm and its parent ConvertBinaryPFile.pm have been modified to make it all work. xpdftools' pdftohtml generates a folder containing an html file and a screenshot for each page in a PDF (as well as an index.html linking to each page's html). However, we want a single html file that contains each individual 'page' html's content in a div, and need to do some further HTML style, attribute and structure modifications to massage the xpdftool output to what we want for GS. In order to parse and manipulate the HTML 'DOM' to do this, we're using the Mojo::DOM package that Dr Bainbridge found and which he's compiled up. Mojo::DOM is therefore also committed in this revision. Some further changes and some display fixes are required, but need to check with the others about that.

File size: 7.3 KB
Line 
1package Mojo::Transaction;
2use Mojo::Base 'Mojo::EventEmitter';
3
4use Carp 'croak';
5use Mojo::Message::Request;
6use Mojo::Message::Response;
7
8has [
9 qw(kept_alive local_address local_port original_remote_address remote_port)];
10has req => sub { Mojo::Message::Request->new };
11has res => sub { Mojo::Message::Response->new };
12
13sub client_read { croak 'Method "client_read" not implemented by subclass' }
14sub client_write { croak 'Method "client_write" not implemented by subclass' }
15
16sub closed { shift->completed->emit('finish') }
17
18sub completed { ++$_[0]{completed} and return $_[0] }
19
20sub connection {
21 my $self = shift;
22 return $self->emit(connection => $self->{connection} = shift) if @_;
23 return $self->{connection};
24}
25
26sub error { $_[0]->req->error || $_[0]->res->error }
27
28sub is_finished { !!shift->{completed} }
29
30sub is_websocket {undef}
31
32sub remote_address {
33 my $self = shift;
34
35 return $self->original_remote_address(@_) if @_;
36 return $self->original_remote_address unless $self->req->reverse_proxy;
37
38 # Reverse proxy
39 return ($self->req->headers->header('X-Forwarded-For') // '') =~ /([^,\s]+)$/
40 ? $1
41 : $self->original_remote_address;
42}
43
44sub result {
45 my $self = shift;
46 my $err = $self->error;
47 return !$err || $err->{code} ? $self->res : croak $err->{message};
48}
49
50sub server_read { croak 'Method "server_read" not implemented by subclass' }
51sub server_write { croak 'Method "server_write" not implemented by subclass' }
52
53sub success { $_[0]->error ? undef : $_[0]->res }
54
551;
56
57=encoding utf8
58
59=head1 NAME
60
61Mojo::Transaction - Transaction base class
62
63=head1 SYNOPSIS
64
65 package Mojo::Transaction::MyTransaction;
66 use Mojo::Base 'Mojo::Transaction';
67
68 sub client_read {...}
69 sub client_write {...}
70 sub server_read {...}
71 sub server_write {...}
72
73=head1 DESCRIPTION
74
75L<Mojo::Transaction> is an abstract base class for transactions, like
76L<Mojo::Transaction::HTTP> and L<Mojo::Transaction::WebSocket>.
77
78=head1 EVENTS
79
80L<Mojo::Transaction> inherits all events from L<Mojo::EventEmitter> and can
81emit the following new ones.
82
83=head2 connection
84
85 $tx->on(connection => sub {
86 my ($tx, $connection) = @_;
87 ...
88 });
89
90Emitted when a connection has been assigned to transaction.
91
92=head2 finish
93
94 $tx->on(finish => sub {
95 my $tx = shift;
96 ...
97 });
98
99Emitted when transaction is finished.
100
101=head1 ATTRIBUTES
102
103L<Mojo::Transaction> implements the following attributes.
104
105=head2 kept_alive
106
107 my $bool = $tx->kept_alive;
108 $tx = $tx->kept_alive($bool);
109
110Connection has been kept alive.
111
112=head2 local_address
113
114 my $address = $tx->local_address;
115 $tx = $tx->local_address('127.0.0.1');
116
117Local interface address.
118
119=head2 local_port
120
121 my $port = $tx->local_port;
122 $tx = $tx->local_port(8080);
123
124Local interface port.
125
126=head2 original_remote_address
127
128 my $address = $tx->original_remote_address;
129 $tx = $tx->original_remote_address('127.0.0.1');
130
131Remote interface address.
132
133=head2 remote_port
134
135 my $port = $tx->remote_port;
136 $tx = $tx->remote_port(8081);
137
138Remote interface port.
139
140=head2 req
141
142 my $req = $tx->req;
143 $tx = $tx->req(Mojo::Message::Request->new);
144
145HTTP request, defaults to a L<Mojo::Message::Request> object.
146
147 # Access request information
148 my $method = $tx->req->method;
149 my $url = $tx->req->url->to_abs;
150 my $info = $tx->req->url->to_abs->userinfo;
151 my $host = $tx->req->url->to_abs->host;
152 my $agent = $tx->req->headers->user_agent;
153 my $custom = $tx->req->headers->header('Custom-Header');
154 my $bytes = $tx->req->body;
155 my $str = $tx->req->text;
156 my $hash = $tx->req->params->to_hash;
157 my $all = $tx->req->uploads;
158 my $value = $tx->req->json;
159 my $foo = $tx->req->json('/23/foo');
160 my $dom = $tx->req->dom;
161 my $bar = $tx->req->dom('div.bar')->first->text;
162
163=head2 res
164
165 my $res = $tx->res;
166 $tx = $tx->res(Mojo::Message::Response->new);
167
168HTTP response, defaults to a L<Mojo::Message::Response> object.
169
170 # Access response information
171 my $code = $tx->res->code;
172 my $message = $tx->res->message;
173 my $server = $tx->res->headers->server;
174 my $custom = $tx->res->headers->header('Custom-Header');
175 my $bytes = $tx->res->body;
176 my $str = $tx->res->text;
177 my $value = $tx->res->json;
178 my $foo = $tx->res->json('/23/foo');
179 my $dom = $tx->res->dom;
180 my $bar = $tx->res->dom('div.bar')->first->text;
181
182=head1 METHODS
183
184L<Mojo::Transaction> inherits all methods from L<Mojo::EventEmitter> and
185implements the following new ones.
186
187=head2 client_read
188
189 $tx->client_read($bytes);
190
191Read data client-side, used to implement user agents such as L<Mojo::UserAgent>.
192Meant to be overloaded in a subclass.
193
194=head2 client_write
195
196 my $bytes = $tx->client_write;
197
198Write data client-side, used to implement user agents such as
199L<Mojo::UserAgent>. Meant to be overloaded in a subclass.
200
201=head2 closed
202
203 $tx = $tx->closed;
204
205Same as L</"completed">, but also indicates that all transaction data has been
206sent.
207
208=head2 completed
209
210 $tx = $tx->completed;
211
212Low-level method to finalize transaction.
213
214=head2 connection
215
216 my $id = $tx->connection;
217 $tx = $tx->connection($id);
218
219Connection identifier.
220
221=head2 error
222
223 my $err = $tx->error;
224
225Get request or response error and return C<undef> if there is no error,
226commonly used together with L</"success">.
227
228 # Longer version
229 my $err = $tx->req->error || $tx->res->error;
230
231 # Check for 4xx/5xx response and connection errors
232 if (my $err = $tx->error) {
233 die "$err->{code} response: $err->{message}" if $err->{code};
234 die "Connection error: $err->{message}";
235 }
236
237=head2 is_finished
238
239 my $bool = $tx->is_finished;
240
241Check if transaction is finished.
242
243=head2 is_websocket
244
245 my $bool = $tx->is_websocket;
246
247False, this is not a L<Mojo::Transaction::WebSocket> object.
248
249=head2 remote_address
250
251 my $address = $tx->remote_address;
252 $tx = $tx->remote_address('127.0.0.1');
253
254Same as L</"original_remote_address"> or the last value of the
255C<X-Forwarded-For> header if L</"req"> has been performed through a reverse
256proxy.
257
258=head2 result
259
260 my $res = $tx->result;
261
262Returns the L<Mojo::Message::Response> object from L</"res"> or dies if a
263connection error has occurred.
264
265 # Fine grained response handling (dies on connection errors)
266 my $res = $tx->result;
267 if ($res->is_success) { say $res->body }
268 elsif ($res->is_error) { say $res->message }
269 elsif ($res->code == 301) { say $res->headers->location }
270 else { say 'Whatever...' }
271
272=head2 server_read
273
274 $tx->server_read($bytes);
275
276Read data server-side, used to implement web servers such as
277L<Mojo::Server::Daemon>. Meant to be overloaded in a subclass.
278
279=head2 server_write
280
281 my $bytes = $tx->server_write;
282
283Write data server-side, used to implement web servers such as
284L<Mojo::Server::Daemon>. Meant to be overloaded in a subclass.
285
286=head2 success
287
288 my $res = $tx->success;
289
290Returns the L<Mojo::Message::Response> object from L</"res"> if transaction was
291successful or C<undef> otherwise. Connection and parser errors have only a
292message in L</"error">, C<400> and C<500> responses also a code.
293
294 # Manual exception handling
295 if (my $res = $tx->success) { say $res->body }
296 else {
297 my $err = $tx->error;
298 die "$err->{code} response: $err->{message}" if $err->{code};
299 die "Connection error: $err->{message}";
300 }
301
302=head1 SEE ALSO
303
304L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
305
306=cut
Note: See TracBrowser for help on using the repository browser.