Class: WebSocket::Handshake::Server

Inherits:
Base
  • Object
show all
Defined in:
lib/websocket/handshake/server.rb

Overview

Construct or parse a server WebSocket handshake.

Examples:

handshake = WebSocket::Handshake::Server.new

# Parse client request
@handshake << <<EOF
GET /demo HTTP/1.1\r
Upgrade: websocket\r
Connection: Upgrade\r
Host: example.com\r
Origin: http://example.com\r
Sec-WebSocket-Version: 13\r
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r
\r
EOF

# All data received?
@handshake.finished?

# No parsing errors?
@handshake.valid?

# Create response
@handshake.to_s # HTTP/1.1 101 Switching Protocols
                # Upgrade: websocket
                # Connection: Upgrade
                # Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

Instance Attribute Summary

Attributes inherited from Base

#headers, #path, #protocols, #query, #secure, #state, #version

Attributes included from ExceptionHandler

#error

Instance Method Summary collapse

Methods inherited from Base

#finished?, #leftovers, #to_s, #uri, #valid?

Methods included from NiceInspect

#inspect

Methods included from ExceptionHandler

included

Constructor Details

#initialize(args = {}) ⇒ Server

Initialize new WebSocket Server

Examples:

Websocket::Handshake::Server.new(secure: true)

Parameters:

  • args (Hash) (defaults to: {})

    Arguments for server

Options Hash (args):

  • :secure (Boolean)

    If true then server will use wss:// protocol

  • :protocols (Array<String>)

    an array of supported sub-protocols


44
45
46
47
# File 'lib/websocket/handshake/server.rb', line 44

def initialize(args = {})
  super
  @secure ||= false
end

Instance Method Details

#<<(data) ⇒ Object

Add text of request from Client. This method will parse content immediately and update version, state and error(if neccessary)

Examples:

@handshake << <<EOF
GET /demo HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==

EOF

Parameters:

  • data (String)

    Data to add


64
65
66
67
# File 'lib/websocket/handshake/server.rb', line 64

def <<(data)
  super
  set_version if parse_data
end

#from_hash(hash) ⇒ Object

Parse the request from hash

Examples:

@handshake.from_hash(hash)

Parameters:

  • hash

    Hash to import data

Options Hash (hash):

  • :headers (Hash)

    HTTP headers of request, downcased

  • :path (String)

    Path for request(without host and query string)

  • :query (String)

    Query string for request

  • :body (String)

    Body of request(if exists)


113
114
115
116
117
118
119
120
121
# File 'lib/websocket/handshake/server.rb', line 113

def from_hash(hash)
  @headers = hash[:headers] || {}
  @path = hash[:path] || '/'
  @query = hash[:query] || ''
  @leftovers = hash[:body]

  set_version
  @state = :finished
end

#from_rack(env) ⇒ Object

Parse the request from a rack environment

Examples:

@handshake.from_rack(env)

Parameters:

  • env

    Rack Environment


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/websocket/handshake/server.rb', line 75

def from_rack(env)
  @headers = env.select { |key, _value| key.to_s.start_with? 'HTTP_' }.each_with_object({}) do |tuple, memo|
    key, value = tuple
    memo[key.gsub(/\AHTTP_/, '').tr('_', '-').downcase] = value
  end

  @path      = env['REQUEST_PATH']
  @query     = env['QUERY_STRING']

  set_version

  # Passenger is blocking on read
  # Unicorn doesn't support readpartial
  # Maybe someone is providing even plain string?
  # Better safe than sorry...
  if @version == 76
    input = env['rack.input']
    @leftovers = if input.respond_to?(:readpartial)
                   input.readpartial
                 elsif input.respond_to?(:read)
                   input.read
                 else
                   input.to_s
                 end
  end

  @state = :finished
end

#hostString

Host of server according to client header

Returns:

  • (String)

    host


131
132
133
# File 'lib/websocket/handshake/server.rb', line 131

def host
  @headers['host'].to_s.split(':')[0].to_s
end

#portString

Port of server according to client header

Returns:

  • (String)

    port


137
138
139
# File 'lib/websocket/handshake/server.rb', line 137

def port
  @headers['host'].to_s.split(':')[1]
end

#should_respond?Boolean

Should send content to client after finished parsing?

Returns:

  • (Boolean)

    true


125
126
127
# File 'lib/websocket/handshake/server.rb', line 125

def should_respond?
  true
end