Class: RubyLLM::MCP::Auth::HttpResponseHandler

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_llm/mcp/auth/http_response_handler.rb

Overview

Utility class for handling HTTP responses in OAuth flows Consolidates error handling and response parsing

Class Method Summary collapse

Class Method Details

.extract_redirect_mismatch(body) ⇒ Hash?

Extract redirect URI mismatch details from error response

Parameters:

  • body (String)

    error response body

Returns:

  • (Hash, nil)

    mismatch details or nil



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/ruby_llm/mcp/auth/http_response_handler.rb', line 39

def self.extract_redirect_mismatch(body)
  data = JSON.parse(body)
  error = data["error"] || data[:error]
  return nil unless error == "unauthorized_client"

  description = data["error_description"] || data[:error_description]
  return nil unless description.is_a?(String)

  # Parse common OAuth error message format
  # Matches: "You sent <url> and we expected <url>"
  match = description.match(%r{You sent\s+(https?://[^\s,]+)[\s,]+and we expected\s+(https?://\S+?)\.?\s*$}i)
  return nil unless match

  {
    sent: match[1],
    expected: match[2],
    description: description
  }
rescue JSON::ParserError
  nil
end

.handle_response(response, context:, expected_status: 200) ⇒ Hash

Handle and parse a successful HTTP response

Parameters:

  • response (HTTPX::Response, HTTPX::ErrorResponse)

    HTTP response

  • context (String)

    description for error messages (e.g., "Token exchange")

  • expected_status (Integer, Array<Integer>) (defaults to: 200)

    expected status code(s)

Returns:

  • (Hash)

    parsed JSON response

Raises:



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/ruby_llm/mcp/auth/http_response_handler.rb', line 15

def self.handle_response(response, context:, expected_status: 200)
  expected_statuses = Array(expected_status)

  # Handle HTTPX ErrorResponse (connection failures, timeouts, etc.)
  if response.is_a?(HTTPX::ErrorResponse)
    error_message = response.error&.message || "Request failed"
    raise Errors::TransportError.new(
      message: "#{context} failed: #{error_message}"
    )
  end

  unless expected_statuses.include?(response.status)
    raise Errors::TransportError.new(
      message: "#{context} failed: HTTP #{response.status}",
      code: response.status
    )
  end

  JSON.parse(response.body.to_s)
end