bayserver-docker-http 3.0.5 → 3.3.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b3f7151a765dc5d7e998d7ada10ae2ecc046085647e28ce01c8376c07c34499c
4
- data.tar.gz: '01791184ee8ceff8fafbeacfab0159f7c8ec0e9079a3bcfcf09e63030350cb61'
3
+ metadata.gz: 77533775218a5eeece533642ac1268d650988959191835225d32c64169b0a22b
4
+ data.tar.gz: 1f84273c4d5308ed6f0a9f35304d87a3ac81f39bc82ca1e2f76b51cb9e42fc72
5
5
  SHA512:
6
- metadata.gz: 33972f70152484741d656ad3ff12c7de391aad24bcce455c64eb9c37b169ad7c9c50b7f9bd92e130df634ad91b290b4bb62a10d39f5c32aae62a344df1676238
7
- data.tar.gz: 3efd07af360f198d91289441dac24e3da3094e3207c3f1f429e45a3b71fbcd47d4f06f31d12d99696fbbd2364fb4d6ebf4552741a2e8dc771647af1acb75b7d9
6
+ metadata.gz: 8843bca3e9b0468c6c2b3f3a92803c2f8246a670ac8f94258c3e4b73bc5a2cf959b0d6d8e86067bd3f8ef7fe58a69b910bd37a9156fe55de7df26db937603693
7
+ data.tar.gz: 589f8e2c5db82799fe851e78c1a42c35a51dd963f849aad53f3dad6d246293cd0baa5e7e6cdbd7f9b271e84a18a0cba531ef5b661ca289472dcf0d804c13651b
@@ -118,42 +118,48 @@ module Baykit
118
118
  end
119
119
 
120
120
  def unpack(pkt)
121
- acc = pkt.new_data_accessor
122
121
  data_len = pkt.data_len()
123
122
  state = STATE_READ_FIRST_LINE
124
123
 
125
124
  line_start_pos = 0
126
125
  line_len = 0
127
126
 
128
- data_len.times do |pos|
129
- b = acc.get_byte
130
- case b
131
- when CharUtil::CR_BYTE
132
- next
127
+ pos = 0
128
+ while pos < data_len
129
+ next_nl = pkt.buf.index("\n", pos)
130
+ if !next_nl
131
+ # No more new lines
132
+ break
133
+ end
133
134
 
134
- when CharUtil::LF_BYTE
135
- if line_len == 0
136
- break
137
- end
138
- if state == STATE_READ_FIRST_LINE
139
- if @is_req_header
140
- unpack_request_line(pkt.buf, line_start_pos, line_len)
141
- else
142
- unpack_status_line(pkt.buf, line_start_pos, line_len)
143
- end
144
-
145
- state = STATE_READ_MESSAGE_HEADERS
135
+ line_start_pos = pos
136
+
137
+ # Calculate line length excluding \n
138
+ # Also handle \r if it exists just before \n
139
+ line_end = (next_nl > pos && pkt.buf[next_nl - 1] == "\r") ? next_nl - 1 : next_nl
140
+ line_len = line_end - pos
141
+
142
+ if line_len == 0
143
+ # Empty line found (End of headers)
144
+ # Move pos past the newline and exit
145
+ pos = next_nl + 1
146
+ break
147
+ end
148
+
149
+ if state == STATE_READ_FIRST_LINE
150
+ if @is_req_header
151
+ unpack_request_line(pkt.buf, pos, line_len)
146
152
  else
147
- unpack_message_header(pkt.buf, line_start_pos, line_len)
153
+ unpack_status_line(pkt.buf, pos, line_len)
148
154
  end
149
155
 
150
- line_len = 0
151
- line_start_pos = pos + 1
152
-
156
+ state = STATE_READ_MESSAGE_HEADERS
153
157
  else
154
- line_len += 1
158
+ unpack_message_header(pkt.buf, pos, line_len)
155
159
  end
156
160
 
161
+ # Move to the start of the next line
162
+ pos = next_nl + 1
157
163
  end
158
164
 
159
165
  if state == STATE_READ_FIRST_LINE
@@ -257,11 +263,11 @@ module Baykit
257
263
  end
258
264
 
259
265
  def pack_request_line(acc)
