class Seahorse::Client::H2::Handler
Public Instance Methods
call(context)
click to toggle source
# File lib/seahorse/client/h2/handler.rb, line 29 def call(context) stream = nil begin conn = context.client.connection stream = conn.new_stream stream_mutex = Mutex.new close_condition = ConditionVariable.new sync_queue = Queue.new conn.connect(context.http_request.endpoint) _register_callbacks( context.http_response, stream, stream_mutex, close_condition, sync_queue ) conn.debug_output("sending initial request ...") if input_emitter = context[:input_event_emitter] _send_initial_headers(context.http_request, stream) # prepare for sending events later input_emitter.stream = stream # request sigv4 serves as the initial #prior_signature input_emitter.encoder.prior_signature = context.http_request.headers['authorization'].split('Signature=').last input_emitter.validate_event = context.config.validate_params else _send_initial_headers(context.http_request, stream) _send_initial_data(context.http_request, stream) end conn.start(stream) rescue *NETWORK_ERRORS => error error = NetworkingError.new( error, error_message(context.http_request, error)) context.http_response.signal_error(error) rescue => error conn.debug_output(error.inspect) # not retryable context.http_response.signal_error(error) end AsyncResponse.new( context: context, stream: stream, stream_mutex: stream_mutex, close_condition: close_condition, sync_queue: sync_queue ) end
Private Instance Methods
_h2_headers(req)
click to toggle source
H2
pseudo headers http2.github.io/http2-spec/#rfc.section.8.1.2.3
# File lib/seahorse/client/h2/handler.rb, line 127 def _h2_headers(req) headers = {} headers[':method'] = req.http_method.upcase headers[':scheme'] = req.endpoint.scheme headers[':path'] = req.endpoint.path.empty? ? '/' : req.endpoint.path if req.endpoint.query && !req.endpoint.query.empty? headers[':path'] += "?#{req.endpoint.query}" end req.headers.each {|k, v| headers[k.downcase] = v } headers end
_register_callbacks(resp, stream, stream_mutex, close_condition, sync_queue)
click to toggle source
# File lib/seahorse/client/h2/handler.rb, line 85 def _register_callbacks(resp, stream, stream_mutex, close_condition, sync_queue) stream.on(:headers) do |headers| resp.signal_headers(headers) end stream.on(:data) do |data| resp.signal_data(data) end stream.on(:close) do resp.signal_done # block until #wait is ready for signal # else deadlock may happen because #signal happened # eariler than #wait (see AsyncResponse#wait) sync_queue.pop stream_mutex.synchronize { close_condition.signal } end end
_send_initial_data(req, stream)
click to toggle source
# File lib/seahorse/client/h2/handler.rb, line 115 def _send_initial_data(req, stream) begin data = req.body.read stream.data(data, end_stream: true) rescue => e raise Http2InitialRequestError.new(e) end data end
_send_initial_headers(req, stream)
click to toggle source
# File lib/seahorse/client/h2/handler.rb, line 106 def _send_initial_headers(req, stream) begin headers = _h2_headers(req) stream.headers(headers, end_stream: false) rescue => e raise Http2InitialRequestError.new(e) end end
error_message(req, error)
click to toggle source
# File lib/seahorse/client/h2/handler.rb, line 139 def error_message(req, error) if error.is_a?(SocketError) && DNS_ERROR_MESSAGES.include?(error.message) host = req.endpoint.host "unable to connect to `#{host}`; SocketError: #{error.message}" else error.message end end