Class: AtProto::DpopHandler
- Inherits:
-
Object
- Object
- AtProto::DpopHandler
- Defined in:
- lib/atproto_client/dpop_handler.rb
Overview
Handler for DPoP (Demonstrating Proof-of-Possession) protocol implementation
Instance Method Summary collapse
-
#generate_token(http_method, url, nonce = @current_nonce) ⇒ String
Generates a DPoP token for a request.
-
#initialize(private_key = nil) ⇒ DpopHandler
constructor
Initialize a new DPoP handler.
-
#make_request(uri, method, headers: {}, body: nil) ⇒ Net::HTTPResponse
Makes an HTTP request with DPoP handling, when no nonce is used for the first try, takes it from the response and retry.
-
#update_nonce(response) ⇒ Object
Updates the current nonce from response headers.
Constructor Details
#initialize(private_key = nil) ⇒ DpopHandler
Initialize a new DPoP handler
6 7 8 9 10 11 |
# File 'lib/atproto_client/dpop_handler.rb', line 6 def initialize(private_key = nil) @private_key = private_key || generate_private_key @current_nonce = nil @nonce_mutex = Mutex.new @token_mutex = Mutex.new end |
Instance Method Details
#generate_token(http_method, url, nonce = @current_nonce) ⇒ String
Generates a DPoP token for a request
18 19 20 21 22 |
# File 'lib/atproto_client/dpop_handler.rb', line 18 def generate_token(http_method, url, nonce = @current_nonce) @token_mutex.synchronize do create_dpop_token(http_method, url, nonce) end end |
#make_request(uri, method, headers: {}, body: nil) ⇒ Net::HTTPResponse
Makes an HTTP request with DPoP handling, when no nonce is used for the first try, takes it from the response and retry
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/atproto_client/dpop_handler.rb', line 41 def make_request(uri, method, headers: {}, body: nil) retried = false begin dpop_token = generate_token(method.to_s.upcase, uri.to_s) request = Request.new(method, uri, headers.merge('DPoP' => dpop_token)) request.body = body.to_json if body request.run rescue Net::HTTPClientException => e unless retried update_nonce(e.response) retried = true retry end raise APIError, "Request failed: #{e.response.code} - #{e.response.body}" end end |
#update_nonce(response) ⇒ Object
Updates the current nonce from response headers
26 27 28 29 30 31 |
# File 'lib/atproto_client/dpop_handler.rb', line 26 def update_nonce(response) new_nonce = response.to_hash.dig('dpop-nonce', 0) @nonce_mutex.synchronize do @current_nonce = new_nonce if new_nonce end end |