Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 8e2fb962ef
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 73 lines (57 sloc) 2.231 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 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 66 67 68 69 70 71 72 73
module Rack
  module SpeedTracer

    class Context
      TRACER_PATH = /^\/speedtracer/.freeze
      CONTENT_TYPE = 'application/json;charset=UTF-8'.freeze

      attr_accessor :db

      def initialize(app, options = {}, &blk)
        @app = app
        @uuid = UUID.new

        # TODO: storage strategy...
        # initialize_options with options
        # yield self if block_given?

        @db = {}
      end

      def call(env)
        if env['PATH_INFO'].match(TRACER_PATH)

          resp = Rack::Response.new('', 200)
          resp['Content-Type'] = CONTENT_TYPE

          case env['REQUEST_METHOD']
            when 'HEAD' then
              # SpeedTracer dispatches HEAD requests to verify the
              # tracer endpoint when it detects the X-TraceUrl
              # header for the first time. After the initial load
              # the verification is cached by the extension.
              #
              # By default, we'll return 200.

            when 'GET' then
              # GET requests for specific trace are generated by
              # the extension when the user expands the network
              # resource tab. Hence, server-side tracer data is
              # request on-demand, and we need to store it for
              # some time.

              qs = Rack::Utils.parse_query(env['QUERY_STRING'])
              if qs['id'] && @db[qs['id']]
                resp.write @db[qs['id']]
              else
                # Invalid request or missing request trace id
                resp.status = 404
              end
            else
              # SpeedTracer should only issue GET & HEAD requests
              resp.status = 400
          end

          return resp.finish
        end

        env['st.id'] = @uuid.generate
        env['st.tracer'] = Tracer.new(env['st.id'], env['REQUEST_METHOD'], env['REQUEST_URI'])

        @status, @headers, @response = @app.call(env)
        @db[env['st.id']] = env['st.tracer'].finish

        # set the TraceUrl header to notify SpeedTracer that
        # serverside meta-data is available for this request
        @headers['X-TraceUrl'] = '/speedtracer?id=' + env['st.id']

        [@status, @headers, @response]
      end
    end

  end
end
Something went wrong with that request. Please try again.