line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Mojo::UserAgent::SecureServer; |
2
|
3
|
|
|
3
|
|
1620132
|
use Mojo::Base 'Mojo::UserAgent::Server'; |
|
3
|
|
|
|
|
27
|
|
|
3
|
|
|
|
|
20
|
|
3
|
|
|
|
|
|
|
|
4
|
3
|
|
|
3
|
|
550
|
use Net::SSLeay (); |
|
3
|
|
|
|
|
7
|
|
|
3
|
|
|
|
|
57
|
|
5
|
3
|
|
|
3
|
|
17
|
use Scalar::Util qw(weaken); |
|
3
|
|
|
|
|
7
|
|
|
3
|
|
|
|
|
1934
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.02'; |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
has listen => sub { Mojo::URL->new('https://127.0.0.1') }; |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
sub from_ua { |
12
|
5
|
100
|
|
5
|
1
|
53571
|
my $self = ref $_[0] ? shift : shift->new; |
13
|
5
|
|
|
|
|
20
|
my $ua = shift; |
14
|
5
|
|
|
|
|
15
|
my $server = $ua->server; |
15
|
|
|
|
|
|
|
|
16
|
5
|
|
|
|
|
54
|
$self->$_($server->$_) for qw(app ioloop); |
17
|
5
|
|
|
|
|
141
|
$self->listen->query->param($_ => $ua->$_) for grep { $ua->$_ } qw(ca cert key); |
|
15
|
|
|
|
|
88
|
|
18
|
5
|
100
|
|
|
|
916
|
$self->listen->query->param(verify => Net::SSLeay::VERIFY_PEER()) unless $ua->insecure; |
19
|
|
|
|
|
|
|
|
20
|
5
|
|
|
|
|
350
|
return $self; |
21
|
|
|
|
|
|
|
} |
22
|
|
|
|
|
|
|
|
23
|
1
|
|
|
1
|
1
|
36080
|
sub nb_url { shift->_url(1, @_) } |
24
|
2
|
|
|
2
|
1
|
2007
|
sub url { shift->_url(0, @_) } |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub _url { |
27
|
3
|
|
|
3
|
|
9
|
my ($self, $nb) = @_; |
28
|
|
|
|
|
|
|
|
29
|
3
|
100
|
|
|
|
13
|
my $port_key = $nb ? 'nb_port' : 'port'; |
30
|
3
|
50
|
|
|
|
12
|
unless ($self->{$port_key}) { |
31
|
3
|
100
|
|
|
|
12
|
my $server_key = $nb ? 'nb_server' : 'server'; |
32
|
3
|
|
|
|
|
12
|
my $url = $self->listen->clone; |
33
|
3
|
|
|
|
|
585
|
my @daemon_attrs = (silent => 1); |
34
|
3
|
100
|
|
|
|
21
|
push @daemon_attrs, ioloop => $self->ioloop unless $nb; |
35
|
|
|
|
|
|
|
|
36
|
3
|
|
|
|
|
50
|
my $server = $self->{$server_key} = Mojo::Server::Daemon->new(@daemon_attrs); |
37
|
3
|
|
|
|
|
99
|
weaken $server->app($self->app)->{app}; |
38
|
3
|
|
50
|
|
|
75
|
$url->port($self->{port} || undef); |
39
|
3
|
|
|
|
|
26
|
$self->{$port_key} = $server->listen([$url->to_string])->start->ports->[0]; |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
|
42
|
3
|
|
|
|
|
7867
|
return Mojo::URL->new("https://127.0.0.1:$self->{$port_key}/"); |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
1; |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
=encoding utf8 |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=head1 NAME |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
Mojo::UserAgent::SecureServer - Secure application server for Mojo::UserAgent |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
=head1 SYNOPSIS |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
# Construct from Mojo::UserAgent |
56
|
|
|
|
|
|
|
my $ua = Mojo::UserAgent->new; |
57
|
|
|
|
|
|
|
$ua->ca('ca.pem')->cert('cert.pem')->key('key.pem'); |
58
|
|
|
|
|
|
|
$ua->server(Mojo::UserAgent::SecureServer->from_ua($ua)); |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
# Construct manually |
61
|
|
|
|
|
|
|
my $ua = Mojo::UserAgent->new; |
62
|
|
|
|
|
|
|
my $server = Mojo::UserAgent::SecureServer->new; |
63
|
|
|
|
|
|
|
$server->listen(Mojo::URL->new('https://127.0.0.1?cert=/x/server.crt&key=/y/server.key&ca=/z/ca.crt')); |
64
|
|
|
|
|
|
|
$ua->server($server); |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# Test::Mojo |
67
|
|
|
|
|
|
|
my $app = Mojolicious->new; |
68
|
|
|
|
|
|
|
$app->routes->get('/' => sub { |
69
|
|
|
|
|
|
|
my $c = shift; |
70
|
|
|
|
|
|
|
my $handle = Mojo::IOLoop->stream($c->tx->connection)->handle; |
71
|
|
|
|
|
|
|
$c->render(json => {cn => $handle->peer_certificate('cn')}); |
72
|
|
|
|
|
|
|
}); |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
my $t = Test::Mojo->new($app); |
75
|
|
|
|
|
|
|
$t->ua->insecure(0); |
76
|
|
|
|
|
|
|
$t->ua->ca('t/pki/certs/ca-chain.cert.pem') |
77
|
|
|
|
|
|
|
->cert('t/pki/mojo.example.com.cert.pem') |
78
|
|
|
|
|
|
|
->key('t/pki/mojo.example.com.key.pem'); |
79
|
|
|
|
|
|
|
$t->ua->server(Mojo::UserAgent::SecureServer->from_ua($t->ua)); |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
$t->get_ok('/')->status_is(200)->json_is('/cn', 'mojo.example.com'); |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=head1 DESCRIPTION |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
L allows you to test your L web |
86
|
|
|
|
|
|
|
application with custom SSL/TLS key/cert/ca. |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
L inherits all attributes from |
91
|
|
|
|
|
|
|
L and implements the following new ones. |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=head2 listen |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
$url = $server->listen; |
96
|
|
|
|
|
|
|
$server = $server->listen(Mojo::URL->new('https://127.0.0.1')); |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
The base listen URL for L created by L and |
99
|
|
|
|
|
|
|
L. The "port" will be discarded, while other |
100
|
|
|
|
|
|
|
L parameters are kept. |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=head1 METHODS |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
L inherits all methods from |
105
|
|
|
|
|
|
|
L and implements the following new ones. |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
=head2 from_ua |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
$server = Mojo::UserAgent::SecureServer->from_ua($ua); |
110
|
|
|
|
|
|
|
$server = $server->from_ua($ua); |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
Used to construct a new object and/or copy attributes from a L |
113
|
|
|
|
|
|
|
object. Here is the long version: |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
$server->app($ua->server->app); |
116
|
|
|
|
|
|
|
$server->ioloop($ua->server->ioloop); |
117
|
|
|
|
|
|
|
$server->listen->query->param(ca => $ua->ca); |
118
|
|
|
|
|
|
|
$server->listen->query->param(cert => $ua->cert); |
119
|
|
|
|
|
|
|
$server->listen->query->param(key => $ua->key); |
120
|
|
|
|
|
|
|
$server->listen->query->param(verify => Net::SSLeay::VERIFY_PEER()) unless $ua->insecure |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=head2 nb_url |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
$url = $server->nb_url; |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
Get absolute L object for server processing non-blocking requests |
127
|
|
|
|
|
|
|
with L. |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=head2 url |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
$url = $server->url; |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
Get absolute L object for server processing non-blocking requests |
134
|
|
|
|
|
|
|
with L. |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
=head1 AUTHOR |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
Jan Henning Thorsen |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
Copyright (C) Jan Henning Thorsen. |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
This program is free software, you can redistribute it and/or modify it under |
145
|
|
|
|
|
|
|
the terms of the Artistic License version 2.0. |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=head1 SEE ALSO |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
L, L and L. |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=cut |