Thread HTTP::Server::Simple & SSL & fork() (1 answers)
Opened by Perlaqua at 2009-10-25 16:32

Gast Perlaqua
 2009-10-25 16:32
#127311 #127311
Hallo,

ich möchte gerne eine kleine Webapplication bauen, die über einen Browser zu bedienen ist. Als Basis verwende ich des Beispielcode von CPAN:HTTP::Server::Simple inklusive des accept_hooks für SSL:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!/usr/bin/perl
 {
 package MyWebServer;
 
 use HTTP::Server::Simple::CGI;
 use base qw(HTTP::Server::Simple::CGI);
 
 my %dispatch = (
     '/hello' => \&resp_hello,
     # ...
 );
 
 sub handle_request {
     my $self = shift;
     my $cgi  = shift;
   
     my $path = $cgi->path_info();
     my $handler = $dispatch{$path};
 
     if (ref($handler) eq "CODE") {
         print "HTTP/1.0 200 OK\r\n";
         $handler->($cgi);
         
     } else {
         print "HTTP/1.0 404 Not found\r\n";
         print $cgi->header,
               $cgi->start_html('Not found'),
               $cgi->h1('Not found'),
               $cgi->end_html;
     }
 }
 
 sub resp_hello {
     my $cgi  = shift;   # CGI.pm object
     return if !ref $cgi;
     
     my $who = $cgi->param('name');
     
     print $cgi->header,
           $cgi->start_html("Hello"),
           $cgi->h1("Hello $who!"),
           $cgi->end_html;
 }
 
 } 
 
    sub accept_hook {
        my $self = shift;
        my $fh   = $self->stdio_handle;

        $self->SUPER::accept_hook(@_);

        my $newfh =
        IO::Socket::SSL->start_SSL( $fh, 
            SSL_server    => 1,
            SSL_use_cert  => 1,
            SSL_cert_file => 'myserver.crt',
            SSL_key_file  => 'myserver.key',
        )
        or warn "problem setting up SSL socket: " . IO::Socket::SSL::errstr();

        $self->stdio_handle($newfh) if $newfh;
    }

 # start the server on port 8080
 my $pid = MyWebServer->new(8080)->background();
 print "Use 'kill $pid' to stop server.\n";


Der Quelltext funktioniert prima, allerdings möchte ich den Code gerne so erweitern, dass für jede Verbindung gefork()t wird. Einige Methoden, die ich in der späteren Anwendung nutze dauern ein paar Minuten und da ansonsten während dieser Zeit die gesamte Anwendung nicht mehr reagieren würde, möchte ich gerne Multi-Threading nutzen.

Ich habe bisher soetwas versucht:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
sub accept_hook {
    my $self = shift;
    my $fh   = $self->stdio_handle;

    $self->SUPER::accept_hook(@_);

    my $pid = fork();

    if ($pid == 0) {
        my $newfh = IO::Socket::SSL->start_SSL(
            $fh,
            SSL_server    => 1,
            SSL_use_cert  => 1,
            SSL_cert_file => '/etc/xen0d/xen0d.crt',
            SSL_key_file  => '/etc/xen0d/rsa_private.key',
        )
        or warn "problem setting up SSL socket: " . IO::Socket::SSL::errstr();

        $self->stdio_handle($newfh) if $newfh;
    }
}

Hier bekomme ich aber folgenden Fehler in der Konsole:
Code: (dl )
problem setting up SSL socket: SSL accept attempt failed with unknown errorerror:00000000:lib(0):func(0):reason(0) at ./webserver.pl line 35, <DATA> line 16.


Der Firefox meldet mir folgendes:
Code: (dl )
1
2
3
SSL hat einen Eintrag erhalten, der die maximal erlaubte Länge überschritten hat.

(Fehlercode: ssl_error_rx_record_too_long)


Danach reagiert das Script nicht mehr auf einen Aufruf per Browser. Es werden zwar noch Threads erstellt, aber weiter passiert nichts.


Aber wie stelle ich das ganze so an, dass es funktioniert?


Gruß
Perlaqua

View full thread HTTP::Server::Simple & SSL & fork()