bayserver-docker-ajp 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/baykit/bayserver/docker/ajp/ajp_command.rb +55 -0
- data/lib/baykit/bayserver/docker/ajp/ajp_command_handler.rb +26 -0
- data/lib/baykit/bayserver/docker/ajp/ajp_command_unpacker.rb +66 -0
- data/lib/baykit/bayserver/docker/ajp/ajp_docker.rb +15 -0
- data/lib/baykit/bayserver/docker/ajp/ajp_inbound_handler.rb +292 -0
- data/lib/baykit/bayserver/docker/ajp/ajp_packet.rb +112 -0
- data/lib/baykit/bayserver/docker/ajp/ajp_packet_factory.rb +18 -0
- data/lib/baykit/bayserver/docker/ajp/ajp_packet_unpacker.rb +150 -0
- data/lib/baykit/bayserver/docker/ajp/ajp_port_docker.rb +52 -0
- data/lib/baykit/bayserver/docker/ajp/ajp_protocol_handler.rb +55 -0
- data/lib/baykit/bayserver/docker/ajp/ajp_type.rb +22 -0
- data/lib/baykit/bayserver/docker/ajp/ajp_warp_docker.rb +54 -0
- data/lib/baykit/bayserver/docker/ajp/ajp_warp_handler.rb +258 -0
- data/lib/baykit/bayserver/docker/ajp/command/cmd_data.rb +59 -0
- data/lib/baykit/bayserver/docker/ajp/command/cmd_end_response.rb +48 -0
- data/lib/baykit/bayserver/docker/ajp/command/cmd_forward_request.rb +288 -0
- data/lib/baykit/bayserver/docker/ajp/command/cmd_get_body_chunk.rb +44 -0
- data/lib/baykit/bayserver/docker/ajp/command/cmd_send_body_chunk.rb +71 -0
- data/lib/baykit/bayserver/docker/ajp/command/cmd_send_headers.rb +153 -0
- data/lib/baykit/bayserver/docker/ajp/command/cmd_shutdown.rb +37 -0
- data/lib/baykit/bayserver/docker/ajp/command/package.rb +7 -0
- data/lib/baykit/bayserver/docker/ajp/package.rb +12 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9f0897b0f990499668e38deec50e8c9426cb14c4a41e403bb08c7821a294f692
|
4
|
+
data.tar.gz: 527c1a81a6063b4079781c50e8efb8d2a0324418f6fbf55a4fad2a1fd3f1be73
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f2c5f4a2373e576628a41326b018a301a0e51312068db3e8c16e849ede6e7bdd5c2ece680151c761c3d31ad8ebfd895e90ae14d77201420cd3858633a4c00d87
|
7
|
+
data.tar.gz: 13dab20d83962f56f704f312a4a49817be9689dfd5416646a253520f23876b61abbfa8a62bce73406dee3c07242ae2fd53d612ac21a11cf23399a7e6997755c0
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#
|
2
|
+
# AJP Protocol
|
3
|
+
# https://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html
|
4
|
+
#
|
5
|
+
module Baykit
|
6
|
+
module BayServer
|
7
|
+
module Docker
|
8
|
+
module Ajp
|
9
|
+
class AjpCommand < Baykit::BayServer::Protocol::Command
|
10
|
+
|
11
|
+
attr_accessor :to_server
|
12
|
+
|
13
|
+
def initialize(type, to_server)
|
14
|
+
super type
|
15
|
+
@to_server = to_server
|
16
|
+
end
|
17
|
+
|
18
|
+
def unpack(pkt)
|
19
|
+
if pkt.type() != @type
|
20
|
+
raise RuntimeError.new("Illegal State")
|
21
|
+
end
|
22
|
+
@to_server = pkt.to_server
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Super class method must be called from last line of override method
|
27
|
+
# since header cannot be packed before data is constructed.
|
28
|
+
#
|
29
|
+
def pack(pkt)
|
30
|
+
if pkt.type() != @type
|
31
|
+
raise RuntimeError.new "Illegal State"
|
32
|
+
end
|
33
|
+
pkt.to_server = @to_server
|
34
|
+
pack_header(pkt)
|
35
|
+
end
|
36
|
+
|
37
|
+
def pack_header(pkt)
|
38
|
+
acc = pkt.new_ajp_header_accessor
|
39
|
+
if pkt.to_server
|
40
|
+
acc.put_byte(0x12)
|
41
|
+
acc.put_byte(0x34)
|
42
|
+
else
|
43
|
+
acc.put_byte('A')
|
44
|
+
acc.put_byte('B')
|
45
|
+
end
|
46
|
+
|
47
|
+
acc.put_byte((pkt.data_len >> 8) & 0xff)
|
48
|
+
acc.put_byte(pkt.data_len & 0xff)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'baykit/bayserver/protocol/command_handler'
|
2
|
+
|
3
|
+
module Baykit
|
4
|
+
module BayServer
|
5
|
+
module Docker
|
6
|
+
module Ajp
|
7
|
+
module AjpCommandHandler
|
8
|
+
include Baykit::BayServer::Protocol::CommandHandler # implements
|
9
|
+
|
10
|
+
# abstract method
|
11
|
+
#
|
12
|
+
# handle_data(cmd)
|
13
|
+
# handle_end_response(cmd)
|
14
|
+
# handle_forward_request(cmd)
|
15
|
+
# handle_send_body_chunk(cmd)
|
16
|
+
# handle_send_headers(cmd)
|
17
|
+
# handle_shutdown(cmd)
|
18
|
+
# handle_get_body_chunk(cmd)
|
19
|
+
# need_data()
|
20
|
+
#
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'baykit/bayserver/protocol/command_unpacker'
|
2
|
+
require 'baykit/bayserver/docker/ajp/ajp_type'
|
3
|
+
require 'baykit/bayserver/docker/ajp/command/package'
|
4
|
+
|
5
|
+
module Baykit
|
6
|
+
module BayServer
|
7
|
+
module Docker
|
8
|
+
module Ajp
|
9
|
+
class AjpCommandUnPacker <Baykit::BayServer::Protocol::CommandUnPacker
|
10
|
+
|
11
|
+
include Baykit::BayServer::Docker::Ajp::Command
|
12
|
+
|
13
|
+
attr :cmd_handler
|
14
|
+
|
15
|
+
def initialize(handler)
|
16
|
+
@cmd_handler = handler
|
17
|
+
reset
|
18
|
+
end
|
19
|
+
|
20
|
+
def reset()
|
21
|
+
end
|
22
|
+
|
23
|
+
def packet_received(pkt)
|
24
|
+
|
25
|
+
BayLog.debug("ajp: packet received: type=%d datalen=%d", pkt.type, pkt.data_len)
|
26
|
+
|
27
|
+
case pkt.type
|
28
|
+
when AjpType::DATA
|
29
|
+
cmd = CmdData.new
|
30
|
+
|
31
|
+
when AjpType::FORWARD_REQUEST
|
32
|
+
cmd = CmdForwardRequest.new
|
33
|
+
|
34
|
+
when AjpType::SEND_BODY_CHUNK
|
35
|
+
cmd = CmdSendBodyChunk.new(pkt.buf, pkt.header_len, pkt.data_len)
|
36
|
+
|
37
|
+
when AjpType::SEND_HEADERS
|
38
|
+
cmd = CmdSendHeaders.new
|
39
|
+
|
40
|
+
when AjpType::END_RESPONSE
|
41
|
+
cmd = CmdEndResponse.new
|
42
|
+
|
43
|
+
when AjpType::SHUTDOWN
|
44
|
+
cmd = CmdShutdown.new
|
45
|
+
|
46
|
+
when AjpType::GET_BODY_CHUNK
|
47
|
+
cmd = CmdGetBodyChunk.new
|
48
|
+
|
49
|
+
else
|
50
|
+
raise Sink.new()
|
51
|
+
end
|
52
|
+
|
53
|
+
cmd.unpack(pkt)
|
54
|
+
return cmd.handle(@cmd_handler) # visit
|
55
|
+
end
|
56
|
+
|
57
|
+
def need_data()
|
58
|
+
return @cmd_handler.need_data()
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
@@ -0,0 +1,292 @@
|
|
1
|
+
require 'baykit/bayserver/docker/base/inbound_handler'
|
2
|
+
require 'baykit/bayserver/tours/req_content_handler'
|
3
|
+
|
4
|
+
require 'baykit/bayserver/util/string_util'
|
5
|
+
require 'baykit/bayserver/util/http_util'
|
6
|
+
require 'baykit/bayserver/docker/ajp/ajp_protocol_handler'
|
7
|
+
require 'baykit/bayserver/docker/ajp/command/package'
|
8
|
+
|
9
|
+
module Baykit
|
10
|
+
module BayServer
|
11
|
+
module Docker
|
12
|
+
module Ajp
|
13
|
+
class AjpInboundHandler < Baykit::BayServer::Docker::Ajp::AjpProtocolHandler
|
14
|
+
|
15
|
+
class InboundProtocolHandlerFactory
|
16
|
+
include Baykit::BayServer::Protocol::ProtocolHandlerFactory # implements
|
17
|
+
|
18
|
+
def create_protocol_handler(pkt_store)
|
19
|
+
return AjpInboundHandler.new(pkt_store)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
include Baykit::BayServer::Docker::Base::InboundHandler # implements
|
24
|
+
include Baykit::BayServer::Util
|
25
|
+
include Baykit::BayServer::Agent
|
26
|
+
include Baykit::BayServer::Protocol
|
27
|
+
include Baykit::BayServer::Tours
|
28
|
+
include Baykit::BayServer::Docker::Ajp::Command
|
29
|
+
|
30
|
+
STATE_READ_FORWARD_REQUEST = :FORWARD_REQUEST
|
31
|
+
STATE_READ_DATA = :READ_DATA
|
32
|
+
|
33
|
+
DUMMY_KEY = 1
|
34
|
+
attr :cur_tour_id
|
35
|
+
attr :req_command
|
36
|
+
|
37
|
+
attr :state
|
38
|
+
attr :keeping
|
39
|
+
|
40
|
+
def initialize(pkt_store)
|
41
|
+
super(pkt_store, true)
|
42
|
+
reset_state()
|
43
|
+
end
|
44
|
+
|
45
|
+
######################################################
|
46
|
+
# implements Reusable
|
47
|
+
######################################################
|
48
|
+
def reset()
|
49
|
+
super
|
50
|
+
reset_state()
|
51
|
+
@req_command = nil
|
52
|
+
@keeping = false
|
53
|
+
@cur_tour_id = 0
|
54
|
+
end
|
55
|
+
|
56
|
+
######################################################
|
57
|
+
# implements InboundHandler
|
58
|
+
######################################################
|
59
|
+
def send_res_headers(tur)
|
60
|
+
chunked = false
|
61
|
+
cmd = CmdSendHeaders.new()
|
62
|
+
tur.res.headers.names.each do |name|
|
63
|
+
tur.res.headers.values(name).each do |value|
|
64
|
+
cmd.add_header(name, value)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
cmd.status = tur.res.headers.status
|
68
|
+
command_packer.post(@ship, cmd)
|
69
|
+
|
70
|
+
BayLog.debug("%s send header: content-length=%d", self, tur.res.headers.content_length())
|
71
|
+
end
|
72
|
+
|
73
|
+
def send_res_content(tur, bytes, ofs, len, &lis)
|
74
|
+
cmd = CmdSendBodyChunk.new(bytes, ofs, len);
|
75
|
+
@command_packer.post(ship, cmd, &lis);
|
76
|
+
end
|
77
|
+
|
78
|
+
def send_end_tour(tur, keep_alive, &callback)
|
79
|
+
BayLog.debug("%s endTour: tur=%s keep=%s", @ship, tur, keep_alive)
|
80
|
+
cmd = CmdEndResponse.new()
|
81
|
+
cmd.reuse = keep_alive
|
82
|
+
|
83
|
+
ensure_func = lambda do
|
84
|
+
if !keep_alive
|
85
|
+
command_packer.end(@ship)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
begin
|
90
|
+
command_packer.post(@ship, cmd) do
|
91
|
+
BayLog.debug("%s call back in sendEndTour: tur=%s keep=%s", self, tur, keep_alive)
|
92
|
+
ensure_func.call()
|
93
|
+
callback.call()
|
94
|
+
end
|
95
|
+
rescue IOError => e
|
96
|
+
BayLog.debug("%s post failed in sendEndTour: tur=%s keep=%s", self, tur, keep_alive)
|
97
|
+
ensure_func.call()
|
98
|
+
raise e
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def send_req_protocol_error(e)
|
103
|
+
tur = @ship.get_error_tour()
|
104
|
+
tur.res.send_error(Tour::TOUR_ID_NOCHECK, HttpStatus::BAD_REQUEST, e.message, e)
|
105
|
+
return true
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
######################################################
|
110
|
+
# implements AjpCommandHandler
|
111
|
+
######################################################
|
112
|
+
def handle_forward_request(cmd)
|
113
|
+
BayLog.debug("%s handleForwardRequest method=%s uri=%s", @ship, cmd.method, cmd.req_uri)
|
114
|
+
if @state != STATE_READ_FORWARD_REQUEST
|
115
|
+
raise ProtocolException.new("Invalid AJP command: #{cmd.type}")
|
116
|
+
end
|
117
|
+
|
118
|
+
@keeping = false
|
119
|
+
@req_command = cmd
|
120
|
+
tur = @ship.get_tour(DUMMY_KEY)
|
121
|
+
if tur == nil
|
122
|
+
BayLog.error(BayMessage.get(:INT_NO_MORE_TOURS))
|
123
|
+
tur = @ship.get_tour(AjpInboundHandler::DUMMY_KEY, true)
|
124
|
+
tur.res.send_error(Tour::TOUR_ID_NOCHECK, HttpStatus::SERVICE_UNAVAILABLE, "No available tours")
|
125
|
+
tur.res.end_content(Tour::TOUR_ID_NOCHECK)
|
126
|
+
@ship.agent.shutdown(false)
|
127
|
+
return NextSocketAction::CONTINUE
|
128
|
+
end
|
129
|
+
|
130
|
+
@cur_tour_id = tur.id
|
131
|
+
tur.req.uri = cmd.req_uri
|
132
|
+
tur.req.protocol = cmd.protocol
|
133
|
+
tur.req.method = cmd.method
|
134
|
+
cmd.headers.copy_to(tur.req.headers)
|
135
|
+
query_string = cmd.attributes["?query_string"]
|
136
|
+
|
137
|
+
if StringUtil.set?(query_string)
|
138
|
+
tur.req.uri += "?" + query_string
|
139
|
+
end
|
140
|
+
|
141
|
+
BayLog.debug("%s read header method=%s protocol=%s uri=%s contlen=%d",
|
142
|
+
tur, tur.req.method, tur.req.protocol, tur.req.uri, tur.req.headers.content_length)
|
143
|
+
|
144
|
+
if BayServer.harbor.trace_header?
|
145
|
+
cmd.headers.names.each do |name|
|
146
|
+
cmd.headers.values(name).each do |value|
|
147
|
+
BayLog.info("%s header: %s=%s", tur, name, value)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
req_cont_len = cmd.headers.content_length
|
153
|
+
if req_cont_len > 0
|
154
|
+
sid = @ship.ship_id
|
155
|
+
tur.req.set_consume_listener(req_cont_len) do |len, resume|
|
156
|
+
if resume
|
157
|
+
@ship.resume(sid)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
begin
|
163
|
+
start_tour(tur)
|
164
|
+
|
165
|
+
if req_cont_len <= 0
|
166
|
+
end_req_content(tur)
|
167
|
+
else
|
168
|
+
change_state(STATE_READ_DATA)
|
169
|
+
end
|
170
|
+
|
171
|
+
return NextSocketAction::CONTINUE
|
172
|
+
rescue HttpException => e
|
173
|
+
if req_cont_len <= 0
|
174
|
+
tur.res.send_http_exception(Tour::TOUR_ID_NOCHECK, e)
|
175
|
+
reset_state()
|
176
|
+
return NextSocketAction::WRITE
|
177
|
+
else
|
178
|
+
# Delay send
|
179
|
+
change_state(STATE_READ_DATA)
|
180
|
+
tur.error = e
|
181
|
+
tur.req.set_content_handler(ReqContentHandler::DEV_NULL)
|
182
|
+
return NextSocketAction::CONTINUE
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def handle_data(cmd)
|
188
|
+
BayLog.debug("%s handleData len=%s", @ship, cmd.length)
|
189
|
+
|
190
|
+
if @state != STATE_READ_DATA
|
191
|
+
raise RuntimeError.new("Invalid AJP command: #{cmd.type} state=#{@state}")
|
192
|
+
end
|
193
|
+
|
194
|
+
tur = @ship.get_tour(DUMMY_KEY)
|
195
|
+
success = tur.req.post_content(Tour::TOUR_ID_NOCHECK, cmd.data, cmd.start, cmd.length)
|
196
|
+
|
197
|
+
if tur.req.bytes_posted == tur.req.bytes_limit
|
198
|
+
# request content completed
|
199
|
+
|
200
|
+
if tur.error != nil
|
201
|
+
tur.res.send_http_exception(Tour::TOUR_ID_NOCHECK, tur.error)
|
202
|
+
reset_state()
|
203
|
+
return NextSocketAction::WRITE
|
204
|
+
else
|
205
|
+
begin
|
206
|
+
end_req_content(tur)
|
207
|
+
return NextSocketAction::CONTINUE
|
208
|
+
rescue HttpException => e
|
209
|
+
tur.res.send_http_exception(Tour::TOUR_ID_NOCHECK, e)
|
210
|
+
reset_state()
|
211
|
+
return NextSocketAction::WRITE
|
212
|
+
end
|
213
|
+
end
|
214
|
+
else
|
215
|
+
bch = CmdGetBodyChunk.new()
|
216
|
+
bch.req_len = tur.req.bytes_limit - tur.req.bytes_posted
|
217
|
+
if bch.req_len > AjpPacket::MAX_DATA_LEN
|
218
|
+
bch.req_len = AjpPacket::MAX_DATA_LEN
|
219
|
+
end
|
220
|
+
command_packer.post(@ship, bch)
|
221
|
+
|
222
|
+
if !success
|
223
|
+
return NextSocketAction::SUSPEND
|
224
|
+
else
|
225
|
+
return NextSocketAction::CONTINUE
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def handle_send_body_chunk(cmd)
|
231
|
+
raise RuntimeError.new "Invalid AJP command: #{cmd.type}"
|
232
|
+
end
|
233
|
+
|
234
|
+
def handle_send_headers(cmd)
|
235
|
+
raise RuntimeError.new "Invalid AJP command: #{cmd.type}"
|
236
|
+
end
|
237
|
+
|
238
|
+
def handle_shutdown(cmd)
|
239
|
+
BayLog.info("%s handle_shutdown", @ship)
|
240
|
+
BayServer.shutdown
|
241
|
+
NextSocketAction::CLOSE
|
242
|
+
end
|
243
|
+
|
244
|
+
def handle_end_response(cmd)
|
245
|
+
raise RuntimeError.new "Invalid AJP command: #{cmd.type}"
|
246
|
+
end
|
247
|
+
|
248
|
+
def handle_get_body_chunk(cmd)
|
249
|
+
raise RuntimeError.new "Invalid AJP command: #{cmd.type}"
|
250
|
+
end
|
251
|
+
|
252
|
+
def need_data()
|
253
|
+
return @state == STATE_READ_DATA
|
254
|
+
end
|
255
|
+
|
256
|
+
private
|
257
|
+
def reset_state
|
258
|
+
change_state(STATE_READ_FORWARD_REQUEST)
|
259
|
+
end
|
260
|
+
|
261
|
+
def change_state(new_state)
|
262
|
+
@state = new_state
|
263
|
+
end
|
264
|
+
|
265
|
+
def end_req_content(tur)
|
266
|
+
tur.req.end_content(Tour::TOUR_ID_NOCHECK)
|
267
|
+
reset_state()
|
268
|
+
end
|
269
|
+
|
270
|
+
def start_tour(tur)
|
271
|
+
HttpUtil.parse_host_port(tur, @req_command.is_ssl ? 443 : 80)
|
272
|
+
HttpUtil.parse_authorization(tur)
|
273
|
+
|
274
|
+
skt = @ship.socket
|
275
|
+
tur.req.remote_port = nil
|
276
|
+
tur.req.remote_address = @req_command.remote_addr
|
277
|
+
tur.req.remote_host_func = lambda { @req_command.remote_host }
|
278
|
+
|
279
|
+
tur.req.server_address = skt.local_address.ip_address
|
280
|
+
tur.req.server_port = @req_command.server_port
|
281
|
+
tur.req.server_name = @req_command.server_name
|
282
|
+
tur.is_secure = @req_command.is_ssl
|
283
|
+
|
284
|
+
tur.go()
|
285
|
+
end
|
286
|
+
|
287
|
+
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'baykit/bayserver/protocol/packet_part_accessor'
|
2
|
+
require 'baykit/bayserver/util/string_util'
|
3
|
+
require 'baykit/bayserver/protocol/packet'
|
4
|
+
|
5
|
+
#
|
6
|
+
# AJP Protocol
|
7
|
+
# https://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html
|
8
|
+
#
|
9
|
+
# AJP packet spec
|
10
|
+
#
|
11
|
+
# packet: preamble, length, body
|
12
|
+
# preamble:
|
13
|
+
# 0x12, 0x34 (client->server)
|
14
|
+
# | 'A', 'B' (server->client)
|
15
|
+
# length:
|
16
|
+
# 2 byte
|
17
|
+
# body:
|
18
|
+
# $length byte
|
19
|
+
#
|
20
|
+
#
|
21
|
+
# Body format
|
22
|
+
# client->server
|
23
|
+
# Code Type of Packet Meaning
|
24
|
+
# 2 Forward Request Begin the request-processing cycle with the following data
|
25
|
+
# 7 Shutdown The web server asks the container to shut itself down.
|
26
|
+
# 8 Ping The web server asks the container to take control (secure login phase).
|
27
|
+
# 10 CPing The web server asks the container to respond quickly with a CPong.
|
28
|
+
# none Data Size (2 bytes) and corresponding body data.
|
29
|
+
#
|
30
|
+
# server->client
|
31
|
+
# Code Type of Packet Meaning
|
32
|
+
# 3 Send Body Chunk Send a chunk of the body from the servlet container to the web server (and presumably, onto the browser).
|
33
|
+
# 4 Send Headers Send the response headers from the servlet container to the web server (and presumably, onto the browser).
|
34
|
+
# 5 End Response Marks the end of the response (and thus the request-handling cycle).
|
35
|
+
# 6 Get Body Chunk Get further data from the request if it hasn't all been transferred yet.
|
36
|
+
# 9 CPong Reply The reply to a CPing request
|
37
|
+
#
|
38
|
+
#
|
39
|
+
|
40
|
+
module Baykit
|
41
|
+
module BayServer
|
42
|
+
module Docker
|
43
|
+
module Ajp
|
44
|
+
class AjpPacket < Baykit::BayServer::Protocol::Packet
|
45
|
+
class AjpAccessor < Baykit::BayServer::Protocol::PacketPartAccessor
|
46
|
+
include Baykit::BayServer::Util
|
47
|
+
|
48
|
+
def initialize(type, start, max_len)
|
49
|
+
super
|
50
|
+
end
|
51
|
+
|
52
|
+
def put_string(str)
|
53
|
+
if StringUtil.empty?(str)
|
54
|
+
put_short(0xffff)
|
55
|
+
else
|
56
|
+
put_short(str.length)
|
57
|
+
super str
|
58
|
+
put_byte(0) # null terminator
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def get_string
|
63
|
+
get_string_by_len(get_short())
|
64
|
+
end
|
65
|
+
|
66
|
+
def get_string_by_len(len)
|
67
|
+
|
68
|
+
if len == 0xffff
|
69
|
+
return ""
|
70
|
+
end
|
71
|
+
|
72
|
+
buf = StringUtil.alloc(len)
|
73
|
+
get_bytes(buf, 0, len)
|
74
|
+
get_byte() # null terminator
|
75
|
+
|
76
|
+
buf
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
PREAMBLE_SIZE = 4
|
81
|
+
MAX_DATA_LEN = 8192 - PREAMBLE_SIZE
|
82
|
+
MIN_BUF_SIZE = 1024
|
83
|
+
|
84
|
+
attr_accessor :to_server
|
85
|
+
|
86
|
+
def initialize(type)
|
87
|
+
super(type, PREAMBLE_SIZE, MAX_DATA_LEN)
|
88
|
+
end
|
89
|
+
|
90
|
+
def reset()
|
91
|
+
@to_server = false
|
92
|
+
super
|
93
|
+
end
|
94
|
+
|
95
|
+
def new_ajp_header_accessor
|
96
|
+
AjpAccessor.new(self, 0, PREAMBLE_SIZE)
|
97
|
+
end
|
98
|
+
|
99
|
+
def new_ajp_data_accessor
|
100
|
+
AjpAccessor.new(self, PREAMBLE_SIZE, -1)
|
101
|
+
end
|
102
|
+
|
103
|
+
def to_s
|
104
|
+
"AjpPacket(#{@type})"
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'baykit/bayserver/protocol/packet_factory'
|
2
|
+
|
3
|
+
module Baykit
|
4
|
+
module BayServer
|
5
|
+
module Docker
|
6
|
+
module Ajp
|
7
|
+
class AjpPacketFactory < Baykit::BayServer::Protocol::PacketFactory
|
8
|
+
|
9
|
+
def create_packet(type)
|
10
|
+
AjpPacket.new(type)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|