-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTCP_Server.pl
More file actions
62 lines (52 loc) · 1.6 KB
/
Copy pathTCP_Server.pl
File metadata and controls
62 lines (52 loc) · 1.6 KB
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
# server.pl
use strict;
use warnings;
use IO::Socket::INET;
use XTTP::Message;
my $hmac_key = 'supersecret'; # replace with proper key management
my $server = IO::Socket::INET->new(
LocalAddr => '0.0.0.0',
LocalPort => 8088,
Proto => 'tcp',
Listen => 5,
Reuse => 1,
) or die "Could not start server: $!";
print "XTTP server listening on 0.0.0.0:8088\n";
while (my $client = $server->accept) {
$client->autoflush(1);
# Read until we can parse headers and body length
my $buf = '';
while ($buf !~ /\r\n\r\n/) {
my $read = <$client>;
last unless defined $read;
$buf .= $read;
}
# Extract Content-Length to read body
my ($headers) = $buf =~ /\A.*?\r\n\r\n/s;
my ($len) = $headers =~ /^Content-Length:\s*(\d+)/mi;
$len ||= 0;
my $body = '';
read($client, $body, $len) if $len > 0;
$buf .= $body;
# Optionally read HMAC trailer line
my $line = <$client>;
$buf .= $line if defined $line;
my $msg;
eval { $msg = XTTP::Message->parse($buf, hmac_key => $hmac_key) };
if ($@) {
print $client "SEND /error xttp/1.0\r\nStatus: 400\r\nContent-Length: 0\r\n\r\n";
close $client;
next;
}
# Application logic
my $reply_body = "ok";
my $reply = XTTP::Message->new(
method => 'REPLY',
path => $msg->{path},
headers => { Status => 200, 'Content-Type' => 'text/plain' },
body => $reply_body,
hmac_key => $hmac_key,
);
print $client $reply->serialize;
close $client;
}