tipi 0.38 → 0.42
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 +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
|