tipi 0.38 → 0.42
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +5 -1
- data/.gitignore +5 -0
- data/CHANGELOG.md +34 -0
- data/Gemfile +5 -1
- data/Gemfile.lock +58 -16
- data/Rakefile +7 -3
- data/TODO.md +77 -1
- data/benchmarks/bm_http1_parser.rb +61 -0
- data/bin/benchmark +37 -0
- data/bin/h1pd +6 -0
- data/bin/tipi +3 -21
- data/df/sample_agent.rb +1 -1
- data/df/server.rb +16 -47
- data/df/server_utils.rb +178 -0
- data/examples/full_service.rb +13 -0
- data/examples/http1_parser.rb +55 -0
- data/examples/http_server.rb +15 -3
- data/examples/http_server_forked.rb +5 -1
- data/examples/http_server_routes.rb +29 -0
- data/examples/http_server_static.rb +26 -0
- data/examples/http_server_throttled.rb +3 -2
- data/examples/https_server.rb +6 -4
- data/examples/https_wss_server.rb +2 -1
- data/examples/rack_server.rb +5 -0
- data/examples/rack_server_https.rb +1 -1
- data/examples/rack_server_https_forked.rb +4 -3
- data/examples/routing_server.rb +5 -4
- data/examples/servername_cb.rb +37 -0
- data/examples/websocket_demo.rb +2 -8
- data/examples/ws_page.html +2 -2
- data/ext/tipi/extconf.rb +13 -0
- data/ext/tipi/http1_parser.c +823 -0
- data/ext/tipi/http1_parser.h +18 -0
- data/ext/tipi/tipi_ext.c +5 -0
- data/lib/tipi.rb +89 -1
- data/lib/tipi/acme.rb +308 -0
- data/lib/tipi/cli.rb +30 -0
- data/lib/tipi/digital_fabric/agent.rb +22 -17
- data/lib/tipi/digital_fabric/agent_proxy.rb +95 -40
- data/lib/tipi/digital_fabric/executive.rb +6 -2
- data/lib/tipi/digital_fabric/protocol.rb +87 -15
- data/lib/tipi/digital_fabric/request_adapter.rb +6 -10
- data/lib/tipi/digital_fabric/service.rb +77 -51
- data/lib/tipi/http1_adapter.rb +116 -117
- data/lib/tipi/http2_adapter.rb +56 -10
- data/lib/tipi/http2_stream.rb +106 -53
- data/lib/tipi/rack_adapter.rb +2 -53
- data/lib/tipi/response_extensions.rb +17 -0
- data/lib/tipi/version.rb +1 -1
- data/security/http1.rb +12 -0
- data/test/helper.rb +60 -11
- data/test/test_http1_parser.rb +586 -0
- data/test/test_http_server.rb +0 -27
- data/test/test_request.rb +1 -28
- data/tipi.gemspec +11 -5
- metadata +96 -22
- data/e +0 -0
@@ -24,9 +24,11 @@ module DigitalFabric
|
|
24
24
|
class GracefulShutdown < RuntimeError
|
25
25
|
end
|
26
26
|
|
27
|
+
@@id = 0
|
28
|
+
|
27
29
|
def run
|
28
30
|
@fiber = Fiber.current
|
29
|
-
@keep_alive_timer = spin_loop(interval: 5) { keep_alive }
|
31
|
+
@keep_alive_timer = spin_loop("#{@fiber.tag}-keep_alive", interval: 5) { keep_alive }
|
30
32
|
while true
|
31
33
|
connect_and_process_incoming_requests
|
32
34
|
return if @shutdown
|
@@ -119,7 +121,7 @@ module DigitalFabric
|
|
119
121
|
|
120
122
|
def recv_df_message(msg)
|
121
123
|
@last_recv = Time.now
|
122
|
-
case msg[
|
124
|
+
case msg[Protocol::Attribute::KIND]
|
123
125
|
when Protocol::SHUTDOWN
|
124
126
|
recv_shutdown
|
125
127
|
when Protocol::HTTP_REQUEST
|
@@ -130,7 +132,7 @@ module DigitalFabric
|
|
130
132
|
recv_ws_request(msg)
|
131
133
|
when Protocol::CONN_DATA, Protocol::CONN_CLOSE,
|
132
134
|
Protocol::WS_DATA, Protocol::WS_CLOSE
|
133
|
-
fiber = @requests[msg[
|
135
|
+
fiber = @requests[msg[Protocol::Attribute::ID]]
|
134
136
|
fiber << msg if fiber
|
135
137
|
end
|
136
138
|
end
|
@@ -140,7 +142,7 @@ module DigitalFabric
|
|
140
142
|
# messages. This is so we can correctly stop long-running requests
|
141
143
|
# upon graceful shutdown
|
142
144
|
if is_long_running_request_response?(msg)
|
143
|
-
id = msg[
|
145
|
+
id = msg[Protocol::Attribute::ID]
|
144
146
|
@long_running_requests[id] = @requests[id]
|
145
147
|
end
|
146
148
|
@last_send = Time.now
|
@@ -148,11 +150,11 @@ module DigitalFabric
|
|
148
150
|
end
|
149
151
|
|
150
152
|
def is_long_running_request_response?(msg)
|
151
|
-
case msg[
|
153
|
+
case msg[Protocol::Attribute::KIND]
|
152
154
|
when Protocol::HTTP_UPGRADE
|
153
155
|
true
|
154
156
|
when Protocol::HTTP_RESPONSE
|
155
|
-
|
157
|
+
!msg[Protocol::Attribute::HttpResponse::COMPLETE]
|
156
158
|
end
|
157
159
|
end
|
158
160
|
|
@@ -165,13 +167,14 @@ module DigitalFabric
|
|
165
167
|
|
166
168
|
def recv_http_request(msg)
|
167
169
|
req = prepare_http_request(msg)
|
168
|
-
id = msg[
|
169
|
-
@requests[id] = spin do
|
170
|
+
id = msg[Protocol::Attribute::ID]
|
171
|
+
@requests[id] = spin("#{Fiber.current.tag}.#{id}") do
|
170
172
|
http_request(req)
|
171
173
|
rescue IOError, Errno::ECONNREFUSED, Errno::EPIPE
|
172
174
|
# ignore
|
173
|
-
rescue Polyphony::Terminate
|
175
|
+
rescue Polyphony::Terminate => e
|
174
176
|
req.respond(nil, { ':status' => Qeweney::Status::SERVICE_UNAVAILABLE }) if Fiber.current.graceful_shutdown?
|
177
|
+
raise e
|
175
178
|
ensure
|
176
179
|
@requests.delete(id)
|
177
180
|
@long_running_requests.delete(id)
|
@@ -180,17 +183,19 @@ module DigitalFabric
|
|
180
183
|
end
|
181
184
|
|
182
185
|
def prepare_http_request(msg)
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
+
headers = msg[Protocol::Attribute::HttpRequest::HEADERS]
|
187
|
+
body_chunk = msg[Protocol::Attribute::HttpRequest::BODY_CHUNK]
|
188
|
+
complete = msg[Protocol::Attribute::HttpRequest::COMPLETE]
|
189
|
+
req = Qeweney::Request.new(headers, RequestAdapter.new(self, msg))
|
190
|
+
req.buffer_body_chunk(body_chunk) if body_chunk
|
186
191
|
req
|
187
192
|
end
|
188
193
|
|
189
194
|
def recv_http_request_body(msg)
|
190
|
-
fiber = @requests[msg[
|
195
|
+
fiber = @requests[msg[Protocol::Attribute::ID]]
|
191
196
|
return unless fiber
|
192
197
|
|
193
|
-
fiber << msg[
|
198
|
+
fiber << msg[Protocol::Attribute::HttpRequestBody::BODY]
|
194
199
|
end
|
195
200
|
|
196
201
|
def get_http_request_body(id, limit)
|
@@ -199,9 +204,9 @@ module DigitalFabric
|
|
199
204
|
end
|
200
205
|
|
201
206
|
def recv_ws_request(msg)
|
202
|
-
req = Qeweney::Request.new(msg[
|
203
|
-
id = msg[
|
204
|
-
@requests[id] = @long_running_requests[id] = spin do
|
207
|
+
req = Qeweney::Request.new(msg[Protocol::Attribute::WS::HEADERS], RequestAdapter.new(self, msg))
|
208
|
+
id = msg[Protocol::Attribute::ID]
|
209
|
+
@requests[id] = @long_running_requests[id] = spin("#{Fiber.current.tag}.#{id}-ws") do
|
205
210
|
ws_request(req)
|
206
211
|
rescue IOError, Errno::ECONNREFUSED, Errno::EPIPE
|
207
212
|
# ignore
|
@@ -31,14 +31,15 @@ module DigitalFabric
|
|
31
31
|
def run
|
32
32
|
@fiber = Fiber.current
|
33
33
|
@service.mount(route, self)
|
34
|
-
|
34
|
+
@mounted = true
|
35
|
+
# keep_alive_timer = spin_loop("#{@fiber.tag}-keep_alive", interval: 5) { keep_alive }
|
35
36
|
process_incoming_messages(false)
|
36
37
|
rescue GracefulShutdown
|
37
38
|
puts "Proxy got graceful shutdown, left: #{@requests.size} requests" if @requests.size > 0
|
38
|
-
process_incoming_messages(true)
|
39
|
+
move_on_after(15) { process_incoming_messages(true) }
|
39
40
|
ensure
|
40
|
-
keep_alive_timer&.stop
|
41
|
-
|
41
|
+
# keep_alive_timer&.stop
|
42
|
+
unmount
|
42
43
|
end
|
43
44
|
|
44
45
|
def process_incoming_messages(shutdown = false)
|
@@ -48,10 +49,18 @@ module DigitalFabric
|
|
48
49
|
recv_df_message(msg)
|
49
50
|
return if shutdown && @requests.empty?
|
50
51
|
end
|
51
|
-
rescue TimeoutError, IOError
|
52
|
+
rescue TimeoutError, IOError, SystemCallError
|
53
|
+
# ignore and just return in order to terminate the proxy
|
54
|
+
end
|
55
|
+
|
56
|
+
def unmount
|
57
|
+
return unless @mounted
|
58
|
+
|
59
|
+
@service.unmount(self)
|
60
|
+
@mounted = nil
|
52
61
|
end
|
53
62
|
|
54
|
-
def
|
63
|
+
def send_shutdown
|
55
64
|
send_df_message(Protocol.shutdown)
|
56
65
|
@fiber.raise GracefulShutdown.new
|
57
66
|
end
|
@@ -82,9 +91,18 @@ module DigitalFabric
|
|
82
91
|
|
83
92
|
def recv_df_message(message)
|
84
93
|
@last_recv = Time.now
|
85
|
-
|
94
|
+
# puts "<<< #{message.inspect}"
|
95
|
+
|
96
|
+
case message[Protocol::Attribute::KIND]
|
97
|
+
when Protocol::PING
|
98
|
+
return
|
99
|
+
when Protocol::UNMOUNT
|
100
|
+
return unmount
|
101
|
+
when Protocol::STATS_REQUEST
|
102
|
+
return handle_stats_request(message[Protocol::Attribute::ID])
|
103
|
+
end
|
86
104
|
|
87
|
-
handler = @requests[message[
|
105
|
+
handler = @requests[message[Protocol::Attribute::ID]]
|
88
106
|
if !handler
|
89
107
|
# puts "Unknown request id in #{message}"
|
90
108
|
return
|
@@ -94,6 +112,8 @@ module DigitalFabric
|
|
94
112
|
end
|
95
113
|
|
96
114
|
def send_df_message(message)
|
115
|
+
# puts ">>> #{message.inspect}" unless message[Protocol::Attribute::KIND] == Protocol::PING
|
116
|
+
|
97
117
|
@last_send = Time.now
|
98
118
|
@conn << message.to_msgpack
|
99
119
|
end
|
@@ -124,57 +144,68 @@ module DigitalFabric
|
|
124
144
|
t0 = Time.now
|
125
145
|
t1 = nil
|
126
146
|
with_request do |id|
|
127
|
-
|
147
|
+
msg = Protocol.http_request(id, req.headers, req.next_chunk(true), req.complete?)
|
148
|
+
send_df_message(msg)
|
128
149
|
while (message = receive)
|
129
150
|
unless t1
|
130
151
|
t1 = Time.now
|
131
|
-
@service.record_latency_measurement(t1 - t0)
|
152
|
+
@service.record_latency_measurement(t1 - t0, req)
|
132
153
|
end
|
133
|
-
|
154
|
+
kind = message[Protocol::Attribute::KIND]
|
155
|
+
attributes = message[Protocol::Attribute::HttpRequest::HEADERS..-1]
|
156
|
+
return if http_request_message(id, req, kind, attributes)
|
134
157
|
end
|
135
158
|
end
|
136
159
|
rescue => e
|
137
|
-
|
160
|
+
p "Internal server error: #{e.inspect}"
|
161
|
+
puts e.backtrace.join("\n")
|
162
|
+
http_request_send_error_response(e)
|
163
|
+
end
|
164
|
+
|
165
|
+
def http_request_send_error_response(error)
|
166
|
+
response = format("Error: %s\n%s", error.inspect, error.backtrace.join("\n"))
|
167
|
+
req.respond(response, ':status' => Qeweney::Status::INTERNAL_SERVER_ERROR)
|
168
|
+
rescue IOError, SystemCallError
|
169
|
+
# ignore
|
138
170
|
end
|
139
171
|
|
140
172
|
# @return [Boolean] true if response is complete
|
141
|
-
def http_request_message(id, req, message)
|
142
|
-
case
|
173
|
+
def http_request_message(id, req, kind, message)
|
174
|
+
case kind
|
143
175
|
when Protocol::HTTP_UPGRADE
|
144
|
-
http_custom_upgrade(id, req, message)
|
176
|
+
http_custom_upgrade(id, req, *message)
|
145
177
|
true
|
146
178
|
when Protocol::HTTP_GET_REQUEST_BODY
|
147
|
-
http_get_request_body(id, req, message)
|
179
|
+
http_get_request_body(id, req, *message)
|
148
180
|
false
|
149
181
|
when Protocol::HTTP_RESPONSE
|
150
|
-
|
151
|
-
body = message['body']
|
152
|
-
done = message['complete']
|
153
|
-
if !req.headers_sent? && done
|
154
|
-
req.respond(body, headers|| {})
|
155
|
-
true
|
156
|
-
else
|
157
|
-
req.send_headers(headers) if headers && !req.headers_sent?
|
158
|
-
req.send_chunk(body, done: done) if body or done
|
159
|
-
done
|
160
|
-
end
|
182
|
+
http_response(id, req, *message)
|
161
183
|
else
|
162
184
|
# invalid message
|
163
185
|
true
|
164
186
|
end
|
165
187
|
end
|
166
188
|
|
189
|
+
def send_transfer_count(key, rx, tx)
|
190
|
+
send_df_message(Protocol.transfer_count(key, rx, tx))
|
191
|
+
end
|
192
|
+
|
193
|
+
def handle_stats_request(id)
|
194
|
+
stats = @service.get_stats
|
195
|
+
send_df_message(Protocol.stats_response(id, stats))
|
196
|
+
end
|
197
|
+
|
167
198
|
HTTP_RESPONSE_UPGRADE_HEADERS = { ':status' => Qeweney::Status::SWITCHING_PROTOCOLS }
|
168
199
|
|
169
|
-
def http_custom_upgrade(id, req,
|
200
|
+
def http_custom_upgrade(id, req, headers)
|
170
201
|
# send upgrade response
|
171
|
-
upgrade_headers =
|
172
|
-
|
202
|
+
upgrade_headers = headers ?
|
203
|
+
headers.merge(HTTP_RESPONSE_UPGRADE_HEADERS) :
|
173
204
|
HTTP_RESPONSE_UPGRADE_HEADERS
|
174
205
|
req.send_headers(upgrade_headers, true)
|
175
206
|
|
176
207
|
conn = req.adapter.conn
|
177
|
-
reader = spin do
|
208
|
+
reader = spin("#{Fiber.current.tag}.#{id}") do
|
178
209
|
conn.recv_loop do |data|
|
179
210
|
send_df_message(Protocol.conn_data(id, data))
|
180
211
|
end
|
@@ -187,9 +218,9 @@ module DigitalFabric
|
|
187
218
|
end
|
188
219
|
|
189
220
|
def http_custom_upgrade_message(conn, message)
|
190
|
-
case message[
|
221
|
+
case message[Protocol::Attribute::KIND]
|
191
222
|
when Protocol::CONN_DATA
|
192
|
-
conn << message[
|
223
|
+
conn << message[:Protocol::Attribute::ConnData::DATA]
|
193
224
|
false
|
194
225
|
when Protocol::CONN_CLOSE
|
195
226
|
true
|
@@ -199,8 +230,30 @@ module DigitalFabric
|
|
199
230
|
end
|
200
231
|
end
|
201
232
|
|
202
|
-
def
|
203
|
-
|
233
|
+
def http_response(id, req, body, headers, complete, transfer_count_key)
|
234
|
+
if !req.headers_sent? && complete
|
235
|
+
req.respond(body, headers|| {})
|
236
|
+
if transfer_count_key
|
237
|
+
rx, tx = req.transfer_counts
|
238
|
+
send_transfer_count(transfer_count_key, rx, tx)
|
239
|
+
end
|
240
|
+
true
|
241
|
+
else
|
242
|
+
req.send_headers(headers) if headers && !req.headers_sent?
|
243
|
+
req.send_chunk(body, done: complete) if body or complete
|
244
|
+
|
245
|
+
if complete && transfer_count_key
|
246
|
+
rx, tx = req.transfer_counts
|
247
|
+
send_transfer_count(transfer_count_key, rx, tx)
|
248
|
+
end
|
249
|
+
complete
|
250
|
+
end
|
251
|
+
rescue IOError, SystemCallError
|
252
|
+
# ignore error
|
253
|
+
end
|
254
|
+
|
255
|
+
def http_get_request_body(id, req, limit)
|
256
|
+
case limit
|
204
257
|
when nil
|
205
258
|
body = req.read
|
206
259
|
else
|
@@ -230,9 +283,9 @@ module DigitalFabric
|
|
230
283
|
with_request do |id|
|
231
284
|
send_df_message(Protocol.ws_request(id, req.headers))
|
232
285
|
response = receive
|
233
|
-
case response[
|
286
|
+
case response[0]
|
234
287
|
when Protocol::WS_RESPONSE
|
235
|
-
headers = response[
|
288
|
+
headers = response[2] || {}
|
236
289
|
status = headers[':status'] || Qeweney::Status::SWITCHING_PROTOCOLS
|
237
290
|
if status != Qeweney::Status::SWITCHING_PROTOCOLS
|
238
291
|
req.respond(nil, headers)
|
@@ -244,18 +297,20 @@ module DigitalFabric
|
|
244
297
|
req.respond(nil, ':status' => Qeweney::Status::SERVICE_UNAVAILABLE)
|
245
298
|
end
|
246
299
|
end
|
300
|
+
rescue IOError, SystemCallError
|
301
|
+
# ignore
|
247
302
|
end
|
248
303
|
|
249
304
|
def run_websocket_connection(id, websocket)
|
250
|
-
reader = spin do
|
305
|
+
reader = spin("#{Fiber.current}.#{id}-ws") do
|
251
306
|
websocket.recv_loop do |data|
|
252
307
|
send_df_message(Protocol.ws_data(id, data))
|
253
308
|
end
|
254
309
|
end
|
255
310
|
while (message = receive)
|
256
|
-
case message[
|
311
|
+
case message[Protocol::Attribute::KIND]
|
257
312
|
when Protocol::WS_DATA
|
258
|
-
websocket << message[
|
313
|
+
websocket << message[Protocol::Attribute::WS::DATA]
|
259
314
|
when Protocol::WS_CLOSE
|
260
315
|
return
|
261
316
|
else
|
@@ -15,7 +15,7 @@ module DigitalFabric
|
|
15
15
|
route[:executive] = true
|
16
16
|
@service.mount(route, self)
|
17
17
|
@current_request_count = 0
|
18
|
-
@updater = spin_loop(interval: 10) { update_service_stats }
|
18
|
+
# @updater = spin_loop(:executive_updater, interval: 10) { update_service_stats }
|
19
19
|
update_service_stats
|
20
20
|
end
|
21
21
|
|
@@ -33,9 +33,13 @@ module DigitalFabric
|
|
33
33
|
req.respond(message.to_json, { 'Content-Type' => 'text.json' })
|
34
34
|
when '/stream/stats'
|
35
35
|
stream_stats(req)
|
36
|
+
when '/upload'
|
37
|
+
req.respond("body: #{req.read.inspect}")
|
36
38
|
else
|
37
39
|
req.respond('Invalid path', { ':status' => Qeweney::Status::NOT_FOUND })
|
38
40
|
end
|
41
|
+
rescue => e
|
42
|
+
puts "Error: #{e.inspect}"
|
39
43
|
ensure
|
40
44
|
@current_request_count -= 1
|
41
45
|
end
|
@@ -43,7 +47,7 @@ module DigitalFabric
|
|
43
47
|
def stream_stats(req)
|
44
48
|
req.send_headers({ 'Content-Type' => 'text/event-stream' })
|
45
49
|
|
46
|
-
|
50
|
+
every(10) do
|
47
51
|
message = last_service_stats
|
48
52
|
req.send_chunk(format_sse_event(message.to_json))
|
49
53
|
end
|
@@ -4,6 +4,7 @@ module DigitalFabric
|
|
4
4
|
module Protocol
|
5
5
|
PING = 'ping'
|
6
6
|
SHUTDOWN = 'shutdown'
|
7
|
+
UNMOUNT = 'unmount'
|
7
8
|
|
8
9
|
HTTP_REQUEST = 'http_request'
|
9
10
|
HTTP_RESPONSE = 'http_response'
|
@@ -19,16 +20,75 @@ module DigitalFabric
|
|
19
20
|
WS_DATA = 'ws_data'
|
20
21
|
WS_CLOSE = 'ws_close'
|
21
22
|
|
23
|
+
TRANSFER_COUNT = 'transfer_count'
|
24
|
+
|
25
|
+
STATS_REQUEST = 'stats_request'
|
26
|
+
STATS_RESPONSE = 'stats_response'
|
27
|
+
|
22
28
|
SEND_TIMEOUT = 15
|
23
29
|
RECV_TIMEOUT = SEND_TIMEOUT + 5
|
24
30
|
|
31
|
+
module Attribute
|
32
|
+
KIND = 0
|
33
|
+
ID = 1
|
34
|
+
|
35
|
+
module HttpRequest
|
36
|
+
HEADERS = 2
|
37
|
+
BODY_CHUNK = 3
|
38
|
+
COMPLETE = 4
|
39
|
+
end
|
40
|
+
|
41
|
+
module HttpResponse
|
42
|
+
BODY = 2
|
43
|
+
HEADERS = 3
|
44
|
+
COMPLETE = 4
|
45
|
+
TRANSFER_COUNT_KEY = 5
|
46
|
+
end
|
47
|
+
|
48
|
+
module HttpUpgrade
|
49
|
+
HEADERS = 2
|
50
|
+
end
|
51
|
+
|
52
|
+
module HttpGetRequestBody
|
53
|
+
LIMIT = 2
|
54
|
+
end
|
55
|
+
|
56
|
+
module HttpRequestBody
|
57
|
+
BODY = 2
|
58
|
+
COMPLETE = 3
|
59
|
+
end
|
60
|
+
|
61
|
+
module ConnectionData
|
62
|
+
DATA = 2
|
63
|
+
end
|
64
|
+
|
65
|
+
module WS
|
66
|
+
HEADERS = 2
|
67
|
+
DATA = 2
|
68
|
+
end
|
69
|
+
|
70
|
+
module TransferCount
|
71
|
+
KEY = 1
|
72
|
+
RX = 2
|
73
|
+
TX = 3
|
74
|
+
end
|
75
|
+
|
76
|
+
module Stats
|
77
|
+
STATS = 2
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
25
81
|
class << self
|
26
82
|
def ping
|
27
|
-
|
83
|
+
[ PING ]
|
28
84
|
end
|
29
85
|
|
30
86
|
def shutdown
|
31
|
-
|
87
|
+
[ SHUTDOWN ]
|
88
|
+
end
|
89
|
+
|
90
|
+
def unmount
|
91
|
+
[ UNMOUNT ]
|
32
92
|
end
|
33
93
|
|
34
94
|
DF_UPGRADE_RESPONSE = <<~HTTP.gsub("\n", "\r\n")
|
@@ -42,48 +102,60 @@ module DigitalFabric
|
|
42
102
|
DF_UPGRADE_RESPONSE
|
43
103
|
end
|
44
104
|
|
45
|
-
def http_request(id,
|
46
|
-
|
105
|
+
def http_request(id, headers, buffered_chunk, complete)
|
106
|
+
[ HTTP_REQUEST, id, headers, buffered_chunk, complete ]
|
47
107
|
end
|
48
108
|
|
49
|
-
def http_response(id, body, headers, complete)
|
50
|
-
|
109
|
+
def http_response(id, body, headers, complete, transfer_count_key = nil)
|
110
|
+
[ HTTP_RESPONSE, id, body, headers, complete, transfer_count_key ]
|
51
111
|
end
|
52
112
|
|
53
113
|
def http_upgrade(id, headers)
|
54
|
-
|
114
|
+
[ HTTP_UPGRADE, id, headers ]
|
55
115
|
end
|
56
116
|
|
57
117
|
def http_get_request_body(id, limit = nil)
|
58
|
-
|
118
|
+
[ HTTP_GET_REQUEST_BODY, id, limit ]
|
59
119
|
end
|
60
120
|
|
61
121
|
def http_request_body(id, body, complete)
|
62
|
-
|
122
|
+
[ HTTP_REQUEST_BODY, id, body, complete ]
|
63
123
|
end
|
64
124
|
|
65
125
|
def connection_data(id, data)
|
66
|
-
|
126
|
+
[ CONN_DATA, id, data ]
|
67
127
|
end
|
68
128
|
|
69
129
|
def connection_close(id)
|
70
|
-
|
130
|
+
[ CONN_CLOSE, id ]
|
71
131
|
end
|
72
132
|
|
73
133
|
def ws_request(id, headers)
|
74
|
-
|
134
|
+
[ WS_REQUEST, id, headers ]
|
75
135
|
end
|
76
136
|
|
77
137
|
def ws_response(id, headers)
|
78
|
-
|
138
|
+
[ WS_RESPONSE, id, headers ]
|
79
139
|
end
|
80
140
|
|
81
141
|
def ws_data(id, data)
|
82
|
-
|
142
|
+
[ WS_DATA, id, data ]
|
83
143
|
end
|
84
144
|
|
85
145
|
def ws_close(id)
|
86
|
-
|
146
|
+
[ WS_CLOSE, id ]
|
147
|
+
end
|
148
|
+
|
149
|
+
def transfer_count(key, rx, tx)
|
150
|
+
[ TRANSFER_COUNT, key, rx, tx ]
|
151
|
+
end
|
152
|
+
|
153
|
+
def stats_request(id)
|
154
|
+
[ STATS_REQUEST, id ]
|
155
|
+
end
|
156
|
+
|
157
|
+
def stats_response(id, stats)
|
158
|
+
[ STATS_RESPONSE, id, stats ]
|
87
159
|
end
|
88
160
|
end
|
89
161
|
end
|