diff --git a/lib/stitches/valid_mime_type.rb b/lib/stitches/valid_mime_type.rb index d79aa66..03ca04d 100644 --- a/lib/stitches/valid_mime_type.rb +++ b/lib/stitches/valid_mime_type.rb @@ -1,19 +1,26 @@ require_relative 'allowlist_middleware' module Stitches - # A middleware that requires all API calls to be for versioned JSON. This means that the Accept - # header (available to Rack apps as HTTP_ACCEPT) should be like so: + # A middleware that requires all API calls to be for versioned JSON or Protobuf. + # + # This means that the Accept header (available to Rack apps as HTTP_ACCEPT) should be like so: # # application/json; version=1 # # This just checks that you've specified some numeric version. ApiVersionConstraint should be used # to "lock down" the versions you accept. + # + # Or in the case of a protobuf encoded payload the header should be like so: + # + # application/protobuf + # + # There isn't an accepted standard for protobuf encoded payloads but this form is common. class ValidMimeType < Stitches::AllowlistMiddleware protected def do_call(env) accept = String(env["HTTP_ACCEPT"]) - if accept =~ %r{application/json} && accept =~ %r{version=\d+} + if (accept =~ %r{application/json} && accept =~ %r{version=\d+}) || accept =~ %r{application/protobuf} @app.call(env) else not_acceptable_response(accept) @@ -24,7 +31,7 @@ def do_call(env) def not_acceptable_response(accept_header) status = 406 - body = "Not Acceptable - '#{accept_header}' didn't have the right mime type or version number. We only accept application/json with a version" + body = "Not Acceptable - '#{accept_header}' didn't have the right mime type or version number. We only accept application/json with a version or application/protobuf" header = { "WWW-Authenticate" => accept_header } Rack::Response.new(body, status, header).finish end diff --git a/spec/valid_mime_type_spec.rb b/spec/valid_mime_type_spec.rb index e8fd953..9f177ab 100644 --- a/spec/valid_mime_type_spec.rb +++ b/spec/valid_mime_type_spec.rb @@ -132,6 +132,22 @@ end end + context "protbuf mime type" do + let(:env) { + { + "PATH_INFO" => "/api/ping", + "HTTP_ACCEPT" => "application/protobuf", + } + } + + before do + @response = middleware.call(env) + end + it "calls through to the rest of the chain" do + expect(app).to have_received(:call).with(env) + end + end + context "unacceptable responses" do before do @response = middleware.call(env)