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])) {

    if ($req->is_body || $req->is_done) {


    if ($req->version eq 'draft-ietf-hybi-00') {
        if ($self->is_done) {
        else {
    elsif ($self->is_done && $req->version eq 'draft-ietf-hybi-10'
        || $req->version eq 'draft-ietf-hybi-17')

    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, @_);


=head1 NAME

Protocol::WebSocket::Handshake::Server - WebSocket Server Handshake


    my $h = Protocol::WebSocket::Handshake::Server->new;

    # Parse client request
        WebSocket HTTP message

    $h->error;   # Check if there were any errors
    $h->is_done; # Returns 1

    # Create response


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 => '',
        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>

=head2 C<parse>


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>


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.