Class: Baykit::BayServer::Docker::Ajp::AjpPacketUnPacker

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

Constant Summary collapse

STATE_READ_PREAMBLE =
1
STATE_READ_BODY =
2
STATE_END =
3

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pkt_store, cmd_unpacker) ⇒ AjpPacketUnPacker

Returns a new instance of AjpPacketUnPacker.



35
36
37
38
39
40
41
# File 'lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb', line 35

def initialize(pkt_store, cmd_unpacker)
  @pkt_store = pkt_store
  @cmd_unpacker = cmd_unpacker
  @preamble_buf = SimpleBuffer.new
  @body_buf = SimpleBuffer.new
  reset
end

Instance Attribute Details

#body_bufObject (readonly)

Returns the value of attribute body_buf.



19
20
21
# File 'lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb', line 19

def body_buf
  @body_buf
end

#body_lenObject (readonly)

Returns the value of attribute body_len.



29
30
31
# File 'lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb', line 29

def body_len
  @body_len
end

#cmd_unpackerObject (readonly)

Returns the value of attribute cmd_unpacker.



28
29
30
# File 'lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb', line 28

def cmd_unpacker
  @cmd_unpacker
end

#need_dataObject (readonly)

Returns the value of attribute need_data.



33
34
35
# File 'lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb', line 33

def need_data
  @need_data
end

#pkt_storeObject (readonly)

Returns the value of attribute pkt_store.



27
28
29
# File 'lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb', line 27

def pkt_store
  @pkt_store
end

#preamble_bufObject (readonly)

Returns the value of attribute preamble_buf.



18
19
20
# File 'lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb', line 18

def preamble_buf
  @preamble_buf
end

#read_bytesObject (readonly)

Returns the value of attribute read_bytes.



30
31
32
# File 'lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb', line 30

def read_bytes
  @read_bytes
end

#stateObject (readonly)

Returns the value of attribute state.



25
26
27
# File 'lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb', line 25

def state
  @state
end

#to_serverObject (readonly)

Returns the value of attribute to_server.



32
33
34
# File 'lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb', line 32

def to_server
  @to_server
end

#typeObject (readonly)

Returns the value of attribute type.



31
32
33
# File 'lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb', line 31

def type
  @type
end

Instance Method Details

#body_readObject



137
138
139
140
141
142
143
# File 'lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb', line 137

def body_read()
  if @need_data
     @type = AjpType::DATA
  else
     @type =@body_buf.buf[0].codepoints[0] & 0xff
  end
end

#bytes_received(buf) ⇒ Object



52
53
54
55
56
57
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
# File 'lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb', line 52

def bytes_received(buf)
  suspend = false
  pos = 0

  while pos < buf.length
    if @state == STATE_READ_PREAMBLE
      len = AjpPacket::PREAMBLE_SIZE - @preamble_buf.length
      if buf.length - pos < len
        len = buf.length - pos
      end
      @preamble_buf.put(buf, pos, len)
      pos += len

      if @preamble_buf.length == AjpPacket::PREAMBLE_SIZE
        preamble_read()
        change_state(STATE_READ_BODY)
      end
    end

    if @state == STATE_READ_BODY
      len = @body_len - @body_buf.length
      if len > buf.length - pos
        len = buf.length - pos
      end

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

      if @body_buf.length == @body_len
        body_read()
        change_state(STATE_END)
      end
    end

    if @state == STATE_END
      #BayLog.debug "AJP PacketUnpacker parse end: preamblelen=#{@preamble_buf.length} bodyLen=#{@body_buf.length}"

      pkt = @pkt_store.rent(@type)
      pkt.to_server = @to_server
      pkt.new_ajp_header_accessor.put_bytes(@preamble_buf.buf, 0, @preamble_buf.length)
      pkt.new_ajp_data_accessor.put_bytes(@body_buf.buf, 0, @body_buf.length)

      begin
        next_action = @cmd_unpacker.packet_received(pkt)
      ensure
        @pkt_store.Return(pkt)
      end
      reset
      @need_data = @cmd_unpacker.need_data

      if next_action == NextSocketAction::SUSPEND
        suspend = true
      elsif next_action != NextSocketAction::CONTINUE
        return next_action
      end
    end
  end

  #BayLog.debug("ajp: next action=read")
  if suspend
    return NextSocketAction::SUSPEND
  else
    return NextSocketAction::CONTINUE
  end
end

#change_state(new_state) ⇒ Object



118
119
120
# File 'lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb', line 118

def change_state(new_state)
  @state = new_state
end

#preamble_readObject



122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb', line 122

def preamble_read
  data = @preamble_buf.buf

  if data[0].codepoints[0] == 0x12 && data[1].codepoints[0] == 0x34
    @to_server = true
  elsif data[0] == 'A' && data[1] == 'B'
    @to_server = false
  else
    raise RuntimeError.new("Must be start with 0x1234 or 'AB'")
  end

  @body_len =  ((data[2].codepoints[0] << 8) | (data[3].codepoints[0] & 0xff)) & 0xffff
  BayLog.trace("ajp: read packet preamble: bodyLen=%d", @body_len)
end

#resetObject



43
44
45
46
47
48
49
50
# File 'lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb', line 43

def reset
  @state = STATE_READ_PREAMBLE
  @body_len = 0
  @read_bytes = 0
  @need_data = false
  @preamble_buf.reset
  @body_buf.reset
end