| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Mojo::UserAgent::SecureServer; |
|
2
|
3
|
|
|
3
|
|
1319390
|
use Mojo::Base 'Mojo::UserAgent::Server'; |
|
|
3
|
|
|
|
|
22
|
|
|
|
3
|
|
|
|
|
15
|
|
|
3
|
|
|
|
|
|
|
|
|
4
|
3
|
|
|
3
|
|
436
|
use Net::SSLeay (); |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
48
|
|
|
5
|
3
|
|
|
3
|
|
13
|
use Scalar::Util qw(weaken); |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
1561
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.03'; |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
has listen => sub { Mojo::URL->new('https://127.0.0.1') }; |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
sub from_ua { |
|
12
|
5
|
100
|
|
5
|
1
|
42786
|
my $self = ref $_[0] ? shift : shift->new; |
|
13
|
5
|
|
|
|
|
16
|
my $ua = shift; |
|
14
|
5
|
|
|
|
|
11
|
my $server = $ua->server; |
|
15
|
|
|
|
|
|
|
|
|
16
|
5
|
|
|
|
|
26
|
$self->$_($server->$_) for qw(app ioloop); |
|
17
|
5
|
|
|
|
|
106
|
$self->listen->query->param($_ => $ua->$_) for grep { $ua->$_ } qw(ca cert key); |
|
|
15
|
|
|
|
|
59
|
|
|
18
|
5
|
100
|
|
|
|
716
|
$self->listen->query->param(verify => Net::SSLeay::VERIFY_PEER()) unless $ua->insecure; |
|
19
|
|
|
|
|
|
|
|
|
20
|
5
|
|
|
|
|
284
|
return $self; |
|
21
|
|
|
|
|
|
|
} |
|
22
|
|
|
|
|
|
|
|
|
23
|
1
|
|
|
1
|
1
|
21568
|
sub nb_url { shift->_url(1, @_) } |
|
24
|
2
|
|
|
2
|
1
|
1808
|
sub url { shift->_url(0, @_) } |
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub _url { |
|
27
|
3
|
|
|
3
|
|
9
|
my ($self, $nb) = @_; |
|
28
|
|
|
|
|
|
|
|
|
29
|
3
|
100
|
|
|
|
10
|
my $port_key = $nb ? 'nb_port' : 'port'; |
|
30
|
3
|
50
|
|
|
|
10
|
unless ($self->{$port_key}) { |
|
31
|
3
|
100
|
|
|
|
11
|
my $server_key = $nb ? 'nb_server' : 'server'; |
|
32
|
3
|
|
|
|
|
12
|
my $url = $self->listen->clone; |
|
33
|
3
|
|
|
|
|
526
|
my @daemon_attrs = (silent => 1); |
|
34
|
3
|
100
|
|
|
|
17
|
push @daemon_attrs, ioloop => $self->ioloop unless $nb; |
|
35
|
|
|
|
|
|
|
|
|
36
|
3
|
|
|
|
|
41
|
my $server = $self->{$server_key} = Mojo::Server::Daemon->new(@daemon_attrs); |
|
37
|
3
|
|
|
|
|
83
|
weaken $server->app($self->app)->{app}; |
|
38
|
3
|
|
50
|
|
|
61
|
$url->port($self->{port} || undef); |
|
39
|
3
|
|
|
|
|
22
|
$self->{$port_key} = $server->listen([$url->to_string])->start->ports->[0]; |
|
40
|
|
|
|
|
|
|
} |
|
41
|
|
|
|
|
|
|
|
|
42
|
3
|
|
|
|
|
6366
|
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 |