Class: Baykit::BayServer::Docker::Fcgi::FcgPacketUnPacker

Inherits:
Protocol::PacketUnPacker
  • Object
show all
Includes:
Agent, Util
Defined in:
lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb

Constant Summary collapse

STATE_REQD_PREAMBLE =

#state for reading first 8 bytes (from version to reserved)

1
STATE_READ_CONTENT =

state for reading content data

2
STATE_READ_PADDING =

state for reading padding data

3
STATE_END =

End

4

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pkt_store, cmd_unpacker) ⇒ FcgPacketUnPacker

Returns a new instance of FcgPacketUnPacker.



36
37
38
39
40
41
42
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 36

def initialize(pkt_store, cmd_unpacker)
  @cmd_unpacker = cmd_unpacker
  @pkt_store = pkt_store
  @header_buf = SimpleBuffer.new
  @data_buf = SimpleBuffer.new
  reset()
end

Instance Attribute Details

#cmd_unpackerObject (readonly)

Returns the value of attribute cmd_unpacker.



31
32
33
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 31

def cmd_unpacker
  @cmd_unpacker
end

#cont_lenObject (readonly)

Returns the value of attribute cont_len.



33
34
35
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 33

def cont_len
  @cont_len
end

#data_bufObject (readonly)

Returns the value of attribute data_buf.



15
16
17
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 15

def data_buf
  @data_buf
end

#header_bufObject (readonly)

Returns the value of attribute header_buf.



14
15
16
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 14

def header_buf
  @header_buf
end

#lengthObject (readonly)

Returns the value of attribute length.



20
21
22
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 20

def length
  @length
end

#paddingObject (readonly)

Returns the value of attribute padding.



21
22
23
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 21

def padding
  @padding
end

#padding_read_bytesObject (readonly)

Returns the value of attribute padding_read_bytes.



22
23
24
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 22

def padding_read_bytes
  @padding_read_bytes
end

#pkt_storeObject (readonly)

Returns the value of attribute pkt_store.



32
33
34
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 32

def pkt_store
  @pkt_store
end

#read_bytesObject (readonly)

Returns the value of attribute read_bytes.



34
35
36
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 34

def read_bytes
  @read_bytes
end

#req_idObject (readonly)

Returns the value of attribute req_id.



19
20
21
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 19

def req_id
  @req_id
end

#stateObject (readonly)

Returns the value of attribute state.



29
30
31
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 29

def state
  @state
end

#typeObject (readonly)

Returns the value of attribute type.



18
19
20
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 18

def type
  @type
end

#versionObject (readonly)

Returns the value of attribute version.



17
18
19
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 17

def version
  @version
end

Instance Method Details

#byte_to_int(b) ⇒ Object



189
190
191
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 189

def byte_to_int(b)
  return b & 0xff
end

#bytes_received(buf) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 58

def bytes_received(buf)
  next_suspend = false
  next_write = false
  pos = 0

  while pos < buf.length
    while @state != STATE_END && pos < buf.length

      case @state

      when STATE_REQD_PREAMBLE
        # preamble read mode
        len = FcgPacket::PREAMBLE_SIZE - @header_buf.length
        if buf.length - pos < len
          len = buf.length - pos
        end

        @header_buf.put(buf, pos, len)
        pos += len

        if @header_buf.length == FcgPacket::PREAMBLE_SIZE
          header_read_done()
          if @length == 0
            if @padding == 0
              change_state(STATE_END)
            else
              change_state(STATE_READ_PADDING)
            end
          else
            change_state(STATE_READ_CONTENT)
          end
        end

      when STATE_READ_CONTENT
        # content read mode
        len = @length - @data_buf.length
        if len > buf.length - pos
          len = buf.length - pos
        end

        if len > 0
          @data_buf.put(buf, pos, len)
          pos += len

          if @data_buf.length == @length
            if @padding == 0
              change_state(STATE_END)
            else
              change_state(STATE_READ_PADDING)
            end
          end
        end

      when STATE_READ_PADDING
        # padding read mode
        len = @padding - @padding_read_bytes

        if len > buf.length - pos
          len = buf.length - pos
        end

        #@data_buf.put(buf, pos, len)
        pos += len

        if len > 0
          @padding_read_bytes += len

          if @padding_read_bytes == @padding
            change_state(STATE_END)
          end
        end

      else
        raise RuntimeError.new("IllegalState")
      end

    end

    if state == STATE_END
      pkt = @pkt_store.rent(@type)
      pkt.req_id = @req_id
      pkt.new_header_accessor.put_bytes(@header_buf.buf, 0, @header_buf.length)
      pkt.new_data_accessor.put_bytes(@data_buf.buf, 0, @data_buf.length)

      begin
        state = @cmd_unpacker.packet_received(pkt)
      ensure
        @pkt_store.Return(pkt)
      end

      reset()

      case state
      when NextSocketAction::SUSPEND
        next_suspend = true
      when NextSocketAction::CONTINUE
        nil
      when NextSocketAction::WRITE
        next_write = true
      when NextSocketAction::CLOSE
        return state
      end

    end
  end

  if next_write
    return NextSocketAction::WRITE
  elsif next_suspend
    return NextSocketAction::SUSPEND
  else
    return NextSocketAction::CONTINUE
  end
end

#bytes_to_int(b1, b2) ⇒ Object



193
194
195
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 193

def bytes_to_int(b1, b2)
  return byte_to_int(b1) << 8 | byte_to_int(b2)
end

#change_state(new_state) ⇒ Object



173
174
175
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 173

def change_state(new_state)
  @state = new_state
end

#header_read_doneObject



177
178
179
180
181
182
183
184
185
186
187
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 177

def header_read_done
  pre = @header_buf.buf.codepoints
  @version = byte_to_int(pre[0])
  @type = byte_to_int(pre[1])
  @req_id = bytes_to_int(pre[2], pre[3])
  @length = bytes_to_int(pre[4], pre[5])
  @padding = byte_to_int(pre[6])
  reserved = byte_to_int(pre[7])
  BayLog.debug("fcg: read packet header: version=%s type=%d reqId=%d length=%d padding=%d",
                @version, @type, @req_id, @length, @padding)
end

#resetObject



44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/baykit/bayserver/docker/fcgi/fcg_packet_unpacker.rb', line 44

def reset
  @state = STATE_REQD_PREAMBLE
  @version = 0
  @type = nil
  @req_id = 0
  @length = 0
  @padding = 0
  @padding_read_bytes = 0
  @cont_len = 0
  @read_bytes = 0
  @header_buf.reset
  @data_buf.reset
end