Class: NewRelic::Security::WebSocket::Handshake::Server

Inherits:
Base
  • Object
show all
Defined in:
lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/server.rb

Overview

Construct or parse a server WebSocket handshake.

Examples:

handshake = NewRelic::Security::WebSocket::Handshake::Server.new

# Parse client request
@handshake << "GET /demo HTTP/1.1\\r\nUpgrade: websocket\\r\nConnection: Upgrade\\r\nHost: example.com\\r\nOrigin: http://example.com\\r\nSec-WebSocket-Version: 13\\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\\r\n\\r\n"

# 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

#default_port, #default_port?, #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:

  • (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/newrelic_security/websocket-client-simple/websocket-ruby/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 << "GET /demo HTTP/1.1\nUpgrade: websocket\nConnection: Upgrade\nHost: example.com\nOrigin: http://example.com\nSec-WebSocket-Version: 13\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\n\n"

Parameters:

  • Data to add



64
65
66
67
# File 'lib/newrelic_security/websocket-client-simple/websocket-ruby/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 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/newrelic_security/websocket-client-simple/websocket-ruby/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:

  • 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/newrelic_security/websocket-client-simple/websocket-ruby/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:

  • host



131
132
133
# File 'lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/server.rb', line 131

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

#portInteger

Port of server according to client header

Returns:

  • port



137
138
139
# File 'lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/server.rb', line 137

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

#should_respond?Boolean

Should send content to client after finished parsing?

Returns:

  • true



125
126
127
# File 'lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/server.rb', line 125

def should_respond?
  true
end