rswag/rswag

[REQUEST] specifying the Origin header

jessevdp opened this issue · 0 comments

Is your feature request related to a problem? Please describe.

An API I'm working on relies on the HTTP Origin header via CORS requests to determine some context for in which context the API is being used. (The details don't matter.) The Origin header is expected on all requests.

I started out adding an Origin parameter in: :header. This works in specs. All good.

Unfortunately our client-side application generates an API client based on the OpenAPI spec generated by RSwag. It turns out... a custom parameter that specifies the use of a reserved HTTP header like "Origin"... not a good idea.

Describe the solution you'd like

Perhaps we could populate the "Origin" header simply by doing:

let(:Origin) { "https://my-origin.com" }

Much like we can already do:

let(:Host) { "..." }

Workaround

I've added the following patch to my setup to cover this. The patch also includes references to the lines where a solution like this might be implemented.

module Rswag
  module Specs
    class CustomRequestFactory < RequestFactory

      # [https://github.com/rswag/rswag/blob/6c07c71d41e766e5c1084c789507828e8ed192cc/rswag-specs/lib/rswag/specs/request_factory.rb#L198]
      def add_headers(request, metadata, swagger_doc, parameters, example)
        super

        # THE CHANGED LINES
        origin = example.try(:Origin)
        request[:headers].merge!("Origin" => origin) if origin.present?
      end

    end
  end
end

module Rswag
  module Specs
    module ExampleHelpers

      # [https://github.com/rswag/rswag/blob/6c07c71d41e766e5c1084c789507828e8ed192cc/rswag-specs/lib/rswag/specs/example_helpers.rb#L9]
      def submit_request(metadata)
        request = CustomRequestFactory.new.build_request(metadata, self) # THE CHANGED LINE

        if RAILS_VERSION < 5
          send(
            request[:verb],
            request[:path],
            request[:payload],
            request[:headers]
          )
        else
          send(
            request[:verb],
            request[:path],
            params: request[:payload],
            headers: request[:headers]
          )
        end
      end

    end
  end
end

1st party support

Would you be open to having a solution like this?