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

NAME

WebSocket::Version - WebSocket Version

SYNOPSIS

    use WebSocket::Version;
    my $ver = WebSocket::Version->new( 'draft-ietf-hybi-17' ) || die( WebSocket::Version->error, "\n" );
    my $ver = WebSocket::Version->new(13) || die( WebSocket::Version->error, "\n" );
    my $ver = WebSocket::Version->new_from_request( $req ) || die( WebSocket::Version->error, "\n" );
    print( $ver->numify, "\n" );
    print( $ver->draft, "\n" );
    print( "Version is: $ver\n" ); # Version is: 13

VERSION

    v0.1.0

DESCRIPTION

A WebSocket class representing the version of the protocol used.

Version numbering used in the protocol headers started to be used since version 4, thus to allow numeric comparison this class uses an internal version number as a simple increment.

rfc6455 is also known as draft-ietf-hybi-17 (version 13).

CONSTRUCTOR

new

Takes an integer representing a WebSocket protocol version (the latet being 13), or a draft version such as draft-ietf-hybi-17 and this will return a new object.

It can take also an hash or hash reference of optional parameters with the only one being debug. You can provide it an integer value to set the level of debugging. Nothing meaningful is displayed below 3.

METHODS

as_string

Returns the numeric value of the version. However, note that IETF drafts before revision 00, i.e. of type hixie do not have version number, so this method will return undef then.

draft