260
- acc.put_string(@method)
266
+ acc.put_bytes(@method)
261
267
  acc.put_bytes(" ")
262
- acc.put_string(@uri)
268
+ acc.put_bytes(@uri)
263
269
  acc.put_bytes(" ")
264
- acc.put_string(@version);
270
+ acc.put_bytes(@version)
265
271
  acc.put_bytes(CharUtil::CRLF)
266
272
  end
267
273
 
@@ -276,9 +282,9 @@ module Baykit
276
282
 
277
283
  # status
278
284
  acc.put_bytes(" ")
279
- acc.put_string(@status.to_s)
285
+ acc.put_bytes(@status.to_s)
280
286
  acc.put_bytes(" ")
281
- acc.put_string(desc)
287
+ acc.put_bytes(desc)
282
288
  acc.put_bytes(CharUtil::CRLF)
283
289
  end
284
290
 
@@ -289,9 +295,9 @@ module Baykit
289
295
  if !value.kind_of?(String)
290
296
  raise RuntimeError.new("IllegalArgument: #{value}")
291
297
  end
292
- acc.put_string(name)
298
+ acc.put_bytes(name)
293
299
  acc.put_bytes(":")
294
- acc.put_string(value)
300
+ acc.put_bytes(value)
295
301
  acc.put_bytes(CharUtil::CRLF)
296
302
  end
297
303
 
@@ -99,13 +99,13 @@ module Baykit
99
99
  def send_res_headers(tur)
100
100
 
101
101
  # determine Connection header value
102
- if tur.req.headers.get_connection() != Headers::CONNECTION_KEEP_ALIVE
102
+ if tur.req.headers.get_connection() != Headers::CONNECTION_KEEP_ALIVE && tur.req.headers.get_connection() != Headers::CONNECTION_UNKNOWN
103
103
  # If client doesn't support "Keep-Alive", set "Close"
104
104
  res_con = "Close"
105
105
  else
106
106
  res_con = "Keep-Alive"
107
107
  # Client supports "Keep-Alive"
108
- if tur.res.headers.get_connection() != Headers::CONNECTION_KEEP_ALIVE
108
+ if tur.res.headers.get_connection() != Headers::CONNECTION_KEEP_ALIVE && tur.res.headers.get_connection() != Headers::CONNECTION_UNKNOWN
109
109
  # If tours doesn't need "Keep-Alive"
110
110
  if tur.res.headers.content_length() == -1
111
111
  # If content-length not specified
@@ -139,7 +139,8 @@ module Baykit
139
139
  @protocol_handler.post(cmd, &callback)
140
140
  end
141
141
 
142
- def send_end_tour(tur, keep_alive, &callback)
142
+ def send_end_tour(tur, &callback)
143
+ keep_alive = tur.res.headers.get_connection() == Headers::CONNECTION_KEEP_ALIVE
143
144
  BayLog.trace("%s sendEndTour: tur=%s keep=%s", ship, tur, keep_alive)
144
145
 
145
146
  # Send dummy end request command
@@ -175,7 +176,7 @@ module Baykit
175
176
  end
176
177
 
177
178
  tur.res.send_error(Tour::TOUR_ID_NOCHECK, HttpStatus::BAD_REQUEST, err.message, err)
178
- true
179
+ false
179
180
  end
180
181
 
181
182
  ######################################################
@@ -68,50 +68,45 @@ module Baykit
68
68
  suspend = false
69
69
 
70
70
  if @state == STATE_READ_HEADERS
