/[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

Contents of /jsttyplay/shell_server.pl

Parent Directory Parent Directory | Revision Log Revision Log


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

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