package Protocol::WebSocket::Handshake::Client; use strict; use warnings; use base 'Protocol::WebSocket::Handshake'; require Carp; use Protocol::WebSocket::URL; use Protocol::WebSocket::Frame; sub new { my $self = shift->SUPER::new(@_); $self->_set_url($self->{url}) if defined $self->{url}; if (my $version = $self->{version}) { $self->req->version($version); $self->res->version($version); } return $self; } sub url { my $self = shift; my $url = shift; return $self->{url} unless $url; $self->_set_url($url); return $self; } sub parse { my $self = shift; my $req = $self->req; my $res = $self->res; unless ($res->is_done) { unless ($res->parse($_[0])) { $self->error($res->error); return; } if ($res->is_done) { if ( $req->version eq 'draft-ietf-hybi-00' && $req->checksum ne $res->checksum) { $self->error('Checksum is wrong.'); return; } } } return 1; } sub is_done { shift->res->is_done } sub to_string { shift->req->to_string } sub build_frame { my $self = shift; return Protocol::WebSocket::Frame->new(masked => 1, version => $self->version, @_); } sub _build_url { Protocol::WebSocket::URL->new } sub _set_url { my $self = shift; my $url = shift; $url = $self->_build_url->parse($url) unless ref $url; $self->req->secure(1) if $url->secure; my $req = $self->req; my $host = $url->host; $host .= ':' . $url->port if defined $url->port && ($url->secure ? $url->port ne '443' : $url->port ne '80'); $req->host($host); $req->resource_name($url->resource_name); return $self; } 1; __END__ =head1 NAME Protocol::WebSocket::Handshake::Client - WebSocket Client Handshake =head1 SYNOPSIS my $h = Protocol::WebSocket::Handshake::Client->new(url => 'ws://example.com'); # Create request $h->to_string; # Parse server response $h->parse(<<"EOF"); WebSocket HTTP message EOF $h->error; # Check if there were any errors $h->is_done; # Returns 1 =head1 DESCRIPTION Construct or parse a client WebSocket handshake. This module is written for convenience, since using request and response directly requires the same code again and again. =head1 ATTRIBUTES =head2 C $handshake->url('ws://example.com/demo'); Set or get WebSocket url. =head1 METHODS =head2 C Create a new L instance. =head2 C $handshake->parse($buffer); Parse a WebSocket server response. Returns C and sets C attribute on error. Buffer is modified. =head2 C Construct a WebSocket client request. =head2 C Check whether handshake is done. =cut