class Optic::DocumentingMiddleware

Public Class Methods

new(app, options = {}) click to toggle source
# File lib/optic/middleware.rb, line 6
def initialize(app, options = {})
  @app = app
  @app.freeze
  @host = ENV['OPTIC_SERVER_HOST'] || 'localhost'
end

Public Instance Methods

call(env) click to toggle source
# File lib/optic/middleware.rb, line 12
def call(env)
  req = Rack::Request.new(env)
  res = @app.call(env)
  # Log request and response
  logRequestAndResponse(req, res)
  # Return Response without changing
  res
end

Private Instance Methods

addHeaders(headers, request) click to toggle source
# File lib/optic/middleware.rb, line 31
def addHeaders(headers, request)
  headers.each do |key, value|
    request.add_field(key, value)
  end
end
headerHash(message) click to toggle source
# File lib/optic/middleware.rb, line 23
def headerHash(message)
  Hash[*message.select {|k, v| k.start_with? 'HTTP_'}
            .collect {|k, v| [k.sub(/^HTTP_/, ''), v]}
            .collect {|k, v| [k.split('_').collect(&:capitalize).join('-'), v]}
            .sort
            .flatten]
end
logRequestAndResponse(req, res) click to toggle source
# File lib/optic/middleware.rb, line 37
def logRequestAndResponse(req, res)

  # Log Request to Optic

  logging_request = Net::HTTP.const_get(req.request_method.capitalize).new(req.fullpath)
  # Include Headers
  addHeaders(headerHash(req.env), logging_request)
  # Include body
  if req.body
    logging_request.body_stream = req.body
    logging_request.content_length = req.content_length.to_i
    logging_request.content_type = req.content_type if req.content_type
    logging_request.body_stream.rewind
  end

  # Send request to request logging endpoint
  http = Net::HTTP.new(@host, 30334)
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  logging_request_response = http.start do
    http.request(logging_request)
  end

  logging_request_response.code
  # Save the ID Optic assigns this request
  interactionId = logging_request_response.body || ""

  # Log Response to Optic
  resStatus, resHeaders, resBody = res

  logging_response = Net::HTTP.const_get("Post").new("/interactions/" + interactionId + "/status/" + resStatus.to_s)
  addHeaders(resHeaders, logging_response)
  if logging_response.request_body_permitted? && resBody
    bodyData = ""
    resBody.each do |line|
      bodyData << line
    end
    logging_response.body = bodyData
    logging_response.content_length = bodyData.bytesize.to_s
  end

  http = Net::HTTP.new(@host, 30335)
  logging_response_response = http.start do
    http.request(logging_response)
  end

end