Class: Kronk::HTTP

Inherits:
Net::HTTP
  • Object
show all
Defined in:
lib/kronk/http.rb

Overview

Wrapper for Net::HTTP

Constant Summary collapse

CONN_POOL =

Pool of open connections.

Hash.new{|h,k| h[k] = []}
CONN_USED =

Connections currently in use

{}
MAX_CONN_AGE =

Max time a pool should hold onto an open connection.

10
C_MUTEX =
Mutex.new
M_MUTEX =
Mutex.new
POOL_MUTEX =
Hash.new{|h,k| M_MUTEX.synchronize{ h[k] = Mutex.new} }

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Class Attribute Details

.total_connObject

Total number of http connections ever created.



12
13
14
# File 'lib/kronk/http.rb', line 12

def total_conn
  @total_conn
end

Instance Attribute Details

#last_usedObject

Last time this http connection was used



32
33
34
# File 'lib/kronk/http.rb', line 32

def last_used
  @last_used
end

Class Method Details

.conn_countObject

Total number of currently active connections.



71
72
73
74
75
# File 'lib/kronk/http.rb', line 71

def self.conn_count
  M_MUTEX.synchronize do
    CONN_USED.length + CONN_POOL.values.flatten.length
  end
end

.get_conn(conn_id) ⇒ Object

Get a connection from the pool based on a connection id. Connection ids are an Array with the following values:

[addr, port, ssl, proxy_addr, proxy_port, proxy_username]


83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/kronk/http.rb', line 83

def self.get_conn(conn_id)
  conn = nil
  pool = CONN_POOL[conn_id]

  POOL_MUTEX[conn_id].synchronize do
    while !pool.empty? && (!conn || conn.closed? || conn.outdated?)
      conn = pool.shift
    end
  end

  conn
end

.new(address, port = nil, opts = {}) ⇒ Object

Create a new http connection or get an existing, unused keep-alive connection. Supports the following options:

:poxy

String or Hash with proxy settings (see Kronk::Request)

:ssl

Boolean specifying whether to use SSL or not



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/kronk/http.rb', line 41

def self.new(address, port=nil, opts={})
  port ||= HTTP.default_port
  proxy  = opts[:proxy] || {}

  conn_id = [address, port, !!opts[:ssl],
              proxy[:host], proxy[:port], proxy[:username]]

  conn = get_conn(conn_id)

  if !conn
    conn  = super(address, port, proxy[:host], proxy[:port],
                    proxy[:username], proxy[:password])

    if opts[:ssl]
      require 'net/https'
      conn.use_ssl = true
    end

    C_MUTEX.synchronize{ @total_conn += 1 }
  end

  CONN_USED[conn] = true

  conn
end

Instance Method Details

#add_to_poolObject

Put this http connection in the pool for use by another request.



100
101
102
103
104
105
106
107
108
# File 'lib/kronk/http.rb', line 100

def add_to_pool
  return if closed? || outdated?
  conn_id = [@address, @port, @use_ssl,
              proxy_address, proxy_port, proxy_user]

  POOL_MUTEX[conn_id].synchronize do
    CONN_POOL[conn_id] << self
  end
end

#closed?Boolean

Check if the socket for this http connection can be read and written to.

Returns:

  • (Boolean)


123
124
125
# File 'lib/kronk/http.rb', line 123

def closed?
  !@socket || @socket.closed?
end

#outdated?Boolean

Returns true if this connection was last used more than MAX_CONN_AGE seconds ago.

Returns:

  • (Boolean)


115
116
117
# File 'lib/kronk/http.rb', line 115

def outdated?
  Time.now - @last_used > MAX_CONN_AGE
end

#request(req, body = nil, opts = {}, &block) ⇒ Object

Make an http request on the connection. Takes a Net::HTTP request instance for the ‘req’ argument.



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/kronk/http.rb', line 132

def request(req, body=nil, opts={}, &block)  # :yield: +response+
  unless started?
    start {
      req['connection'] ||= 'close'
      return request(req, body, &block)
    }
  end
  if proxy_user()
    req.proxy_basic_auth proxy_user(), proxy_pass() unless use_ssl?
  end
  req.set_body_internal body
  res = transport_request(req, true, opts, &block)
  if sspi_auth?(res)
    sspi_auth(req)
    res = transport_request(req, true, opts, &block)
  end
  res
end