bayserver-docker-ajp 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (24) hide show
  1. checksums.yaml +7 -0
  2. data/lib/baykit/bayserver/docker/ajp/ajp_command.rb +55 -0
  3. data/lib/baykit/bayserver/docker/ajp/ajp_command_handler.rb +26 -0
  4. data/lib/baykit/bayserver/docker/ajp/ajp_command_unpacker.rb +66 -0
  5. data/lib/baykit/bayserver/docker/ajp/ajp_docker.rb +15 -0
  6. data/lib/baykit/bayserver/docker/ajp/ajp_inbound_handler.rb +292 -0
  7. data/lib/baykit/bayserver/docker/ajp/ajp_packet.rb +112 -0
  8. data/lib/baykit/bayserver/docker/ajp/ajp_packet_factory.rb +18 -0
  9. data/lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb +150 -0
  10. data/lib/baykit/bayserver/docker/ajp/ajp_port_docker.rb +52 -0
  11. data/lib/baykit/bayserver/docker/ajp/ajp_protocol_handler.rb +55 -0
  12. data/lib/baykit/bayserver/docker/ajp/ajp_type.rb +22 -0
  13. data/lib/baykit/bayserver/docker/ajp/ajp_warp_docker.rb +54 -0
  14. data/lib/baykit/bayserver/docker/ajp/ajp_warp_handler.rb +258 -0
  15. data/lib/baykit/bayserver/docker/ajp/command/cmd_data.rb +59 -0
  16. data/lib/baykit/bayserver/docker/ajp/command/cmd_end_response.rb +48 -0
  17. data/lib/baykit/bayserver/docker/ajp/command/cmd_forward_request.rb +288 -0
  18. data/lib/baykit/bayserver/docker/ajp/command/cmd_get_body_chunk.rb +44 -0
  19. data/lib/baykit/bayserver/docker/ajp/command/cmd_send_body_chunk.rb +71 -0
  20. data/lib/baykit/bayserver/docker/ajp/command/cmd_send_headers.rb +153 -0
  21. data/lib/baykit/bayserver/docker/ajp/command/cmd_shutdown.rb +37 -0
  22. data/lib/baykit/bayserver/docker/ajp/command/package.rb +7 -0
  23. data/lib/baykit/bayserver/docker/ajp/package.rb +12 -0
  24. metadata +78 -0
