File Coverage

blib/lib/HTTP/Daemon/SSL.pm
Criterion Covered Total %
statement 18 49 36.7
branch 0 10 0.0
condition 0 11 0.0
subroutine 6 13 46.1
pod 3 4 75.0
total 27 87 31.0


line stmt bran cond sub pod time code
1             #
2             # This package derived almost entirely from HTTP::Daemon,
3             # owned by Gisle Aas. Changes include minor alterations in
4             # the documentation to reflect the use of IO::Socket::SSL
5             # and modified new(),accept() functions that use IO::Socket::SSL
6              
7 1     1   800 use strict;
  1         3  
  1         88  
8              
9             package HTTP::Daemon::SSL;
10              
11             =head1 NAME
12              
13             HTTP::Daemon::SSL - a simple http server class with SSL support
14              
15             =head1 SYNOPSIS
16              
17             use HTTP::Daemon::SSL;
18             use HTTP::Status;
19              
20             # Make sure you have a certs/ directory with "server-cert.pem"
21             # and "server-key.pem" in it before running this!
22             my $d = HTTP::Daemon::SSL->new || die;
23             print "Please contact me at: url, ">\n";
24             while (my $c = $d->accept) {
25             while (my $r = $c->get_request) {
26             if ($r->method eq 'GET' and $r->url->path eq "/xyzzy") {
27             # remember, this is *not* recommened practice :-)
28             $c->send_file_response("/etc/passwd");
29             } else {
30             $c->send_error(RC_FORBIDDEN)
31             }
32             }
33             $c->close;
34             undef($c);
35             }
36              
37             =head1 DESCRIPTION
38              
39             Instances of the I class are HTTP/1.1 servers that
40             listen on a socket for incoming requests. The I is a
41             sub-class of I, so you can perform socket operations
42             directly on it too.
43              
44             The accept() method will return when a connection from a client is
45             available. In a scalar context the returned value will be a reference
46             to a object of the I class which is another
47             I subclass. In a list context a two-element array
48             is returned containing the new I reference
49             and the peer address; the list will be empty upon failure. (Note that version
50             1.02 erroneously did not honour list context). Calling
51             the get_request() method on the I object
52             will read data from the client and return an I object
53             reference.
54              
55             This HTTPS daemon does not fork(2) for you. Your application, i.e. the
56             user of the I is reponsible for forking if that is
57             desirable. Also note that the user is responsible for generating
58             responses that conform to the HTTP/1.1 protocol. The
59             I class provides some methods that make this easier.
60              
61             =head1 METHODS
62              
63             The following methods are the only differences from the I base class:
64              
65             =over 4
66              
67             =cut
68              
69              
70 1     1   6 use vars qw($VERSION @ISA $PROTO $DEBUG);
  1         2  
  1         102  
71              
72 1     1   1852 use IO::Socket::SSL;
  1         176317  
  1         11  
73 1     1   1472 use HTTP::Daemon;
  1         183461  
  1         18  
74              
75             $VERSION = "1.04";
76             @ISA = qw(IO::Socket::SSL HTTP::Daemon);
77              
78             =item $d = new HTTP::Daemon::SSL
79              
80             The constructor takes the same parameters as the
81             I constructor. It can also be called without specifying
82             any parameters, but you will have to make sure that you have an SSL certificate
83             and key for the server in F and F.
84             See the IO::Socket::SSL documentation for how to change these default locations
85             and specify many other aspects of SSL behavior. The daemon will then set up a
86             listen queue of 5 connections and allocate some random port number. A server
87             that wants to bind to some specific address on the standard HTTPS port will be
88             constructed like this:
89              
90             $d = new HTTP::Daemon::SSL
91             LocalAddr => 'www.someplace.com',
92             LocalPort => 443;
93              
94             =cut
95              
96             sub new
97             {
98 0     0 1   my ($class, %args) = @_;
99 0   0       $args{Listen} ||= 5;
100 0   0       $args{Proto} ||= 'tcp';
101 0   0       $args{SSL_error_trap} ||= \&ssl_error;
102 0           return $class->SUPER::new(%args);
103             }
104              
105             sub accept
106             {
107 0     0 1   my $self = shift;
108 0   0       my $pkg = shift || "HTTP::Daemon::ClientConn::SSL";
109 0           my ($sock, $peer) = IO::Socket::SSL::accept($self,$pkg);
110 0 0         if ($sock) {
111 0           ${*$sock}{'httpd_daemon'} = $self;
  0            
112 0 0         return wantarray ? ($sock, $peer) : $sock;
113             }
114             else {
115 0           return;
116             }
117             }
118              
119 0     0     sub _default_port { 443; }
120 0     0     sub _default_scheme { "https"; }
121              
122             sub url
123             {
124 0     0 1   my $self = shift;
125 0           my $url = $self->SUPER::url;
126 0 0         return $url if ($self->can("HTTP::Daemon::_default_port"));
127            
128             # Workaround for old versions of HTTP::Daemon
129 0           $url =~ s!^http:!https:!;
130 0 0         $url =~ s!/$!:80/! unless ($url =~ m!:(?:\d+)/$!);
131 0           $url =~ s!:443/$!/!;
132 0           return $url;
133             }
134              
135              
136             package HTTP::Daemon::SSL::DummyDaemon;
137 1     1   1132 use vars qw(@ISA);
  1         2  
  1         455  
138             @ISA = qw(HTTP::Daemon);
139 0     0     sub new { bless [], shift; }
140              
141             package HTTP::Daemon::SSL;
142              
143             sub ssl_error {
144 0     0 0   my ($self, $error) = @_;
145 0           ${*$self}{'httpd_client_proto'} = 1000;
  0            
146 0           ${*$self}{'httpd_daemon'} = new HTTP::Daemon::SSL::DummyDaemon;
  0            
147 0 0 0       if ($error =~ /http/i and $self->opened) {
148 0           $self->send_error(400, "Your browser attempted to make an unencrypted\n ".
149             "request to this server, which is not allowed. Try using\n ".
150             "HTTPS instead.\n");
151             }
152 0           $self->kill_socket;
153             }
154              
155             # we're not overriding any methods here, but we are inserting IO::Socket::SSL
156             # into the message dispatch tree
157              
158             package HTTP::Daemon::ClientConn::SSL;
159 1     1   7 use vars qw(@ISA $DEBUG);
  1         1  
  1         100  
160             @ISA = qw(IO::Socket::SSL HTTP::Daemon::ClientConn);
161             *DEBUG = \$HTTP::Daemon::DEBUG;
162              
163              
164             =head1 SEE ALSO
165              
166             RFC 2068
167              
168             L, L, L
169              
170             =head1 COPYRIGHT
171              
172             Code and documentation from HTTP::Daemon Copyright 1996-2001, Gisle Aas
173             Changes Copyright 2003-2004, Peter Behroozi
174              
175             This library is free software; you can redistribute it and/or
176             modify it under the same terms as Perl itself.
177              
178             =cut
179              
180             1;