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 Vines::Stream

ERROR, PAD

Instance Attribute Summary collapse

Attributes inherited from Client

#config

Attributes inherited from Vines::Stream

#domain, #user

Instance Method Summary collapse

Methods inherited from Client

#method_missing, #ssl_handshake_completed, #unbind

Methods inherited from Vines::Stream

#advance, #cert_domain_matches?, #close_connection, #encrypt, #encrypt?, #error, #receive_data, #router, #ssl_verify_peer, #storage, #unbind, #update_user_streams

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

#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.



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

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

#post_initObject



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

def post_init
  super
  router.delete(self)
  @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

#process_request(request) ⇒ Object



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

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

#start(node) ⇒ Object



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

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::HostUnknown unless @config.vhost?(domain)
  raise StreamErrors::InvalidNamespace unless node.namespaces['xmlns'] == NAMESPACES[:http_bind]

  Sessions[@session.id] = @session
  router << @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.



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

alias :stream_write :write

#terminateObject



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

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.



63
64
65
# File 'lib/vines/stream/http.rb', line 63

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