X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=lib%2FPlack%2FApp%2FProxy%2FWebSocket.pm;h=70b4d4f1ac3908365cca7cf2cce4c065b116e56b;hb=d42bcca517d4e42c0aed0bf7d63cb8956a9aa6fb;hp=94008e63492c7d01a7a6a708c508ad2d071813f8;hpb=9d371b6a17dca828e500d898aa8e1b11b6a2ce0e;p=chaz%2Fp5-Plack-App-Proxy-WebSocket diff --git a/lib/Plack/App/Proxy/WebSocket.pm b/lib/Plack/App/Proxy/WebSocket.pm index 94008e6..70b4d4f 100644 --- a/lib/Plack/App/Proxy/WebSocket.pm +++ b/lib/Plack/App/Proxy/WebSocket.pm @@ -6,8 +6,8 @@ use strict; use AnyEvent::Handle; use AnyEvent::Socket; +use HTTP::Parser::XS qw/parse_http_response HEADERS_AS_ARRAYREF/; use HTTP::Request; -use HTTP::Response; use Plack::Request; use URI; @@ -31,7 +31,7 @@ This is a subclass of L that adds support for proxying WebSocket connections. It has no extra dependencies or configuration options beyond what L requires or provides, so it may be an easy drop-in replacement. Read the documentation of that module for advanced usage -not covered by the L. +not covered here. This subclass necessarily requires extra L server features in order to work. The server must support C and C. It is also @@ -109,20 +109,17 @@ sub call { my $hdl = shift; my $buf = delete $hdl->{rbuf}; - if ($writer) { - $writer->write($buf); - return; - } - - if (($buffer .= $buf) =~ s/^(.+\r?\n\r?\n)//s) { - my $http = HTTP::Response->parse($1); - my @headers; - $http->headers->remove_header('Status'); - $http->headers->scan(sub { push @headers, @_ }); - $writer = $res->([$http->code, [@headers]]); - $writer->write($buffer) if $buffer; - $buffer = undef; - } + return $writer->write($buf) if $writer; + $buffer .= $buf; + + my ($ret, $http_version, $status, $message, $headers) = + parse_http_response($buffer, HEADERS_AS_ARRAYREF); + $server->push_shutdown if $ret == -2; + return if $ret < 0; + + $writer = $res->([$status, $headers]); + $writer->write(substr($buffer, $ret)); + $buffer = undef; }); # shut down the sockets and exit the loop if an error occurs @@ -135,7 +132,7 @@ sub call { $server->on_error(sub { $server->destroy; # get the client handle's attention - $writer->close; + $client->push_shutdown; }); };