outpunch-rails 0.1.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 +7 -0
- data/app/controllers/outpunch/tunnel_controller.rb +88 -0
- data/lib/outpunch/rails/engine.rb +19 -0
- data/lib/outpunch/rails/version.rb +7 -0
- data/lib/outpunch/rails.rb +56 -0
- data/lib/outpunch.rb +3 -0
- metadata +103 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: a26df1916a7b588561507c63bf92ff1a37f5514177cc5f20b5b452dfce87dff1
|
|
4
|
+
data.tar.gz: c5938d675495f16c91141723d47307dc5f15929c467bd2a1ca3aa29cf12a76aa
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f92c995d5c61514dfba82aea81282e54af8fbbe92a4e218247b43673413b6dc85387317019ff2bc8e0d2271f041ba1b0f3c0eb9864b25c210755530e54342b2e
|
|
7
|
+
data.tar.gz: e81584f3cf84df13e5f5bf4b3bc166ca30e6a21251631f1aaf9920bff8c80cc910bdb87212abf5a50d8721fed37b9b586f0a230b1af2d6bc2c83afedda3f74fb
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Outpunch::TunnelController < OutpunchRails.configuration.base_controller.constantize
|
|
4
|
+
skip_before_action :verify_authenticity_token, raise: false
|
|
5
|
+
|
|
6
|
+
def proxy
|
|
7
|
+
service_name = params[:service_name]
|
|
8
|
+
service_path = params[:service_path] || ""
|
|
9
|
+
|
|
10
|
+
return render_error(400, "Service name required") if service_name.blank?
|
|
11
|
+
|
|
12
|
+
if (auth = OutpunchRails.configuration.authorize_service)
|
|
13
|
+
unless auth.call(service_name, request)
|
|
14
|
+
return render_error(403, "Service '#{service_name}' not allowed for this product")
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
unless OutpunchRails.connected?(service_name)
|
|
19
|
+
return render_error(502, "Service '#{service_name}' offline")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
request_id = SecureRandom.uuid
|
|
23
|
+
payload = {
|
|
24
|
+
request_id: request_id,
|
|
25
|
+
method: request.method,
|
|
26
|
+
path: service_path,
|
|
27
|
+
query: request.query_parameters,
|
|
28
|
+
headers: OutpunchRails.extract_proxy_headers(request.headers),
|
|
29
|
+
body: request.body&.read || ""
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
run_hook(:before_proxy, service_name, service_path, payload)
|
|
33
|
+
|
|
34
|
+
response_data = OutpunchRails.handle_request(
|
|
35
|
+
service: service_name,
|
|
36
|
+
method: payload[:method],
|
|
37
|
+
path: payload[:path],
|
|
38
|
+
query: payload[:query],
|
|
39
|
+
headers: payload[:headers],
|
|
40
|
+
body: payload[:body]
|
|
41
|
+
)
|
|
42
|
+
result = OutpunchRails.success_response(response_data)
|
|
43
|
+
|
|
44
|
+
run_hook(:after_proxy, service_name, service_path, payload, result: result)
|
|
45
|
+
|
|
46
|
+
render_tunnel_result(result)
|
|
47
|
+
rescue Timeout::Error
|
|
48
|
+
render_error(504, "Tunnel timeout for service '#{params[:service_name]}'")
|
|
49
|
+
rescue => e
|
|
50
|
+
render_error(502, e.message)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def run_hook(type, service_name, path, payload, extra = {})
|
|
56
|
+
hooks = OutpunchRails.configuration.hooks
|
|
57
|
+
return unless hooks
|
|
58
|
+
|
|
59
|
+
case type
|
|
60
|
+
when :before_proxy
|
|
61
|
+
hooks.before_proxy(service_name: service_name, path: path, payload: payload, request: request)
|
|
62
|
+
when :after_proxy
|
|
63
|
+
hooks.after_proxy(service_name: service_name, path: path, payload: payload, request: request, **extra)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def render_tunnel_result(result)
|
|
68
|
+
if result[:body_encoding] == "base64"
|
|
69
|
+
content_disposition = result[:headers]["content-disposition"] || "attachment"
|
|
70
|
+
disposition = content_disposition.start_with?("attachment") ? "attachment" : "inline"
|
|
71
|
+
filename = content_disposition[/filename="?([^";]+)"?/, 1]
|
|
72
|
+
|
|
73
|
+
send_data result[:body],
|
|
74
|
+
type: result[:headers]["content-type"] || "application/octet-stream",
|
|
75
|
+
disposition: disposition,
|
|
76
|
+
filename: filename,
|
|
77
|
+
status: result[:status]
|
|
78
|
+
else
|
|
79
|
+
result[:headers]&.each { |key, value| response.set_header(key, value) }
|
|
80
|
+
render body: result[:body], status: result[:status]
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def render_error(status, message)
|
|
85
|
+
result = OutpunchRails.error_response(status, message)
|
|
86
|
+
render json: JSON.parse(result[:body]), status: result[:status]
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Outpunch
|
|
4
|
+
module Rails
|
|
5
|
+
class Engine < ::Rails::Engine
|
|
6
|
+
initializer "outpunch_rails.insert_middleware" do |app|
|
|
7
|
+
app.middleware.insert_before 0, Outpunch::Rack::Middleware
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
initializer "outpunch_rails.routes" do
|
|
11
|
+
prefix = OutpunchRails.configuration.route_prefix
|
|
12
|
+
::Rails.application.routes.prepend do
|
|
13
|
+
match "#{prefix}/:service_name/*service_path", to: "outpunch/tunnel#proxy", via: :all
|
|
14
|
+
match "#{prefix}/:service_name", to: "outpunch/tunnel#proxy", via: :all
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "outpunch/rack"
|
|
4
|
+
require "outpunch/rails/version"
|
|
5
|
+
require "outpunch/rails/engine"
|
|
6
|
+
|
|
7
|
+
# OutpunchRails — thin Rails wrapper around OutpunchRack.
|
|
8
|
+
#
|
|
9
|
+
# Usage in config/initializers/outpunch.rb:
|
|
10
|
+
#
|
|
11
|
+
# OutpunchRails.configure do |config|
|
|
12
|
+
# config.secret = ENV['MORDOR_TUNNEL_SECRET']
|
|
13
|
+
# config.timeout = 60
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
module OutpunchRails
|
|
17
|
+
class << self
|
|
18
|
+
def configure(&block)
|
|
19
|
+
Outpunch::Rack.configure(&block)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def configuration
|
|
23
|
+
Outpunch::Rack.configuration
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def hooks
|
|
27
|
+
Outpunch::Rack.configuration.hooks
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def server
|
|
31
|
+
Outpunch::Rack.server
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Convenience delegates so application code only needs to reference OutpunchRails.
|
|
35
|
+
|
|
36
|
+
def connected?(service_name)
|
|
37
|
+
Outpunch::Rack.connected?(service_name)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def handle_request(**kwargs)
|
|
41
|
+
Outpunch::Rack.handle_request(**kwargs)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def success_response(data)
|
|
45
|
+
Outpunch::Rack.success_response(data)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def error_response(status, message)
|
|
49
|
+
Outpunch::Rack.error_response(status, message)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def extract_proxy_headers(headers)
|
|
53
|
+
Outpunch::Rack.extract_proxy_headers(headers)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
data/lib/outpunch.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: outpunch-rails
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- TechyCorp
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-04-05 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: outpunch-rack
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - '='
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 0.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: 0.1.2
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: railties
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '7.0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '7.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec-rails
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '6.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '6.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rails
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '7.0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '7.0'
|
|
69
|
+
description:
|
|
70
|
+
email:
|
|
71
|
+
executables: []
|
|
72
|
+
extensions: []
|
|
73
|
+
extra_rdoc_files: []
|
|
74
|
+
files:
|
|
75
|
+
- app/controllers/outpunch/tunnel_controller.rb
|
|
76
|
+
- lib/outpunch.rb
|
|
77
|
+
- lib/outpunch/rails.rb
|
|
78
|
+
- lib/outpunch/rails/engine.rb
|
|
79
|
+
- lib/outpunch/rails/version.rb
|
|
80
|
+
homepage:
|
|
81
|
+
licenses:
|
|
82
|
+
- MIT
|
|
83
|
+
metadata: {}
|
|
84
|
+
post_install_message:
|
|
85
|
+
rdoc_options: []
|
|
86
|
+
require_paths:
|
|
87
|
+
- lib
|
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
89
|
+
requirements:
|
|
90
|
+
- - ">="
|
|
91
|
+
- !ruby/object:Gem::Version
|
|
92
|
+
version: '3.1'
|
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
|
+
requirements:
|
|
95
|
+
- - ">="
|
|
96
|
+
- !ruby/object:Gem::Version
|
|
97
|
+
version: '0'
|
|
98
|
+
requirements: []
|
|
99
|
+
rubygems_version: 3.5.22
|
|
100
|
+
signing_key:
|
|
101
|
+
specification_version: 4
|
|
102
|
+
summary: Rails Engine adapter for the outpunch reverse WebSocket tunnel
|
|
103
|
+
test_files: []
|