Returns the draft version such as draft-ietf-hybi-17, as a scalar object (Module::Generic::Scalar

expires

Returns the draft expiration date as a DateTime object.

get_dictionary

Takes an hash or hash reference of options and returns a dictionary hash containing all the attributes for the draft found.

Current supported options are:

draft

The draft version, such as draft-ietf-hybi-17

revision

The draft revision number such as 17. This is used in conjunction with the type option

serial

The serial number to search for. This is an internal number not part of the rfc6455https://datatracker.ietf.org/doc/html/rfc6455.

type

The draft type, which is either hiby or hixie. This is used in conjunction with the revision option

version

Its value is an integer representing the WebSocket protocol version. For example 13, the latest version.

If none of those options are provided, undef is return and an error is set.

issued

Returns the draft issue date as a DateTime object.

new_from_request

Given a WebSocket::Request object, this will analyse the request headers and based on the information found, it will infer a WebSocket protocol version and return the corresponding most recent object matching that version.

next

Returns the next version object. For example, if the current object is the draft draft-ietf-hybi-16, calling next will return a version object matching the draft version draft-ietf-hybi-17.

Note that some draft version share the same protocol version. For example, draft-ietf-hybi-13 to draft-ietf-hybi-17 all use protocol version 13.

Also note that version prior to draft-ietf-hybi-00, such as draft-hixie-76 to draft-hixie-00 have no version number and thus the stringification of the object returns undef.

numify

Returns the numeric representation of the version as a Module::Generic::Number object. For example, 13 which is the latest version of the WebSocket protocol.

offset

Returns the offset position of the object in the repository of all IETF drafts for the WebSocket protocol.

prev

Alias for "previous".

previous

Returns the previous version object. For example, if the current object is the draft draft-ietf-hybi-16, calling next will return a version object matching the draft version draft-ietf-hybi-15

Note that some draft version share the same protocol version. For example, draft-ietf-hybi-13 to draft-ietf-hybi-17 all use protocol version 13.

Also note that version prior to draft-ietf-hybi-00, such as draft-hixie-76 to draft-hixie-00 have no version number and thus the stringification of the object returns undef.

revision

Returns the draft revision number. For example in draft-ietf-hybi-17, the revision number is 17

serial

Returns the internal serial number used to identify and manipulate the version objects. This value is used by internal private methods to handle overloading. See "OPERATIONS"

status

Returns the status as scalar object (Module::Generic::Scalar). Typical status is draft, obsolete

type

Returns the type as scalar object (Module::Generic::Scalar). Possible types are: hybi or hixie

version

Returns the WebSocket protocol version. Below is a summary table[1] of the IETF drafts and their version.

[1] Courtesy of Table Generator

OPERATIONS

The WebSocket::Version object supports the following overloaded operators: "", -, +, *, /, %, <, <=, >, >=, <=>, ==, !=, eq, ne, cmp, bool

    my $v = WebSocket::Version->new(13);
    # Now draft version draft-ietf-hybi-17, which is the latest 
    # draft version for protocol version 13
    my $v16 = $v - 1;
    # Now draft version draft-ietf-hybi-16

But be careful that, if as a result of an operation, the product yields a version out of bound, i.e. above the latest draft-ietf-hybi-17 or prior to draft-hixie-00, then it will return undef. For example:

    my $non_existing = $v16 * 2;
    # $non_existing is undef because there is no draft version 32

Likewise, if a product yields a fractional number, it will return undef. For example:

    my $undef_too = $v / 2;
    # This would yield 8.5, which is not usable and thus returns undef

IETF WORKING DRAFTS

Headers and Versions

Below is a table of the availability of headers by IETF draft revision number.

"all" means all the versions that are relevant and listed below after the table. Other earlier versions such as drafts Hixie 0 to 74 are not meaningful nor relevant, thus, 75 means draft-hixie-75, otherwise those revisions are from drafts draft-ietf-hybi-00 to draft-ietf-hybi-17

HyBi 17

Request:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 13

Response:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Protocol: chat

Date: 2011-09-30

Reference

Diff from HyBi 16

  • Only editorial changes

  • Sec-WebSocket-Version value is still 13 and this must be the version for RFC

HyBi 16

Request:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 13

Response:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Protocol: chat

Date: 2011-09-27

Reference

Diff from HyBi 15

Only editorial changes

HyBi 15

Request:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 13

Response:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Protocol: chat

Date: 2011-09-17

Reference

Diff from HyBi 14

Sec-WebSocket-Version is still 13.

Editorial changes only.

  • If servers doesn't support the requested version, they MUST respond with Sec-WebSocket-Version headers containing all available versions.

  • The servers MUST close the connection upon receiving a non-masked frame with status code of 1002.

  • The clients MUST close the connection upon receiving a masked frame with status code of 1002.

HyBi 14

Request:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 13

Response:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Protocol: chat

Date: 2011-09-08

Reference

Diff from HyBi 13

Sec-WebSocket-Version is still 13.

  • Version negotiation

    The following example demonstrates version negotiation:

        GET /chat HTTP/1.1
        Host: server.example.com
        Upgrade: websocket
        Connection: Upgrade
        ...
        Sec-WebSocket-Version: 25

    The response from the server might look as follows:

        HTTP/1.1 400 Bad Request
        ...
        Sec-WebSocket-Version: 13, 8, 7

    Note that the last response from the server might also look like:

        HTTP/1.1 400 Bad Request
        ...
        Sec-WebSocket-Version: 13
        Sec-WebSocket-Version: 8, 7

    The client now repeats the handshake that conforms to version 13:

        GET /chat HTTP/1.1
        Host: server.example.com
        Upgrade: websocket
        Connection: Upgrade
        ...
        Sec-WebSocket-Version: 13
  • Extension values in extension-param could be quoted-string in addition to token.

  • Clarify the way to support multiple versions of WebSocket protocol.

  • Payload length MUST be encoded in minimal number of bytes.

  • WebSocket MUST support TLS.

  • Sec-WebSocket-Key and Sec-WebSocketAccept header field MUST NOT appear more than once.

  • Sec-WebSocket-Extensions and Sec-WebSocket-Protocol header filed MAY appear multiple times in requests, but it MUST NOT appear more than once in responses. See rfc6455 section 11.3.2 for more information

  • Sec-WebSocket-Version header filed MAY appear multiple times in responses, but it MUST NOT appear more than once in requests.

  • Status code 1007 was changed.

HyBi 13

Request:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 13

Response:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Protocol: chat

Date: 2011-08-31

Reference

Diff from HyBi 12

  • Now spec allow to use WWW-Authenticate header and 401 status explicitly.

  • Servers might redirect the client using a 3xx status code, but client are not required to follow them.

  • Clients' reconnection on abnormal closure must be delayed (between 0 and 5 seconds is a reasonable initial delay, and subsequent reconnection should be delayed longer by exponential backoff.

  • Sec-WebSocket-Version is 13.

  • Clients must fail the connection on receiving a subprotocol indication that was not present in the client requests in the opening handshake.

  • Status Codes was changes (Change 1004 as reserved, and add 1008, 1009, 1010).

HyBi 12

Request:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 8

Response:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Protocol: chat

Date: 2011-08-24

Reference

Diff from HyBi 11

  • Only editorial changes

  • Sec-WebSocket-Version value is still 8.

HyBi 11

Request:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 8

Response:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Protocol: chat

Date: 2011-08-23

Reference

Diff from HyBi 10

Sec-WebSocket-Version value is still 8, and 9/10/11 were reserved but were not and will not be used.

  • Sec-WebSocket-Origin -> Origin

  • Servers send all supported protocol numbers in Sec-WebSocket-Version header.

HyBi 10

Request:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Sec-WebSocket-Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 8

Response:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Protocol: chat

Date: 2011-07-11

Reference

Diff from HyBi 09

Sec-WebSocket-Version value is still 8.

  • Status code 1007.

  • Receiving strings including invalid UTF-8 result in Fail.

HyBi 09

Request:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Sec-WebSocket-Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 8

Response:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Protocol: chat

Date: 2011-06-13

Reference

Diff from HyBi 08

Sec-WebSocket-Version value is still 8.

  • On receiving a frame with any of RSV1-3 raised but no extension negotiated, Fail the WebSocket Connection.

HyBi 08

Request:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Sec-WebSocket-Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 8

Response:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Protocol: chat

Date: 2011-06-07

Reference

Diff from HyBi 07

  • Absolute path is now allowed for resource.

  • extension parameter is token.

  • Sec-WebSocket-Protocol from server to client is token.

  • Status code 1005 and 1006 are added, and all codes are unsigned.

  • Internal error results in 1006.

  • HTTP fallback status codes are clarified.

  • The value of Sec-WebSocket-Version is now 8

HyBi 07

Request:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Sec-WebSocket-Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 7

Response:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Protocol: chat

Date: 2011-04-22

Reference

Diff from HyBi 06

HyBi 06

Request:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Sec-WebSocket-Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 6

Response:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Protocol: chat

Date: 2011-02-25

Reference

Diff from HyBi 05

  • The closing handshake was clarified and re-written. See rfc6455 changelog

  • Removed Sec-WebSocket-Nonce

  • Sec-WebSocket-Origin is optional for non-browser clients.

  • Connection header must INCLUDE Upgrade, rather than is equal to Upgrade

  • Editorial changes

HyBi 05

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Sec-WebSocket-Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 5

Response:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Nonce: AQIDBAUGBwgJCgsMDQ4PEC==
    Sec-WebSocket-Protocol: chat

Date: 2011-02-08

Reference

Diff from HyBi 04

  • Changed masking : SHA-1, client nonce, server nonce, CSPRNG -> CSPRNG only

  • Specified the body of close frame explicitly

  • ABNF fix for origin and protocol

  • Added detailed Sec-WebSocket-Extensions format specification

  • Removed all occurrence of Sec-WebSocket-Location

  • Added IANA Sec-WebSocket-Accept section

  • The value of Sec-WebSocket-Version is now 5

HyBi 04

Request:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Sec-WebSocket-Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 4

Response:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: me89jWimTRKTWwrS3aRrL53YZSo=
    Sec-WebSocket-Nonce: AQIDBAUGBwgJCgsMDQ4PEC==
    Sec-WebSocket-Protocol: chat

Date: 2011-01-11

Reference

Diff from HyBi 03

Requires BASE64 and SHA-1

  • Added frame masking

  • Changed opening handshake (Sec-WebSocket-Key1, Sec-WebSocket-Key2, key3, response -> Sec-WebSocket-Key, Sec-WebSocket-Nonce, Sec-WebSocket-Accept)

  • No more challenge and checksum in request and response body

  • Sec-WebSocket-Nonce containing a base64 16 bytes nonce in server response (see section 5.2.2)

  • Added Sec-WebSocket-Extensions for extension negotiation

  • Upgrade header is now case-insensitive (HTTP compliant)

  • Value of response header Upgrade is changed from WebSocket to websocket (all lower case)

  • Flipped MORE bit and renamed it to FIN bit

  • Renamed Sec-WebSocket-Draft to Sec-WebSocket-Version

  • Renamed Origin to Sec-WebSocket-Origin

  • Added ABNF (one used in HTTP RFC2616) clarification to Sec-WebSocket-Protocol

  • Changed subprotocols separator from SP to ‘,’

  • Removed Sec-WebSocket-Location

HyBi 03

Request:

    GET /demo HTTP/1.1
    Host: example.com
    Connection: Upgrade
    Sec-WebSocket-Key2: 12998 5 Y3 1  .P00
    Sec-WebSocket-Protocol: sample
    Upgrade: WebSocket
    Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5
    Origin: http://example.com

    ^n:ds[4U

Response:

    HTTP/1.1 101 WebSocket Protocol Handshake
    Upgrade: WebSocket
    Connection: Upgrade
    Sec-WebSocket-Origin: http://example.com
    Sec-WebSocket-Location: ws://example.com/demo
    Sec-WebSocket-Protocol: sample

    8jKS'y:G*Co,Wxa-

Date: 2010-10-17

Reference

The value of Sec-WebSocket-Draft is still 2

  • Added one known extension “compression”

  • Added close frame body matching step to closing handshake

HyBi 02

Request:

    GET /demo HTTP/1.1
    Host: example.com
    Connection: Upgrade
    Sec-WebSocket-Key2: 12998 5 Y3 1  .P00
    Sec-WebSocket-Protocol: sample
    Upgrade: WebSocket
    Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5
    Origin: http://example.com

    ^n:ds[4U

Response:

    HTTP/1.1 101 WebSocket Protocol Handshake
    Upgrade: WebSocket
    Connection: Upgrade
    Sec-WebSocket-Origin: http://example.com
    Sec-WebSocket-Location: ws://example.com/demo
    Sec-WebSocket-Protocol: sample

    8jKS'y:G*Co,Wxa-

Date: 2010-09-24

Reference

  • Added /defer cookies/ flag

  • Added Sec-WebSocket-Draft with a value of 2

HyBi 01

Request:

    GET /demo HTTP/1.1
    Host: example.com
    Connection: Upgrade
    Sec-WebSocket-Key2: 12998 5 Y3 1  .P00
    Sec-WebSocket-Protocol: sample
    Upgrade: WebSocket
    Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5
    Origin: http://example.com

    ^n:ds[4U

Response:

    HTTP/1.1 101 WebSocket Protocol Handshake
    Upgrade: WebSocket
    Connection: Upgrade
    Sec-WebSocket-Origin: http://example.com
    Sec-WebSocket-Location: ws://example.com/demo
    Sec-WebSocket-Protocol: sample

    8jKS'y:G*Co,Wxa-

Date: 2010-08-31

Reference

  • Changed frame format

  • Added extension mechanism (no negotiation yet)

Hixie 76 (HyBi 00)

Request:

    GET /demo HTTP/1.1
    Host: example.com
    Connection: Upgrade
    Sec-WebSocket-Key2: 12998 5 Y3 1  .P00
    Sec-WebSocket-Protocol: sample
    Upgrade: WebSocket
    Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5
    Origin: http://example.com

    ^n:ds[4U

Response:

    HTTP/1.1 101 WebSocket Protocol Handshake
    Upgrade: WebSocket
    Connection: Upgrade
    Sec-WebSocket-Origin: http://example.com
    Sec-WebSocket-Location: ws://example.com/demo
    Sec-WebSocket-Protocol: sample

    8jKS'y:G*Co,Wxa-

Date: 2010-05-06

Reference HyBi 00

Reference Hixie 76

Requires Digest::MD5

  • Added challenge/response handshaking using binary data with header fields Sec-WebSocket-Key1 and Sec-WebSocket-Key2

  • Added closing handshake

Hixie 75

Date: 2010-02-04

Reference

From version 10 to 75 there is an optional WebSocket-Protocol header field, but from version 0 to 7, there is none at all. Note that version 8 and 9 are skipped.

Request:

    GET /demo HTTP/1.1
    Upgrade: WebSocket
    Connection: Upgrade
    Host: example.com
    Origin: http://example.com
    WebSocket-Protocol: sample

Response:

    HTTP/1.1 101 Web Socket Protocol Handshake
    Upgrade: WebSocket
    Connection: Upgrade
    WebSocket-Origin: http://example.com
    WebSocket-Location: ws://example.com/demo
    WebSocket-Protocol: sample

AUTHOR

Jacques Deguest <jack@deguest.jp>

SEE ALSO

perl

COPYRIGHT & LICENSE

Copyright(c) 2021 DEGUEST Pte. Ltd.

You can use, copy, modify and redistribute this package and associated files under the same terms as Perl itself.