Class: TelnetQ::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/telnet_q/base.rb

Overview

This class implements RFC 1143 - The Q Method of implementing TELNET option negotiation.

There are two sides to the conversation: “us” and “him”. “us” refers to the local party; “him” refers to the remote party. (This is the terminology used in the RFC.)

Telnet options are integers between 0 and 255. The current list of options is available at: www.iana.org/assignments/telnet-options

Options:

:us

The list of options the local party should initially enable. When the connection is established, the local party sends a WILL request for each of these options. Note that if the remote party sends DONT in response to our request, the option will remain disabled.

:him

The list of options we want the remote party should initially enable. When the connection is established, the local party sends a DO request for each of these options. Note that if the remote party sends WONT in response to our request, the option will remain disabled.

Example usage:

TelnetQ::Base.new(:us => [0,3], :him => [0,1,3])

Direct Known Subclasses

SocketQ

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Base

Returns a new instance of Base.



31
32
33
34
35
36
37
38
39
40
# File 'lib/telnet_q/base.rb', line 31

def initialize(options={})
  @state_machines = {
    :us => {},
    :him => {},
  }
  @supported_options = {
    :us => Set.new(options[:us] || []),
    :him => Set.new(options[:him].uniq || []),
  }
end

Instance Method Details

#enabled?(party, option) ⇒ Boolean

Check whether the option is currently enabled

Returns:

  • (Boolean)


73
74
75
76
# File 'lib/telnet_q/base.rb', line 73

def enabled?(party, option)
  sm = state_machine(party, option)
  sm.state == :yes
end

#forbid(party, option) ⇒ Object

Ask the specified party to disable this option.

party may be one of :us or :them.



91
92
93
94
95
96
# File 'lib/telnet_q/base.rb', line 91

def forbid(party, option)
  sm = state_machine(party, option)
  @supported_options[party].delete(option)
  sm.ask_disable unless sm.state == :no
  nil
end

#inspectObject



46
47
48
49
50
# File 'lib/telnet_q/base.rb', line 46

def inspect
  us = @state_machines[:us].keys.sort.map{|opt| "#{opt}:#{@state_machines[:us][opt].state}"}.join(" ")
  him = @state_machines[:him].keys.sort.map{|opt| "#{opt}:#{@state_machines[:him][opt].state}"}.join(" ")
  "#<#{self.class.name} us(#{us}) him(#{him})>"
end

#received_message(verb, option) ⇒ Object

Invoke this when a TELNET negotiation message is received.

Example usage:

tq = TelnetQ::Base.new(...)
tq.received_message(:do, 0)       # Remote party requesting that we enable binary transmission on our side
tq.received_message(:will, 0)     # Remote party requesting that to enable binary transmission on his side.


58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/telnet_q/base.rb', line 58

def received_message(verb, option)
  case verb
  when :do, :dont
    party = :us
  when :will, :wont
    party = :him
  else
    raise ArgumentError.new("invalid verb #{verb.inspect}")
  end
  sm = state_machine(party, option)
  sm.received(verb)
  nil
end

#request(party, option) ⇒ Object

Ask the specified party enable this option.

party may be one of :us or :them.



81
82
83
84
85
86
# File 'lib/telnet_q/base.rb', line 81

def request(party, option)
  sm = state_machine(party, option)
  @supported_options[party] << option
  sm.ask_enable unless sm.state == :yes
  nil
end

#startObject



42
43
44
# File 'lib/telnet_q/base.rb', line 42

def start
  initial_requests
end