root/trunk/lib/Perlbal/ClientManage.pm

Revision 798, 4.2 kB (checked in by hachi, 13 months ago)

Silence a warning, this one comes from the HTTP access method on managment ports. Some services don't have listeners, so we shouldn't try to print the listener out.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1######################################################################
2# Management connection from a client
3######################################################################
4
5package Perlbal::ClientManage;
6use strict;
7use warnings;
8no  warnings qw(deprecated);
9
10use base "Perlbal::Socket";
11use fields ('service',
12            'buf',
13            'is_http',  # bool: is an HTTP request?
14            'ctx',      # command context
15            );
16
17# ClientManage
18sub new {
19    my Perlbal::ClientManage $self = shift;
20    my ($service, $sock) = @_;
21    $self = fields::new($self) unless ref $self;
22    $self->SUPER::new($sock);
23    $self->{service} = $service;
24    $self->{buf} = "";   # what we've read so far, not forming a complete line
25
26    $self->{ctx} = Perlbal::CommandContext->new;
27    $self->{ctx}->verbose(1);
28
29    $self->watch_read(1);
30    return $self;
31}
32
33# ClientManage
34sub event_read {
35    my Perlbal::ClientManage $self = shift;
36
37    my $bref;
38    unless ($self->{is_http}) {
39        $bref = $self->read(1024);
40        return $self->close() unless defined $bref;
41        $self->{buf} .= $$bref;
42
43        if ($self->{buf} =~ /^(?:HEAD|GET|POST) /) {
44            $self->{is_http} = 1;
45            $self->{headers_string} .= $$bref;
46        }
47    }
48
49    if ($self->{is_http}) {
50        my $hd = $self->read_request_headers;
51        return unless $hd;
52        $self->handle_http();
53        return;
54    }
55
56    while ($self->{buf} =~ s/^(.+?)\r?\n//) {
57        my $line = $1;
58
59        if ($line =~ /^quit|exit$/) {
60            $self->close('user_requested_quit');
61            return;
62        }
63
64        my $out = sub {
65            $self->write("$_[0]\r\n");
66        };
67
68        Perlbal::run_manage_command($line, $out, $self->{ctx});
69    }
70}
71
72sub event_write {
73    my $self = shift;
74    $self->watch_write(0) if $self->write(undef);
75}
76
77# ClientManage
78sub event_err {  my $self = shift; $self->close; }
79sub event_hup {  my $self = shift; $self->close; }
80
81# HTTP management support
82sub handle_http {
83    my Perlbal::ClientManage $self = shift;
84
85    my $uri = $self->{req_headers}->request_uri;
86
87    my $body;
88    my $code = "200 OK";
89
90    my $prebox = sub {
91        my $cmd = shift;
92        my $alt = shift;
93        $body .= "<pre><div style='margin-bottom: 5px; background: #ddd'><b>$cmd</b></div>";
94        Perlbal::run_manage_command($cmd, sub {
95            my $line = $_[0] || "";
96            $alt->(\$line) if $alt;
97            $body .= "$line\n";
98        });
99        $body .= "</pre>\n";
100
101    };
102
103    $body .= "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
104    $body .= "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en-ZA\">\n";
105    $body .= "<head><title>perlbal management interface</title><meta name=\"generator\" content=\"perlbal\" /></head><body>";
106
107    if ($uri eq "/") {
108        $body .= "<h1>perlbal management interface</h1><ul>";
109        $body .= "<li><a href='/socks'>Sockets</a></li>";
110        $body .= "<li><a href='/obj'>Perl Objects in use</a></li>";
111        $body .= "<li>Service Details<ul>";
112        foreach my $sname (Perlbal->service_names) {
113            my Perlbal::Service $svc = Perlbal->service($sname);
114            next unless $svc;
115            my $listen = $svc->{listen} ? " ($svc->{listen})" : "";
116            $body .= "<li><a href='/service?$sname'>$sname</a> - $svc->{role}$listen</li>\n";
117        }
118        $body .= "</ul></li>";
119        $body .= "</ul>";
120    } elsif ($uri eq "/socks") {
121        $prebox->('socks summary');
122
123        $prebox->('socks', sub {
124            ${$_[0]} =~ s!service \'(\w+)\'!<a href=\"/service?$1\">$1</a>!;
125        });
126    } elsif ($uri eq "/obj") {
127        $prebox->('obj');
128    } elsif ($uri =~ m!^/service\?(\w+)$!) {
129        my $service = $1;
130        $prebox->("show service $service");
131    } else {
132        $code = "404 Not found";
133        $body .= "<h1>$code</h1>";
134    }
135
136    $body .= "<hr style='margin-top: 10px' /><p><a href='/'>Perlbal management</a>.</p></body></html>\n";
137    $self->write("HTTP/1.0 $code\r\nContent-type: text/html\r\nContent-Length: " . length($body) .
138                 "\r\n\r\n$body");
139    $self->write(sub { $self->close; });
140    return;
141}
142
1431;
144
145
146# Local Variables:
147# mode: perl
148# c-basic-indent: 4
149# indent-tabs-mode: nil
150# End:
Note: See TracBrowser for help on using the browser.