The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Net::Inspect::L7::HTTP::WebSocket - implements WebSocket-upgrade

SYNOPSIS

 package myRequest;
 use base 'Net::Inspect::Flow';

 # define methods needed by Net::Inspect::L7::HTTP
 sub in_request_header { ... }
 ...

 use base 'Net::Inspect::L7::HTTP::WebSocket';
 # define the methods needed for WebSockets
 sub in_wsctl  { ... }
 sub in_wsdata { ... }

DESCRIPTION

This module implements the upgrade_websocket method which gets called by Net::Inspect::L7::HTTP if an upgrade to websockets is encountered:

$request->update_websocket($conn,$request,$response) -> $sub

If this function is implemented in the request object by deriving from this class it will check if the current upgrade is a valid websocket upgrade by inspecting $request and <$response>. These hashes are a the result of parse_reqhdr and parse_rsphdr in Net::Inspect::L7::HTTP.

The Net::Inspect::L7::HTTP object is also given, because it will be used (as a weak reference) in the callback $sub which gets returned if the connection upgrade was considered is valid.

This callback $sub will then be called as $sub->($dir,$data,$eof,$time) similar to in_data as documented in Net:Inspect::L7::HTTP. Based on the input $sub will then forward to in_wsctl or in_wsdata which need to be defined by the request object.

If the upgrade fails because the information sent in the headers are not correct the function will throw an error (i.e. die()) which will be catched by the caller $conn and will cause the connection to be declared bad.

The following functions will be called on new data and will need to be defined by the request object:

$request->in_wsctl($dir,$data,$time,$frameinfo)

This will be called after a Websocket upgrade when receiving a control frame. $dir is 0 for data from client, 1 for data from server. $data is the unmasked payload of the frame. $frameinfo is a blessed hash reference which contains the opcode of the frame, the mask (binary) and header for the frame header. For a close frame it will also contain the extracted status code and the reason.

To get the unmasked payload call $frameinfo->unmask($masked_data).

in_wsctl will be called on connection close with $data of '' and no \%frameinfo (i.e. no hash reference).

$request->in_wsdata($dir,$data,$eom,$time,$frameinfo)

This will be called after a Websocket upgrade when receiving data inside a data frame. Contrary to (the short) control frames the data frame must not be read fully before calling in_wsdata.

$dir is 0 for data from client, 1 for data from server. $data is the unmasked payload of the frame. $eom is true if the message is done with this call, that is if the data frame is done and the FIN bit was set on the frame. $frameinfo is a blessed hash reference which contains the data type as opcode. This will be the original opcode of the starting frame in case of fragmented transfer. It will also contain the mask (binary) of the current frame.

If this is the initial part of the data (i.e. initial frame in possibly fragmented data and initial data inside this frame) it will also have init set to true inside $frameinfo.

If there are still unread data within the frame $frameinfo will contain bytes_left as <[hi,low]> where hi and low are the upper and lower 32 bit parts of the number of outstanding bytes.

If this call to in_wsdata was caused by the start of a new frame and not further data in the same frame header will be set to the header of this new frame. In all other cases header is not set.

To get the unmasked payload call $frameinfo->unmask($masked_data).