Class: Stub::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/uaa/stub/server.rb

Overview


request handler logic – server is initialized with a class derived from this. there will be one instance of this object per connection.

Direct Known Subclasses

CF::UAA::StubUAAConn, CF::UAA::TokenCatcher

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(server) ⇒ Base

Returns a new instance of Base.



173
174
175
# File 'lib/uaa/stub/server.rb', line 173

def initialize(server)
  @server, @request, @reply, @match = server, Request.new, Reply.new, nil
end

Instance Attribute Details

#matchObject

Returns the value of attribute match.



136
137
138
# File 'lib/uaa/stub/server.rb', line 136

def match
  @match
end

#replyObject

Returns the value of attribute reply.



136
137
138
# File 'lib/uaa/stub/server.rb', line 136

def reply
  @reply
end

#requestObject

Returns the value of attribute request.



136
137
138
# File 'lib/uaa/stub/server.rb', line 136

def request
  @request
end

#serverObject

Returns the value of attribute server.



136
137
138
# File 'lib/uaa/stub/server.rb', line 136

def server
  @server
end

Class Method Details

.find_route(request) ⇒ Object



158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/uaa/stub/server.rb', line 158

def self.find_route(request)
  fail unless EM.reactor_thread?
  if @routes && (rary = @routes[request.method])
    rary.each { |r; m|
      next unless (m = r[0].match(request.path))
      r[1].each { |k, v|
        next if v.match(request.headers[k])
        return reply_in_kind(400,  "header '#{k}: #{request.headers[k]}' is not accepted")
      }
      return [m, r[2]]
    }
  end
  [nil, :default_route]
end

.route(http_methods, matcher, filters = {}, &handler) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/uaa/stub/server.rb', line 138

def self.route(http_methods, matcher, filters = {}, &handler)
  fail unless !EM.reactor_running? || EM.reactor_thread?
  matcher = Regexp.new("^#{Regexp.escape(matcher.to_s)}$") unless matcher.is_a?(Regexp)
  filters = filters.each_with_object({}) { |(k, v), o|
    o[k.downcase] = v.is_a?(Regexp) ? v : Regexp.new("^#{Regexp.escape(v.to_s)}$")
  }
  @routes ||= {}
  @route_number = @route_number.to_i + 1
  route_name = "route_#{@route_number}".to_sym
  define_method(route_name, handler)
  [*http_methods].each do |m|
    m = m.to_s.downcase
    @routes[m] ||= []
    i = @routes[m].index { |r| r[0].to_s.length < matcher.to_s.length }
    unless i && @routes[m][i][0] == matcher
      @routes[m].insert(i || -1, [matcher, filters, route_name])
    end
  end
end

Instance Method Details

#default_routeObject



177
# File 'lib/uaa/stub/server.rb', line 177

def default_route; reply_in_kind(404, error: "path not handled") end

#processObject



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/uaa/stub/server.rb', line 179

def process
  @reply = Reply.new
  if server.root
    return default_route unless request.path.start_with?(server.root)
    request.path.slice!(0..server.root.length - 1)
  end
  @match, handler = self.class.find_route(request)
  server.logger.debug "processing #{request.method} to path #{request.path}"
  send handler
  reply.headers['connection'] ||= request.headers['connection'] if request.headers['connection']
  server.logger.debug "replying to path #{request.path} with #{reply.body.length} bytes of #{reply.headers['content-type']}"
  #server.logger.debug "full reply is: #{reply.body.inspect}"
rescue Exception => e
  server.logger.debug "exception processing request: #{e.message}"
  server.trace { e.backtrace }
  reply_in_kind 500, e
end

#reply_in_kind(status = nil, info) ⇒ Object



197
198
199
200
201
202
203
# File 'lib/uaa/stub/server.rb', line 197

def reply_in_kind(status = nil, info)
  case request.headers['accept']
  when /application\/json/ then reply.json(status, info)
  when /text\/html/ then reply.html(status, info)
  else reply.text(status, info)
  end
end