71
- while pos < buf.length
72
- b = buf[pos]
73
- @tmp_buf.put_byte(b)
74
- pos += 1
75
- #@BayServer.info b + " " + b.codepoints[0].to_s + " pos=" + pos.to_s
76
- if b == CharUtil::CR
77
- next
78
- elsif b == CharUtil::LF
79
- if line_len == 0
80
- # empty line (all headers are read)
81
- pkt = @pkt_store.rent(H1Type::HEADER)
82
- pkt.new_data_accessor.put_bytes(@tmp_buf.bytes, 0, @tmp_buf.length)
83
-
84
- begin
85
- next_act = @cmd_upacker.packet_received(pkt)
86
- ensure
87
- @pkt_store.Return pkt
88
- end
89
-
90
- case next_act
91
- when NextSocketAction::CONTINUE, NextSocketAction::SUSPEND
92
- if @cmd_upacker.finished()
93
- change_state(STATE_END)
94
- else
95
- change_state(STATE_READ_CONTENT)
96
- end
97
- when NextSocketAction::CLOSE
98
- # Maybe error
99
- reset_state()
100
- return next_act
101
- else
102
- raise RuntimeError.new("Invalid next action: #{next_act}")
103
- end
104
-
105
- suspend = (next_act == NextSocketAction::SUSPEND)
106
- break
71
+
72
+ # Find end of headers (empty line)
73
+ # Look for \n\n (LF+LF) or \n\r\n (LF+CR+LF)
74
+ header_end_pos = buf.index("\n\r\n", pos) || buf.index("\n\n", pos)
75
+
76
+ if header_end_pos
77
+ # Calculate total header length
78
+ header_len = (buf[header_end_pos + 1] == "\r") ? header_end_pos + 3 : header_end_pos + 2
79
+
80
+ # Batch copy all header bytes at once
81
+ @tmp_buf.put(buf, pos, header_len - pos)
82
+ pos = header_len
83
+
84
+ # Move to packet processing
85
+ pkt = @pkt_store.rent(H1Type::HEADER)
86
+ pkt.new_data_accessor.put_bytes(@tmp_buf.bytes, 0, @tmp_buf.length)
87
+
88
+ begin
89
+ next_act = @cmd_upacker.packet_received(pkt)
90
+ ensure
91
+ @pkt_store.Return pkt
92
+ end
93
+
94
+ case next_act
95
+ when NextSocketAction::CONTINUE, NextSocketAction::SUSPEND
96
+ if @cmd_upacker.finished()
97
+ change_state(STATE_END)
98
+ else
99
+ change_state(STATE_READ_CONTENT)
107
100
  end
108
- line_len = 0
101
+ when NextSocketAction::CLOSE
102
+ # Maybe error
103
+ reset_state()
104
+ return next_act
109
105
  else
110
- line_len += 1
111
- end
112
- if line_len >= MAX_LINE_LEN
113
- raise ProtocolException.new("Http/1 Line is too long")
106
+ raise RuntimeError.new("Invalid next action: #{next_act}")
114
107
  end
108
+
109
+ suspend = (next_act == NextSocketAction::SUSPEND)
115
110
  end
116
111
  end
117
112
 
@@ -0,0 +1,58 @@
1
+ require 'baykit/bayserver/docker/http/h2/package'
2
+
3
+ #
4
+ # HTTP/2 Continuation payload format
5
+ #
6
+ # +---------------------------------------------------------------+
7
+ # | Header Block Fragment (*) ...
8
+ # +---------------------------------------------------------------+
9
+ #
10
+ module Baykit
11
+ module BayServer
12
+ module Docker
13
+ module Http
14
+ module H2
15
+ module Command
16
+
17
+ class CmdContinuation < Baykit::BayServer::Docker::Http::H2::H2Command
18
+ include Baykit::BayServer::Docker::Http::H2
19
+
20
+ #
21
+ # This class refers external byte array, so this IS NOT mutable
22
+ #
23
+ attr :start
24
+ attr :length
25
+ attr :data
26
+
27
+ def initialize(stream_id, flags = nil)
28
+ super(H2Type::CONTINUATION, stream_id, flags)
29
+ end
30
+
31
+ def unpack(pkt)
32
+ super
33
+ @data = pkt.buf
34
+ @start = pkt.header_len
35
+ @length = pkt.data_len()
36
+ end
37
+
38
+ def pack(pkt)
39
+ acc = pkt.new_data_accessor()
40
+ if @flags.padded?
41
+ raise RuntimeError.new("Padding not supported")
42
+ end
43
+ acc.put_bytes(@data, @start, @length)
44
+ super
45
+ end
46
+
47
+ def handle(cmd_handler)
48
+ return cmd_handler.handle_continuation(self)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+
@@ -25,6 +25,13 @@ module Baykit
25
25
  class CmdHeaders < Baykit::BayServer::Docker::Http::H2::H2Command
26
26
  include Baykit::BayServer::Docker::Http::H2
