eventmachine-proxy 1.0.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/eventmachine/protocols/connect.rb +23 -0
- data/lib/eventmachine/protocols/proxy.rb +107 -0
- data/lib/eventmachine-proxy.rb +1 -0
- metadata +59 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d605cb41d1c6ee818040dc71dbb074903085bce6c5785345df7f2cd8163dd7c5
|
4
|
+
data.tar.gz: 4089a8b4fd56162c73c6492de7df6012259b7ba820daab52e6e3018d1560fd01
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a26b3131f83886f407f637f98e04e7f3cdd73e0107ba571fab704aa933ef5ac781dd9d85e5069fecb1f1710838abd7b340bac132887da38b87c2030556b9173e
|
7
|
+
data.tar.gz: d5d58fec5932cb8d43c660d17c0c6fba6cf5ab59097eb1a4dba3e0f4698de0f4bbdc7bd3c92d6303e56601659e5dcbfdcff5958d469019854f9682332007ec2d
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "proxy"
|
4
|
+
|
5
|
+
module EventMachine::Protocols
|
6
|
+
class CONNECT < Proxy
|
7
|
+
REQLINE = /\ACONNECT ([^:]+):([1-9][0-9]*) (HTTP\/[0-1]\.\d+).*\r?\n\r?\n/m
|
8
|
+
private_constant :REQLINE
|
9
|
+
|
10
|
+
def receive_message(msg)
|
11
|
+
return unless msg.include?("\r\n\r\n") || msg.include?("\n\n")
|
12
|
+
match = msg.match(REQLINE) or return failure(:invalid_request)
|
13
|
+
host, port, httpv = match.captures
|
14
|
+
completion = proxy_to(host, port)
|
15
|
+
completion.callback do |server|
|
16
|
+
server.send_data(match.post_match)
|
17
|
+
send_data("#{httpv} 200 Connection established\r\n\r\n")
|
18
|
+
end
|
19
|
+
completion.errback { |e| failure(e) }
|
20
|
+
true # done
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "eventmachine"
|
4
|
+
require "ipaddr"
|
5
|
+
|
6
|
+
module EventMachine::Protocols
|
7
|
+
class Proxy < EventMachine::Connection
|
8
|
+
def initialize(opts = {})
|
9
|
+
@buf = nil
|
10
|
+
@failed = false
|
11
|
+
@server = nil
|
12
|
+
@connect_timeout = opts.fetch(:connect_timeout, 20.0)
|
13
|
+
@connection_buffer_size = opts.fetch(:connection_buffer_size, 2**23)
|
14
|
+
@request_buffer_size = opts.fetch(:request_buffer_size, 2**10)
|
15
|
+
@connection_inactivity_timeout = opts.fetch(:connection_inactivity_timeout, 0)
|
16
|
+
@allow_all = opts.fetch(:allow_all, false)
|
17
|
+
end
|
18
|
+
|
19
|
+
def receive_data(data)
|
20
|
+
return if @failed
|
21
|
+
@buf ? @buf << data : @buf = data
|
22
|
+
if @buf.bytesize >= @request_buffer_size
|
23
|
+
failure(:request_too_large)
|
24
|
+
else
|
25
|
+
done = receive_message(@buf)
|
26
|
+
@buf = nil if done || @failed
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def proxy_target_unbound
|
31
|
+
close_connection
|
32
|
+
end
|
33
|
+
|
34
|
+
def unbind
|
35
|
+
@server&.close_connection_after_writing
|
36
|
+
@server = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def proxy_to(host, port)
|
42
|
+
completion = EventMachine::Completion.new
|
43
|
+
begin
|
44
|
+
@server = EventMachine.connect(host, port, Server)
|
45
|
+
rescue => e
|
46
|
+
completion.fail(e)
|
47
|
+
else
|
48
|
+
@server.errback { |e| completion.fail(e) }
|
49
|
+
@server.callback do
|
50
|
+
if @allow_all || !@server.special_purpose?
|
51
|
+
completion.succeed(@server)
|
52
|
+
else
|
53
|
+
completion.fail(:disallowed)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
@server.pending_connect_timeout = @connect_timeout
|
57
|
+
@server.comm_inactivity_timeout = @connection_inactivity_timeout
|
58
|
+
proxy_incoming_to(@server, @connection_buffer_size)
|
59
|
+
@server.proxy_incoming_to(self, @connection_buffer_size)
|
60
|
+
end
|
61
|
+
completion
|
62
|
+
end
|
63
|
+
|
64
|
+
def failure(comment, data = nil)
|
65
|
+
@failed = true
|
66
|
+
close_connection_after_writing
|
67
|
+
end
|
68
|
+
|
69
|
+
class Server < EventMachine::Connection
|
70
|
+
include EventMachine::Deferrable
|
71
|
+
|
72
|
+
def post_init
|
73
|
+
@connected = false
|
74
|
+
end
|
75
|
+
|
76
|
+
def connection_completed
|
77
|
+
@connected = true
|
78
|
+
succeed
|
79
|
+
end
|
80
|
+
|
81
|
+
def unbind(errno)
|
82
|
+
fail(errno) unless @connected
|
83
|
+
end
|
84
|
+
|
85
|
+
def special_purpose?
|
86
|
+
addr = Addrinfo.new(get_peername)
|
87
|
+
addr.ipv4_loopback? ||
|
88
|
+
addr.ipv4_multicast? ||
|
89
|
+
addr.ipv4_private? ||
|
90
|
+
addr.ipv6_linklocal? ||
|
91
|
+
addr.ipv6_loopback? ||
|
92
|
+
addr.ipv6_mc_global? ||
|
93
|
+
addr.ipv6_mc_linklocal? ||
|
94
|
+
addr.ipv6_mc_nodelocal? ||
|
95
|
+
addr.ipv6_mc_orglocal? ||
|
96
|
+
addr.ipv6_mc_sitelocal? ||
|
97
|
+
addr.ipv6_multicast? ||
|
98
|
+
addr.ipv6_sitelocal? ||
|
99
|
+
addr.ipv6_unique_local? ||
|
100
|
+
addr.ipv6_unspecified? ||
|
101
|
+
addr.ipv6_v4mapped?
|
102
|
+
end
|
103
|
+
end
|
104
|
+
private_constant :Server
|
105
|
+
end
|
106
|
+
private_constant :Proxy
|
107
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require "eventmachine/protocols/connect"
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: eventmachine-proxy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- soylent
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-06-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: eventmachine
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.2'
|
27
|
+
description:
|
28
|
+
email:
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- lib/eventmachine-proxy.rb
|
34
|
+
- lib/eventmachine/protocols/connect.rb
|
35
|
+
- lib/eventmachine/protocols/proxy.rb
|
36
|
+
homepage: https://github.com/soylent/eventmachine-proxy
|
37
|
+
licenses:
|
38
|
+
- MIT
|
39
|
+
metadata: {}
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options: []
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 2.5.0
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
requirements: []
|
55
|
+
rubygems_version: 3.5.3
|
56
|
+
signing_key:
|
57
|
+
specification_version: 4
|
58
|
+
summary: minimal CONNECT proxy
|
59
|
+
test_files: []
|