/[ttyrec]/jsttyplay/shell_server.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /jsttyplay/shell_server.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Tue Feb 17 18:12:32 2009 UTC (15 years, 3 months ago) by dpavlin
File MIME type: text/plain
File size: 4230 byte(s)
import upstream from http://encryptio.com/code/jsttyplay

1 dpavlin 1 #!/usr/bin/perl
2     use warnings;
3     use strict;
4    
5     my $max_session_idle = 60; # more than a minute without a request
6    
7     use Term::Emulator;
8     use TermEncoder;
9    
10     use URI;
11     use URI::QueryParam;
12     use JSON;
13     use HTTP::Status;
14     use POSIX ':sys_wait_h';
15     use CGI::Fast;
16     use CGI;
17    
18     while ( my $cgi = CGI::Fast->new ) {
19     eval {
20     my $uri = URI->new($ENV{REQUEST_URI});
21     print STDERR "$uri\n";
22     if ( $uri->path eq "/api" ) {
23     api($uri);
24     } else {
25     static($uri);
26     }
27     };
28     warn "error in handler: $@" if $@;
29     }
30    
31     sub static {
32     my ($uri) = @_;
33     my $path = $uri->path;
34     if ( $path eq "/" ) {
35     print "status: 200\015\012Content-type: text/html\015\012\015\012";
36     print <<EOF;
37     <html>
38     <head>
39     <script src="/streamtty.js"></script>
40     </head>
41     <body>
42     <div id="tty">Enable javascript, asshole</div>
43     <script>
44     startStreamTTY( document.getElementById("tty") );
45     </script>
46     </body>
47     </html>
48     EOF
49     return;
50     } elsif ( $path eq "/streamtty.js" ) {
51     open my $lf, "<", "html/streamtty.js" or die $!;
52     my $content = do { local $/; <$lf> };
53     close $lf;
54     print "status: 200\015\012content-type: text/javascript\015\012\015\012";
55     print $content;
56     return;
57     } else {
58     print "status: 404\015\012content-type: text/plain\015\012\015\012";
59     print "Not found.";
60     return;
61     }
62     }
63    
64     my %sessions = ();
65    
66     sub reap {
67     for my $id ( keys %sessions ) {
68     if ( time() - $sessions{$id}{'last_active'} > $max_session_idle ) {
69     print STDERR "reaped session: $id\n";
70     my $s = delete $sessions{$id};
71     $s->{'term'}->stop_it_in(1);
72     }
73     }
74     1 while waitpid(-1, WNOHANG) > 0;
75     }
76    
77     sub req_error {
78     my ($msg) = @_;
79     print "status: 500\015\012content-type: text/json\015\012\015\012";
80     print to_json( { ok => 0, error => $msg } );
81     }
82    
83     sub api {
84     my ($uri) = @_;
85    
86     reap();
87    
88     if ( $uri->query_param("type") eq "create session" ) {
89     my $id = new_session();
90     print STDERR "new session: $id\n";
91     $sessions{$id}->{'term'}->work_for(0.02);
92     print "status: 200\015\012content-type: text/json\015\012\015\012";
93     print to_json( { ok => 1, id => $id, iframe => $sessions{$id}->{'encoder'}->next_iframe } );
94     return;
95    
96     } elsif ( $uri->query_param("type") eq "user input" ) {
97     my $id = $uri->query_param("id");
98     return req_error("No such session.") unless exists $sessions{$id};
99     $sessions{$id}{'last_active'} = time;
100     my ($term, $enc) = @{$sessions{$id}}{'term', 'encoder'};
101     $term->userinput($uri->query_param("keys"));
102     $term->work_for(0.02);
103     print "status: 200\015\012content-type: text/json\015\012\015\012";
104     print to_json( { ok => 1, id => $id, pframe => $enc->next_pframe } );
105     return;
106    
107     } elsif ( $uri->query_param("type") eq "pframe" ) {
108     my $id = $uri->query_param("id");
109     return req_error("No such session.") unless exists $sessions{$id};
110     $sessions{$id}{'last_active'} = time;
111     my ($term, $enc) = @{$sessions{$id}}{'term', 'encoder'};
112     $term->work_for(0.02);
113     print "status: 200\015\012content-type: text/json\015\012\015\012";
114     print to_json( { ok => 1, id => $id, pframe => $enc->next_pframe } );
115     return;
116    
117     } elsif ( $uri->query_param("type") eq "close session" ) {
118     my $id = $uri->query_param("id");
119     return req_error("No such session.") unless exists $sessions{$id};
120     my $s = delete $sessions{$id};
121     my $term = $s->{'term'};
122     $term->stop_it_in(1);
123     print "status: 200\015\012content-type: text/json\015\012\015\012";
124     print to_json( { ok => 1 } );
125     return;
126    
127     } else {
128     return req_error("Bad request: unknown request type");
129     }
130     }
131    
132     sub new_session {
133     my $id = '';
134     while ( not length $id or exists $sessions{$id} ) {
135     $id = unpack "H*", join '', map chr rand 255, 1 .. 20;
136     }
137     my $term = Term::Emulator->new;
138     $term->spawn("login");
139     my $encoder = TermEncoder->new(term => $term->term);
140     $sessions{$id} = {
141     term => $term,
142     encoder => $encoder,
143     last_active => time,
144     };
145     return $id;
146     }
147    

Properties

Name Value
svn:executable

  ViewVC Help
Powered by ViewVC 1.1.26