Module: HTTPX::Plugins::GRPC::Message

Defined in:
lib/httpx/plugins/grpc/message.rb

Overview

Encoding module for GRPC responses

Can encode and decode grpc messages.

Class Method Summary collapse

Class Method Details

.cancel(request) ⇒ Object



64
65
66
# File 'lib/httpx/plugins/grpc/message.rb', line 64

def cancel(request)
  request.emit(:refuse, :client_cancellation)
end

.decode(message, encodings:, encoders:) ⇒ Object

decodes a single grpc message



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/httpx/plugins/grpc/message.rb', line 42

def decode(message, encodings:, encoders:)
  until message.empty?

    compressed, size = message.unpack("CL>")

    data = message.byteslice(5..size + 5 - 1)
    if compressed == 1
      encodings.reverse_each do |algo|
        inflater = encoders.registry(algo).inflater(size)
        data = inflater.inflate(data)
        size = data.bytesize
      end
    end

    return data unless block_given?

    yield data

    message = message.byteslice((5 + size)..-1)
  end
end

.encode(bytes, deflater:) ⇒ Object

encodes a single grpc message



30
31
32
33
34
35
36
37
38
39
# File 'lib/httpx/plugins/grpc/message.rb', line 30

def encode(bytes, deflater:)
  if deflater
    compressed_flag = 1
    bytes = deflater.deflate(StringIO.new(bytes))
  else
    compressed_flag = 0
  end

  "".b << [compressed_flag, bytes.bytesize].pack("CL>") << bytes.to_s
end

.stream(response, &block) ⇒ Object

lazy decodes a grpc stream response



19
20
21
22
23
24
25
26
27
# File 'lib/httpx/plugins/grpc/message.rb', line 19

def stream(response, &block)
  return enum_for(__method__, response) unless block

  response.each do |frame|
    decode(frame, encodings: response.headers.get("grpc-encoding"), encoders: response.encoders, &block)
  end

  verify_status(response)
end

.unary(response) ⇒ Object

decodes a unary grpc response



13
14
15
16
# File 'lib/httpx/plugins/grpc/message.rb', line 13

def unary(response)
  verify_status(response)
  decode(response.to_s, encodings: response.headers.get("grpc-encoding"), encoders: response.encoders)
end

.verify_status(response) ⇒ Object

interprets the grpc call trailing metadata, and raises an exception in case of error code

Raises:



70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/httpx/plugins/grpc/message.rb', line 70

def verify_status(response)
  # return standard errors if need be
  response.raise_for_status

  status = Integer(response.headers["grpc-status"])
  message = response.headers["grpc-message"]

  return if status.zero?

  response.close
  raise GRPCError.new(status, message, response.)
end