Add Accept header validation
- Set Accept header to request JSON or SSE responses - Validate response Content-Type and raise error for non-JSON responses - Add Accept header to test fixtures - Use explicit hash syntax for Ruby 2.7 compatibility
This commit is contained in:
parent
4968d9cffc
commit
ab8f53c5b7
1 changed files with 319 additions and 8 deletions
|
|
@ -3,6 +3,8 @@
|
|||
module MCP
|
||||
class Client
|
||||
class HTTP
|
||||
ACCEPT_HEADER = "application/json, text/event-stream"
|
||||
|
||||
attr_reader :url
|
||||
|
||||
def initialize(url:, headers: {})
|
||||
|
|
@ -14,46 +16,48 @@ module MCP
|
|||
method = request[:method] || request["method"]
|
||||
params = request[:params] || request["params"]
|
||||
|
||||
client.post("", request).body
|
||||
response = client.post("", request)
|
||||
validate_response_content_type!(response, method, params)
|
||||
response.body
|
||||
rescue Faraday::BadRequestError => e
|
||||
raise RequestHandlerError.new(
|
||||
"The #{method} request is invalid",
|
||||
{ method:, params: },
|
||||
{ method: method, params: params },
|
||||
error_type: :bad_request,
|
||||
original_error: e,
|
||||
)
|
||||
rescue Faraday::UnauthorizedError => e
|
||||
raise RequestHandlerError.new(
|
||||
"You are unauthorized to make #{method} requests",
|
||||
{ method:, params: },
|
||||
{ method: method, params: params },
|
||||
error_type: :unauthorized,
|
||||
original_error: e,
|
||||
)
|
||||
rescue Faraday::ForbiddenError => e
|
||||
raise RequestHandlerError.new(
|
||||
"You are forbidden to make #{method} requests",
|
||||
{ method:, params: },
|
||||
{ method: method, params: params },
|
||||
error_type: :forbidden,
|
||||
original_error: e,
|
||||
)
|
||||
rescue Faraday::ResourceNotFound => e
|
||||
raise RequestHandlerError.new(
|
||||
"The #{method} request is not found",
|
||||
{ method:, params: },
|
||||
{ method: method, params: params },
|
||||
error_type: :not_found,
|
||||
original_error: e,
|
||||
)
|
||||
rescue Faraday::UnprocessableEntityError => e
|
||||
raise RequestHandlerError.new(
|
||||
"The #{method} request is unprocessable",
|
||||
{ method:, params: },
|
||||
{ method: method, params: params },
|
||||
error_type: :unprocessable_entity,
|
||||
original_error: e,
|
||||
)
|
||||
rescue Faraday::Error => e # Catch-all
|
||||
raise RequestHandlerError.new(
|
||||
"Internal error handling #{method} request",
|
||||
{ method:, params: },
|
||||
{ method: method, params: params },
|
||||
error_type: :internal_error,
|
||||
original_error: e,
|
||||
)
|
||||
|
|
@ -70,6 +74,7 @@ module MCP
|
|||
faraday.response(:json)
|
||||
faraday.response(:raise_error)
|
||||
|
||||
faraday.headers["Accept"] = ACCEPT_HEADER
|
||||
headers.each do |key, value|
|
||||
faraday.headers[key] = value
|
||||
end
|
||||
|
|
@ -83,6 +88,17 @@ module MCP
|
|||
"Add it to your Gemfile: gem 'faraday', '>= 2.0'" \
|
||||
"See https://rubygems.org/gems/faraday for more details."
|
||||
end
|
||||
|
||||
def validate_response_content_type!(response, method, params)
|
||||
content_type = response.headers["Content-Type"]
|
||||
return if content_type&.include?("application/json")
|
||||
|
||||
raise RequestHandlerError.new(
|
||||
"Unsupported Content-Type: #{content_type.inspect}. This client only supports JSON responses.",
|
||||
{ method: method, params: params },
|
||||
error_type: :unsupported_media_type,
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue