mirror of
https://github.com/webmin/webmin.git
synced 2026-02-07 07:52:13 +00:00
162 lines
3.3 KiB
Perl
162 lines
3.3 KiB
Perl
package Protocol::WebSocket::Handshake::Server;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use base 'Protocol::WebSocket::Handshake';
|
|
|
|
use Protocol::WebSocket::Request;
|
|
use Protocol::WebSocket::Frame;
|
|
|
|
sub new_from_psgi {
|
|
my $class = shift;
|
|
|
|
my $req = Protocol::WebSocket::Request->new_from_psgi(@_);
|
|
my $self = $class->new(req => $req);
|
|
|
|
return $self;
|
|
}
|
|
|
|
sub parse {
|
|
my $self = shift;
|
|
|
|
my $req = $self->req;
|
|
my $res = $self->res;
|
|
|
|
return 1 if $req->is_done;
|
|
|
|
unless ($req->parse($_[0])) {
|
|
$self->error($req->error);
|
|
return;
|
|
}
|
|
|
|
if ($req->is_body || $req->is_done) {
|
|
$res->version($req->version);
|
|
$res->host($req->host);
|
|
|
|
$res->secure($req->secure);
|
|
$res->resource_name($req->resource_name);
|
|
$res->origin($req->origin);
|
|
}
|
|
|
|
if ($req->version eq 'draft-ietf-hybi-00') {
|
|
if ($self->is_done) {
|
|
$res->checksum(undef);
|
|
$res->number1($req->number1);
|
|
$res->number2($req->number2);
|
|
$res->challenge($req->challenge);
|
|
}
|
|
else {
|
|
$res->checksum('');
|
|
}
|
|
}
|
|
elsif ($self->is_done && $req->version eq 'draft-ietf-hybi-10'
|
|
|| $req->version eq 'draft-ietf-hybi-17')
|
|
{
|
|
$res->key($req->key);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
sub is_body { shift->req->is_body }
|
|
sub is_done { shift->req->is_done }
|
|
sub to_string {
|
|
my $self = shift;
|
|
|
|
if ($self->is_body) {
|
|
return $self->{partial} = $self->res->to_string;
|
|
}
|
|
elsif ($self->{partial}) {
|
|
my $to_string = $self->res->to_string;
|
|
|
|
$to_string =~ s/^\Q$self->{partial}\E//;
|
|
|
|
return $to_string;
|
|
}
|
|
|
|
return $self->res->to_string;
|
|
}
|
|
|
|
sub build_frame {
|
|
my $self = shift;
|
|
|
|
return Protocol::WebSocket::Frame->new(version => $self->version, @_);
|
|
}
|
|
|
|
1;
|
|
__END__
|
|
|
|
=head1 NAME
|
|
|
|
Protocol::WebSocket::Handshake::Server - WebSocket Server Handshake
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
my $h = Protocol::WebSocket::Handshake::Server->new;
|
|
|
|
# Parse client request
|
|
$h->parse(<<"EOF");
|
|
WebSocket HTTP message
|
|
EOF
|
|
|
|
$h->error; # Check if there were any errors
|
|
$h->is_done; # Returns 1
|
|
|
|
# Create response
|
|
$h->to_string;
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
Construct or parse a server WebSocket handshake. This module is written for
|
|
convenience, since using request and response directly requires the same code
|
|
again and again.
|
|
|
|
=head1 METHODS
|
|
|
|
=head2 C<new>
|
|
|
|
Create a new L<Protocol::WebSocket::Handshake::Server> instance.
|
|
|
|
=head2 C<new_from_psgi>
|
|
|
|
my $env = {
|
|
HTTP_HOST => 'example.com',
|
|
HTTP_CONNECTION => 'Upgrade',
|
|
...
|
|
};
|
|
my $handshake = Protocol::WebSocket::Handshake::Server->new_from_psgi($env);
|
|
|
|
Create a new L<Protocol::WebSocket::Handshake::Server> instance from L<PSGI>
|
|
environment.
|
|
|
|
=head2 C<parse>
|
|
|
|
$handshake->parse($buffer);
|
|
$handshake->parse($handle);
|
|
|
|
Parse a WebSocket client request. Returns C<undef> and sets C<error> attribute
|
|
on error.
|
|
|
|
When buffer is passed it's modified (unless readonly).
|
|
|
|
=head2 C<build_frame>
|
|
|
|
$handshake->build_frame;
|
|
|
|
Builds L<Protocol::WebSocket::Frame> with an appropriate version.
|
|
|
|
=head2 C<to_string>
|
|
|
|
Construct a WebSocket server response.
|
|
|
|
=head2 C<is_body>
|
|
|
|
Check whether handshake is in body state.
|
|
|
|
=head2 C<is_done>
|
|
|
|
Check whether handshake is done.
|
|
|
|
=cut
|