27
27
 
28
+ #
29
+ # This class refers external byte array, so this IS NOT mutable
30
+ #
31
+ attr_accessor :start
32
+ attr_accessor :length
33
+ attr_accessor :data
34
+
28
35
  attr :pad_length
29
36
  attr_accessor :excluded
30
37
  attr :stream_dependency
@@ -42,7 +49,7 @@ module Baykit
42
49
 
43
50
  def unpack(pkt)
44
51
  super
45
- acc = pkt.new_h2_data_accessor
52
+ acc = pkt.new_data_accessor
46
53
 
47
54
  if pkt.flags.padded?
48
55
  @pad_length = acc.get_byte
@@ -53,11 +60,13 @@ module Baykit
53
60
  @stream_dependency = H2Packet.extract_int31(val)
54
61
  @weight = acc.get_byte
55
62
  end
56
- read_header_block(acc, pkt.data_len())
63
+ @data = pkt.buf
64
+ @start = pkt.header_len + acc.pos
65
+ @length = pkt.data_len - acc.pos
57
66
  end
58
67
 
59
68
  def pack(pkt)
60
- acc = pkt.new_h2_data_accessor
69
+ acc = pkt.new_data_accessor
61
70
 
62
71
  if @flags.padded?
63
72
  acc.put_byte(@pad_length)
@@ -67,7 +76,8 @@ module Baykit
67
76
  acc.put_int(H2Packet.make_stream_dependency32(@excluded, @stream_dependency))
68
77
  acc.put_byte(@weight)
69
78
  end
70
- write_header_block(acc)
79
+
80
+ acc.put_bytes(@data, @start, @length)
71
81
  super
72
82
  end
73
83
 
@@ -75,28 +85,6 @@ module Baykit
75
85
  return cmd_handler.handle_headers(self)
76
86
  end
77
87
 
78
- def read_header_block(acc, len)
79
- while acc.pos < len
80
- blk = HeaderBlock.unpack(acc)
81
- #if(BayLog.trace_mode?)
82
- # BayLog.trace "h2: Read header block: #{blk}"
83
- #end
84
- @header_blocks << blk
85
- end
86
- end
87
-
88
- def write_header_block(acc)
89
- @header_blocks.each do |blk|
90
- #if(BayLog.trace_mode?)
91
- # BayLog.trace "h2: Write header block: #{blk}"
92
- #end
93
- HeaderBlock.pack(blk, acc)
94
- end
95
- end
96
-
97
- def add_header_block(blk)
98
- @header_blocks.append(blk)
99
- end
100
88
  end
101
89
  end
102
90
  end
@@ -33,7 +33,7 @@ module Baykit
33
33
  end
34
34
 
35
35
  def pack(pkt)
36
- acc = pkt.new_h2_data_accessor()
36
+ acc = pkt.new_data_accessor()
37
37
  acc.put_bytes(PREFACE_BYTES)
38
38
  end
39
39
 
@@ -7,3 +7,4 @@ require 'baykit/bayserver/docker/http/h2/command/cmd_priority'
7
7
  require 'baykit/bayserver/docker/http/h2/command/cmd_rst_stream'
8
8
  require 'baykit/bayserver/docker/http/h2/command/cmd_settings'
9
9
  require 'baykit/bayserver/docker/http/h2/command/cmd_window_update'
10
+ require 'baykit/bayserver/docker/http/h2/command/cmd_continuation'
@@ -41,6 +41,10 @@ module Baykit
41
41
  def handle_rst_stream(cmd)
42
42
  raise NotImplementedError.new
43
43
  end
44
+
45
+ def handle_continuation(cmd)
46
+ raise NotImplementedError.new
47
+ end
44
48
  end
45
49
  end
46
50
  end
@@ -54,6 +54,9 @@ module Baykit
54
54
  when H2Type::RST_STREAM
55
55
  cmd = CmdRstStream.new(pkt.stream_id, pkt.flags)
56
56
 
57
+ when H2Type::CONTINUATION
58
+ cmd = CmdContinuation.new(pkt.stream_id, pkt.flags)
59
+
57
60
  else
58
61
  reset()
59
62
  raise RuntimeError.new("Invalid Packet: #{pkt}")