Class: Vines::Stream::Http

Inherits:
Client show all
Defined in:
lib/vines/stream/http.rb,
lib/vines/stream/http/auth.rb,
lib/vines/stream/http/bind.rb,
lib/vines/stream/http/ready.rb,
lib/vines/stream/http/start.rb,
lib/vines/stream/http/request.rb,
lib/vines/stream/http/session.rb,
lib/vines/stream/http/sessions.rb,
lib/vines/stream/http/bind_restart.rb

Defined Under Namespace

Classes: Auth, Bind, BindRestart, Ready, Request, Session, Sessions, Start

Constant Summary

Constants inherited from Client

Client::MECHANISMS

Constants inherited from Vines::Stream

ERROR, PAD

Instance Attribute Summary collapse

Attributes inherited from Vines::Stream

#config, #domain, #user

Instance Method Summary collapse

Methods inherited from Client

#authentication_mechanisms, #method_missing, #ssl_handshake_completed, #unbind

Methods inherited from Vines::Stream

#advance, #available_resources, #cert_domain_matches?, #close_connection, #connected_resources, #encrypt, #encrypt?, #error, #interested_resources, #post_init, #receive_data, #reset, #router, #ssl_verify_peer, #storage, #unbind, #update_user_streams, #vhost

Methods included from Log

#log

Constructor Details

#initialize(config) ⇒ Http

Returns a new instance of Http.



8
9
10
11
# File 'lib/vines/stream/http.rb', line 8

def initialize(config)
  super
  @session = Http::Session.new(self)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Vines::Stream::Client

Instance Attribute Details

#sessionObject

Returns the value of attribute session.



6
7
8
# File 'lib/vines/stream/http.rb', line 6

def session
  @session
end

Instance Method Details

#create_parserObject

Override Stream#create_parser to provide an HTTP parser rather than a Nokogiri XML parser.



15
16
17
18
19
20
21
22
23
24
# File 'lib/vines/stream/http.rb', line 15

def create_parser
  @parser = ::Http::Parser.new.tap do |p|
    body = ''
    p.on_body = proc {|data| body << data }
    p.on_message_complete = proc {
      process_request(Request.new(self, @parser, body))
      body = ''
    }
  end
end

#parse_body(body) ⇒ Object

Return an array of Node objects inside the body element. TODO This parses the XML again just to strip namespaces. Figure out Nokogiri namespace handling instead.



72
73
74
75
76
77
# File 'lib/vines/stream/http.rb', line 72

def parse_body(body)
  body.namespace = nil
  body.elements.map do |node|
    Nokogiri::XML(node.to_s.sub(' xmlns="jabber:client"', '')).root
  end
end

#process_request(request) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/vines/stream/http.rb', line 42

def process_request(request)
  if request.path == self.bind && request.options?
    request.reply_to_options
  elsif request.path == self.bind
    body = Nokogiri::XML(request.body).root
    if session = Sessions[body['sid']]
      @session = session
    else
      @session = Http::Session.new(self)
    end
    @session.request(request)
    @nodes.push(body)
  else
    request.reply_with_file(self.root)
  end
end

#start(node) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/vines/stream/http.rb', line 79

def start(node)
  domain, type, hold, wait, rid = %w[to content hold wait rid].map {|a| (node[a] || '').strip }
  version = node.attribute_with_ns('version', NAMESPACES[:bosh]).value rescue nil

  @session.inactivity = 20
  @session.domain = domain
  @session.content_type = type unless type.empty?
  @session.hold = hold.to_i unless hold.empty?
  @session.wait = wait.to_i unless wait.empty?

  raise StreamErrors::UndefinedCondition.new('rid required') if rid.empty?
  raise StreamErrors::UnsupportedVersion unless version == '1.0'
  raise StreamErrors::ImproperAddressing unless valid_address?(domain)
  raise StreamErrors::HostUnknown unless config.vhost?(domain)
  raise StreamErrors::InvalidNamespace unless node.namespaces['xmlns'] == NAMESPACES[:http_bind]

  Sessions[@session.id] = @session
  send_stream_header
end

#stream_writeObject

Alias the Stream#write method before overriding it so we can call it later from a Session instance.



61
# File 'lib/vines/stream/http.rb', line 61

alias :stream_write :write

#terminateObject



99
100
101
102
103
104
105
106
# File 'lib/vines/stream/http.rb', line 99

def terminate
  doc = Nokogiri::XML::Document.new
  node = doc.create_element('body',
    'type'  => 'terminate',
    'xmlns' => NAMESPACES[:http_bind])
  @session.reply(node)
  close_stream
end

#valid_session?(sid) ⇒ Boolean

If the session ID is valid, switch this stream’s session to the new ID and return true. Some clients, like Google Chrome, reuse one stream for multiple sessions.

Returns:

  • (Boolean)


29
30
31
32
33
34
# File 'lib/vines/stream/http.rb', line 29

def valid_session?(sid)
  if session = Sessions[sid]
    @session = session
  end
  !!session
end

#write(data) ⇒ Object

Override Stream#write to queue stanzas rather than immediately writing to the stream. Stanza responses must be paired with a queued request.



65
66
67
# File 'lib/vines/stream/http.rb', line 65

def write(data)
  @session.write(data)
end