@@ -0,0 +1,150 @@
1
+ require 'baykit/bayserver/util/simple_buffer'
2
+ require 'baykit/bayserver/agent/next_socket_action'
3
+ require 'baykit/bayserver/protocol/packet_unpacker'
4
+
5
+ #
6
+ # AJP Protocol
7
+ # https://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html
8
+ #
9
+ module Baykit
10
+ module BayServer
11
+ module Docker
12
+ module Ajp
13
+ class AjpPacketUnPacker < Baykit::BayServer::Protocol::PacketUnPacker
14
+
15
+ include Baykit::BayServer::Util
16
+ include Baykit::BayServer::Agent
17
+
18
+ attr :preamble_buf
19
+ attr :body_buf
20
+
21
+ STATE_READ_PREAMBLE = 1
22
+ STATE_READ_BODY = 2
23
+ STATE_END = 3
24
+
25
+ attr :state
26
+
27
+ attr :pkt_store
28
+ attr :cmd_unpacker
29
+ attr :body_len
30
+ attr :read_bytes
31
+ attr :type
32
+ attr :to_server
33
+ attr :need_data
34
+
35
+ def initialize(pkt_store, cmd_unpacker)
36
+ @pkt_store = pkt_store
37
+ @cmd_unpacker = cmd_unpacker
38
+ @preamble_buf = SimpleBuffer.new
39
+ @body_buf = SimpleBuffer.new
40
+ reset
41
+ end
42
+
43
+ def reset
44
+ @state = STATE_READ_PREAMBLE
45
+ @body_len = 0
46
+ @read_bytes = 0
47
+ @need_data = false
48
+ @preamble_buf.reset
49
+ @body_buf.reset
50
+ end
51
+
52
+ def bytes_received(buf)
53
+ suspend = false
54
+ pos = 0
55
+
56
+ while pos < buf.length
57
+ if @state == STATE_READ_PREAMBLE
58
+ len = AjpPacket::PREAMBLE_SIZE - @preamble_buf.length
59
+ if buf.length - pos < len
60
+ len = buf.length - pos
61
+ end
62
+ @preamble_buf.put(buf, pos, len)
63
+ pos += len
64
+
65
+ if @preamble_buf.length == AjpPacket::PREAMBLE_SIZE
66
+ preamble_read()
67
+ change_state(STATE_READ_BODY)
68
+ end
69
+ end
70
+
71
+ if @state == STATE_READ_BODY
72
+ len = @body_len - @body_buf.length
73
+ if len > buf.length - pos
74
+ len = buf.length - pos
75
+ end
76
+
77
+ @body_buf.put(buf, pos, len)
78
+ pos += len
79
+
80
+ if @body_buf.length == @body_len
81
+ body_read()
82
+ change_state(STATE_END)
83
+ end
84
+ end
85
+
86
+ if @state == STATE_END
87
+ #BayLog.debug "AJP PacketUnpacker parse end: preamblelen=#{@preamble_buf.length} bodyLen=#{@body_buf.length}"
88
+
89
+ pkt = @pkt_store.rent(@type)
90
+ pkt.to_server = @to_server
91
+ pkt.new_ajp_header_accessor.put_bytes(@preamble_buf.buf, 0, @preamble_buf.length)
92
+ pkt.new_ajp_data_accessor.put_bytes(@body_buf.buf, 0, @body_buf.length)
93
+
94
+ begin
95
+ next_action = @cmd_unpacker.packet_received(pkt)
96
+ ensure
97
+ @pkt_store.Return(pkt)
98
+ end
99
+ reset
100
+ @need_data = @cmd_unpacker.need_data
101
+
102
+ if next_action == NextSocketAction::SUSPEND
103
+ suspend = true
104
+ elsif next_action != NextSocketAction::CONTINUE
105
+ return next_action
106
+ end
107
+ end
108
+ end
109
+
110
+ #BayLog.debug("ajp: next action=read")
111
+ if suspend
112
+ return NextSocketAction::SUSPEND
113
+ else
114
+ return NextSocketAction::CONTINUE
115
+ end
116
+ end
117
+
118
+ def change_state(new_state)
119
+ @state = new_state
120
+ end
121
+
122
+ def preamble_read
123
+ data = @preamble_buf.buf
124
+
125
+ if data[0].codepoints[0] == 0x12 && data[1].codepoints[0] == 0x34
126
+ @to_server = true
127
+ elsif data[0] == 'A' && data[1] == 'B'
128
+ @to_server = false
129
+ else
130
+ raise RuntimeError.new("Must be start with 0x1234 or 'AB'")
131
+ end
132
+
133
+ @body_len = ((data[2].codepoints[0] << 8) | (data[3].codepoints[0] & 0xff)) & 0xffff
134
+ BayLog.trace("ajp: read packet preamble: bodyLen=%d", @body_len)
135
+ end
136
+
137
+ def body_read()
138
+ if @need_data
139
+ @type = AjpType::DATA
140
+ else
141
+ @type =@body_buf.buf[0].codepoints[0] & 0xff
142
+ end
143
+ end
144
+
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
150
+
@@ -0,0 +1,52 @@
1
+ require 'baykit/bayserver/protocol/packet_store'
2
+ require 'baykit/bayserver/docker/base/port_base'
3
+ require 'baykit/bayserver/docker/ajp/package'
4
+
5
+ module Baykit
6
+ module BayServer
7
+ module Docker
8
+ module Ajp
9
+ class AjpPortDocker < Baykit::BayServer::Docker::Base::PortBase
10
+ include Baykit::BayServer::Docker::Ajp::AjpDocker # implements
11
+
12
+ include Baykit::BayServer::Protocol
13
+ include Baykit::BayServer::WaterCraft
14
+ include Baykit::BayServer::Docker::Base
15
+
16
+ ######################################################
17
+ # Implements Port
18
+ ######################################################
19
+ def protocol()
20
+ return PROTO_NAME
21
+ end
22
+
23
+ ######################################################
24
+ # Implements PortBase
25
+ ######################################################
26
+ def support_anchored()
27
+ return true
28
+ end
29
+
30
+ def support_unanchored()
31
+ return false
32
+ end
33
+
34
+ ######################################################
35
+ # Class initializer
36
+ ######################################################
37
+ begin
38
+ PacketStore.register_protocol(
39
+ PROTO_NAME,
40
+ AjpPacketFactory.new()
41
+ )
42
+ ProtocolHandlerStore.register_protocol(
43
+ PROTO_NAME,
44
+ true,
45
+ AjpInboundHandler::InboundProtocolHandlerFactory.new())
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+
@@ -0,0 +1,55 @@
1
+ require 'baykit/bayserver/protocol/protocol_handler'
2
+ require 'baykit/bayserver/protocol/packet_store'
3
+ require 'baykit/bayserver/util/http_status'
4
+ require 'baykit/bayserver/tours/package'
5
+ require 'baykit/bayserver/docker/ajp/package'
6
+ require 'baykit/bayserver/docker/ajp/command/package'
7
+
8
+ module Baykit
9
+ module BayServer
10
+ module Docker
11
+ module Ajp
12
+ class AjpProtocolHandler < Baykit::BayServer::Protocol::ProtocolHandler
13
+ include Baykit::BayServer::Docker::Ajp::AjpCommandHandler # implements
14
+
15
+ include Baykit::BayServer::Protocol
16
+ include Baykit::BayServer::Agent
17
+ include Baykit::BayServer::Util
18
+ include Baykit::BayServer::Docker::Ajp::Command
19
+
20
+
21
+ def initialize(pkt_store, svr_mode)
22
+ @command_unpacker = AjpCommandUnPacker.new(self)
23
+ @packet_unpacker = AjpPacketUnPacker.new(pkt_store, @command_unpacker)
24
+ @packet_packer = PacketPacker.new()
25
+ @command_packer = CommandPacker.new(@packet_packer, pkt_store)
26
+ @server_mode = svr_mode
27
+ end
28
+
29
+ def to_s
30
+ "pch[#{@ship}]"
31
+ end
32
+
33
+ ######################################################
34
+ # Implements ProtocolHandler
35
+ ######################################################
36
+
37
+ def protocol()
38
+ return AjpDocker::PROTO_NAME
39
+ end
40
+
41
+ def max_req_packet_data_size()
42
+ return CmdData::MAX_DATA_LEN
43
+ end
44
+
45
+ def max_res_packet_data_size()
46
+ return CmdSendBodyChunk::MAX_CHUNKLEN
47
+ end
48
+
49
+
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+
@@ -0,0 +1,22 @@
1
+ #
2
+ # Ajp packet type
3
+ #
4
+ module Baykit
5
+ module BayServer
6
+ module Docker
7
+ module Ajp
8
+ class AjpType
9
+ DATA = 0
10
+ FORWARD_REQUEST = 2
11
+ SEND_BODY_CHUNK = 3
12
+ SEND_HEADERS = 4
13
+ END_RESPONSE = 5
14
+ GET_BODY_CHUNK = 6
15
+ SHUTDOWN = 7
16
+ PING = 8
17
+ CPING = 10
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,54 @@
1
+ require 'baykit/bayserver/docker/warp/warp_docker'
2
+ require 'baykit/bayserver/docker/ajp/package'
3
+ require 'baykit/bayserver/agent/transporter/plain_transporter'
4
+ require 'baykit/bayserver/protocol/packet_store'
5
+
6
+ module Baykit
7
+ module BayServer
8
+ module Docker
9
+ module Ajp
10
+ class AjpWarpDocker < Baykit::BayServer::Docker::Warp::WarpDocker
11
+ include Baykit::BayServer::Docker::Ajp::AjpDocker # implements
12
+
13
+ include Baykit::BayServer::Agent
14
+ include Baykit::BayServer::Protocol
15
+ include Baykit::BayServer::Agent::Transporter
16
+
17
+ ######################################################
18
+ # Implements WarpDocker
19
+ ######################################################
20
+ def secure()
21
+ return false
22
+ end
23
+
24
+ ######################################################
25
+ # Implements WarpDockerBase
26
+ ######################################################
27
+ private
28
+ def protocol()
29
+ return PROTO_NAME
30
+ end
31
+
32
+ def new_transporter(agt, skt)
33
+ PlainTransporter.new(false, IOUtil.get_sock_recv_buf_size(skt))
34
+ end
35
+
36
+ ######################################################
37
+ # Class initializer
38
+ ######################################################
39
+ begin
40
+ PacketStore.register_protocol(
41
+ PROTO_NAME,
42
+ AjpPacketFactory.new()
43
+ )
44
+ ProtocolHandlerStore.register_protocol(
45
+ PROTO_NAME,
46
+ false,
47
+ AjpWarpHandler::WarpProtocolHandlerFactory.new())
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,258 @@
1
+ require 'baykit/bayserver/agent/next_socket_action'
2
+ require 'baykit/bayserver/protocol/protocol_exception'
3
+ require 'baykit/bayserver/docker/ajp/command/package'
4
+ require 'baykit/bayserver/util/string_util'
5
+
6
+ require 'baykit/bayserver/docker/ajp/ajp_protocol_handler'
7
+
8
+
9
+ module Baykit
10
+ module BayServer
11
+ module Docker
12
+ module Ajp
13
+ class AjpWarpHandler < Baykit::BayServer::Docker::Ajp::AjpProtocolHandler
14
+ include Baykit::BayServer::Docker::Warp::WarpHandler # implements
15
+
16
+ class WarpProtocolHandlerFactory
17
+ include Baykit::BayServer::Protocol::ProtocolHandlerFactory # implements
18
+
19
+ def create_protocol_handler(pkt_store)
20
+ return AjpWarpHandler.new(pkt_store)
21
+ end
22
+ end
23
+
24
+
25
+ include Baykit::BayServer::Agent
26
+ include Baykit::BayServer::Protocol
27
+ include Baykit::BayServer::Tours
28
+ include Baykit::BayServer::Docker::Warp
29
+ include Baykit::BayServer::Docker::Ajp::Command
30
+ include Baykit::BayServer::Util
31
+
32
+ FIXED_WARP_ID = 1
33
+
34
+ STATE_READ_HEADER = 1
35
+ STATE_READ_CONTENT = 2
36
+
37
+ attr :state
38
+
39
+ attr :cont_read_len
40
+
41
+ def initialize(pkt_store)
42
+ super(pkt_store, false)
43
+ reset()
44
+ end
45
+
46
+ def reset()
47
+ super
48
+ reset_state()
49
+ @cont_read_len = 0
50
+ end
51
+
52
+ def to_s()
53
+ return ship().to_s()
54
+ end
55
+
56
+ ######################################################
57
+ # Implements WarpHandler
58
+ ######################################################
59
+ def next_warp_id()
60
+ return 1
61
+ end
62
+
63
+ def new_warp_data(warp_id)
64
+ return WarpData.new(ship, warp_id)
65
+ end
66
+
67
+ def post_warp_headers(tur)
68
+ send_forward_request(tur)
69
+ end
70
+
71
+ def post_warp_contents(tur, buf, start, len, &callback)
72
+ send_data(tur, buf, start, len, &callback)
73
+ end
74
+
75
+ def post_warp_end(tur)
76
+ end
77
+
78
+ def verify_protocol(proto)
79
+ end
80
+
81
+ ######################################################
82
+ # Implements AjpCommandHandler
83
+ ######################################################
84
+ def handle_data(cmd)
85
+ raise ProtocolException.new("Invalid AJP command: %d", cmd.type)
86
+ end
87
+
88
+ def handle_end_response(cmd)
89
+ BayLog.debug("%s handle_end_response reuse=%s", @ship, cmd.reuse)
90
+ tur = @ship.get_tour(FIXED_WARP_ID)
91
+
92
+ if @state == STATE_READ_HEADER
93
+ end_res_header(tur)
94
+ end
95
+
96
+ end_res_content(tur)
97
+ if cmd.reuse
98
+ return NextSocketAction::CONTINUE
99
+ else
100
+ return NextSocketAction::CLOSE
101
+ end
102
+
103
+ end
104
+
105
+ def handle_forward_request(cmd)
106
+ raise ProtocolException.new("Invalid AJP command: #{cmd.type}")
107
+ end
108
+
109
+ def handle_send_body_chunk(cmd)
110
+ BayLog.debug("%s handle_send_body_chunk: len=%d", @ship, cmd.length)
111
+ tur = @ship.get_tour(FIXED_WARP_ID)
112
+
113
+ if @state == STATE_READ_HEADER
114
+
115
+ sid = @ship.ship_id
116
+ tur.res.set_consume_listener do |len, resume|
117
+ if resume
118
+ @ship.resume(sid)
119
+ end
120
+ end
121
+
122
+ end_res_header(tur)
123
+ end
124
+
125
+ available = tur.res.send_content(tur.tour_id, cmd.chunk, 0, cmd.length)
126
+ @cont_read_len += cmd.length
127
+
128
+ if available
129
+ return NextSocketAction::CONTINUE
130
+ else
131
+ return NextSocketAction::SUSPEND
132
+ end
133
+ end
134
+
135
+ def handle_send_headers(cmd)
136
+ BayLog.debug("%s handle_send_headers", @ship)
137
+
138
+ tur = @ship.get_tour(FIXED_WARP_ID)
139
+
140
+ if @state != STATE_READ_HEADER
141
+ raise ProtocolException.new("Invalid AJP command: %d state=%s", cmd.type, @state)
142
+ end
143
+
144
+ wdat = WarpData.get(tur)
145
+
146
+ if BayServer.harbor.trace_header?
147
+ BayLog.info("%s recv res status: %d", wdat, cmd.status)
148
+ end
149
+
150
+ wdat.res_headers.status = cmd.status
151
+ cmd.headers.keys.each do |name|
152
+ cmd.headers[name].each do |value|
153
+ if BayServer.harbor.trace_header?
154
+ BayLog.info("%s recv res header: %s=%s", wdat, name, value)
155
+ end
156
+ wdat.res_headers.add(name, value)
157
+ end
158
+ end
159
+
160
+ return NextSocketAction::CONTINUE
161
+ end
162
+
163
+ def handle_shutdown(cmd)
164
+ raise ProtocolException.new("Invalid AJP command: %d", cmd.type)
165
+ end
166
+
167
+ def handle_get_body_chunk(cmd)
168
+ BayLog.debug("%s handle_get_body_chunk", self)
169
+ return NextSocketAction::CONTINUE
170
+ end
171
+
172
+ def handle_eof
173
+ raise EOFError.new()
174
+ end
175
+
176
+ def need_data
177
+ return false
178
+ end
179
+
180
+ private
181
+ def end_res_header(tur)
182
+ wdat = WarpData.get(tur)
183
+ wdat.res_headers.copy_to(tur.res.headers)
184
+ tur.res.send_headers(Tour::TOUR_ID_NOCHECK)
185
+ change_state(STATE_READ_CONTENT)
186
+ end
187
+
188
+ def end_res_content(tur)
189
+ @ship.end_warp_tour(tur)
190
+ tur.res.end_content(Tour::TOUR_ID_NOCHECK)
191
+ reset_state()
192
+ end
193
+
194
+ def change_state(new_state)
195
+ @state = new_state
196
+ end
197
+
198
+ def reset_state
199
+ change_state(STATE_READ_HEADER)
200
+ end
201
+
202
+
203
+ def send_forward_request(tur)
204
+ BayLog.debug("%s construct header", tur)
205
+
206
+ cmd = CmdForwardRequest.new()
207
+ cmd.to_server = true
208
+ cmd.method = tur.req.method
209
+ cmd.protocol = tur.req.protocol
210
+ rel_uri = tur.req.rewritten_uri != nil ? tur.req.rewritten_uri : tur.req.uri
211
+ town_path = tur.town.name
212
+ if !town_path.end_with?("/")
213
+ town_path += "/"
214
+ end
215
+
216
+ rel_uri = rel_uri[town_path.length .. -1]
217
+ req_uri = @ship.docker.warp_base + rel_uri
218
+
219
+ pos = req_uri.index('?')
220
+ if pos != nil
221
+ cmd.req_uri = req_uri[0 .. pos - 1]
222
+ cmd.attributes["?query_string"] = req_uri[pos + 1 .. -1]
223
+ else
224
+ cmd.req_uri = req_uri
225
+ end
226
+
227
+ cmd.remote_addr = tur.req.remote_address
228
+ cmd.remote_host = tur.req.remote_host()
229
+ cmd.server_name = tur.req.server_name
230
+ cmd.server_port = @ship.docker.port
231
+ cmd.is_ssl = tur.is_secure
232
+ cmd.headers = tur.req.headers
233
+ if BayServer.harbor.trace_header?
234
+ cmd.headers.names.each do |name|
235
+ cmd.headers.values(name).each do |value|
236
+ BayLog.info("%s sendWarpHeader: %s=%s", WarpData.get(tur), name, value)
237
+ end
238
+ end
239
+ end
240
+
241
+ command_packer.post(@ship, cmd)
242
+ end
243
+
244
+ def send_data(tur, data, ofs, len, &callback)
245
+ BayLog.debug("%s construct contents", tur)
246
+
247
+ cmd = CmdData.new(data, ofs, len)
248
+ cmd.to_server = true
249
+
250
+ command_packer.post(@ship, cmd, &callback)
251
+ end
252
+
253
+ end
254
+ end
255
+ end
256
+ end
257
+ end
258
+
@@ -0,0 +1,59 @@
1
+ require 'baykit/bayserver/docker/ajp/ajp_command'
2
+ require 'baykit/bayserver/docker/ajp/ajp_type'
3
+ require 'baykit/bayserver/docker/ajp/ajp_packet'
4
+
5
+ #
6
+ # Data command format
7
+ #
8
+ # AJP13_DATA :=
9
+ # len, raw data
10
+ #
11
+ module Baykit
12
+ module BayServer
13
+ module Docker
14
+ module Ajp
15
+ module Command
16
+ class CmdData < Baykit::BayServer::Docker::Ajp::AjpCommand
17
+ LENGTH_OF_SIZE = 2
18
+ MAX_DATA_LEN = AjpPacket::MAX_DATA_LEN - LENGTH_OF_SIZE
19
+
20
+ attr :start
21
+ attr_accessor :length
22
+ attr_accessor :data
23
+
24
+ def initialize(data = nil, start = 0, length = 0)
25
+ super(AjpType::DATA, true)
26
+ @data = data
27
+ @start = start
28
+ @length = length
29
+ end
30
+
31
+ def unpack(pkt)
32
+ super
33
+ acc = pkt.new_ajp_data_accessor
34
+ @length = acc.get_short
35
+ @data = pkt.buf
36
+ @start = pkt.header_len + 2
37
+ end
38
+
39
+ def pack(pkt)
40
+ acc = pkt.new_ajp_data_accessor
41
+ acc.put_short(@length)
42
+ acc.put_bytes(@data, @start, @length)
43
+
44
+ #BayLog.debug "pack AJP command data: #{pkt.data.bytes}"
45
+
46
+ # must be called from last line
47
+ super
48
+ end
49
+
50
+ def handle(handler)
51
+ return handler.handle_data(self)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+
@@ -0,0 +1,48 @@
1
+ require 'baykit/bayserver/docker/ajp/ajp_command'
2
+ require 'baykit/bayserver/docker/ajp/ajp_type'
3
+
4
+ #
5
+ # End response body format
6
+ #
7
+ # AJP13_END_RESPONSE :=
8
+ # prefix_code 5
9
+ # reuse (boolean)
10
+ #
11
+ module Baykit
12
+ module BayServer
13
+ module Docker
14
+ module Ajp
15
+ module Command
16
+ class CmdEndResponse < Baykit::BayServer::Docker::Ajp::AjpCommand
17
+ attr_accessor :reuse
18
+
19
+ def initialize
20
+ super(AjpType::END_RESPONSE, false)
21
+ end
22
+
23
+ def pack(pkt)
24
+ acc = pkt.new_ajp_data_accessor
25
+ acc.put_byte(@type)
26
+ acc.put_byte(@reuse ? 1 : 0)
27
+
28
+ # must be called from last line
29
+ super
30
+ end
31
+
32
+ def unpack(pkt)
33
+ super
34
+ acc = pkt.new_ajp_data_accessor()
35
+ acc.get_byte() # prefix code
36
+ @reuse = acc.get_byte() != 0
37
+ end
38
+
39
+ def handle(handler)
40
+ return handler.handle_end_response(self)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+